C語言 數(shù)據(jù)結(jié)構(gòu)之鏈表實現(xiàn)代碼
前言
最近在復(fù)習(xí)數(shù)據(jù)結(jié)構(gòu)的相關(guān)知識,感覺在初學(xué)的時候還是有很多東西沒有掌握,不過現(xiàn)在終于算是搞得比較有頭緒了,所以就在寫出來和大家一起分享!
什么是鏈表
簡單的說,鏈表就是由多個結(jié)點離散分配,彼此通過指針相連,每個結(jié)點只有一個前驅(qū)結(jié)點和后繼結(jié)點。首節(jié)點無前驅(qū)結(jié)點,為結(jié)點無后繼結(jié)點的一種存儲結(jié)構(gòu)。
鏈表的結(jié)構(gòu)
頭結(jié)點:鏈表的第一個有效結(jié)點前面的結(jié)點,頭結(jié)點并不存放有效數(shù)據(jù),也就是數(shù)據(jù)域為空,加頭結(jié)點的主要目的是為了方便鏈表的操作。
首節(jié)點:鏈表的第一個有效結(jié)點,結(jié)點包含數(shù)據(jù)域和指針域。
尾結(jié)點:尾結(jié)點的指針域為空。
頭指針:指向頭結(jié)點的指針變量,它存放了頭結(jié)點的地址(在這里注意一下,指針變量存放的是地址,也就是說頭指針存放的是
頭結(jié)點的地址,一般通過頭指針對鏈表進行操作)。
具體實現(xiàn)
#include<stdio.h> #include<malloc.h> #include<stdlib.h> //定義鏈表節(jié)點 typedef struct Node { int data; //數(shù)據(jù)域 struct Node * pNext; //指針域 }NODE, * PNODE; //NODE等價于struct Node, PNODE等價于struct Node * //函數(shù)聲明 PNODE createLinkList(void); //創(chuàng)建鏈表的函數(shù) void traverseLinkList(PNODE pHead); //遍歷鏈表的函數(shù) bool isEmpty(PNODE pHead); //判斷鏈表是否為空的函數(shù) int getLength(PNODE pHead); //獲取鏈表長度的函數(shù) bool insertElement(PNODE pHead, int pos, int val); //向鏈表中插入元素的函數(shù),三個參數(shù)依次為鏈表頭結(jié)點、要插入元素的位置和要插入元素的值 bool deleteElement(PNODE pHead, int pos, int * pVal); //從鏈表中刪除元素的函數(shù),三個參數(shù)依次為鏈表頭結(jié)點、要刪除的元素的位置和刪除的元素的值 void sort(PNODE pHead); //對鏈表中的元素進行排序的函數(shù)(基于冒泡排序) int main(void) { int val; //用于保存刪除的元素 PNODE pHead = NULL; //PNODE等價于struct Node * pHead = createLinkList(); //創(chuàng)建一個非循環(huán)單鏈表,并將該鏈表的頭結(jié)點地址賦給pHead traverseLinkList(pHead); //調(diào)用遍歷鏈表的函數(shù) if(isEmpty(pHead)) printf("鏈表為空!\n"); else printf("鏈表不為空!\n"); printf("鏈表的長度為:%d\n", getLength(pHead)); //調(diào)用冒泡排序函數(shù) sort(pHead); //重新遍歷 traverseLinkList(pHead); //向鏈表中指定位置處插入一個元素 if(insertElement(pHead, 4, 30)) printf("插入成功!插入的元素為:%d\n", 30); else printf("插入失敗!\n"); //重新遍歷鏈表 traverseLinkList(pHead); //刪除元素測試 if(deleteElement(pHead, 3, &val)) printf("元素刪除成功!刪除的元素是:%d\n", val); else printf("元素刪除失敗!\n"); traverseLinkList(pHead); system("pause"); return 0; } PNODE createLinkList(void) { int length; //有效結(jié)點的長度 int i; int value; //用來存放用戶輸入的結(jié)點的值 //創(chuàng)建了一個不存放有效數(shù)據(jù)的頭結(jié)點 PNODE pHead = (PNODE)malloc(sizeof(NODE)); if(NULL == pHead) { printf("內(nèi)存分配失敗,程序退出!\n"); exit(-1); } PNODE pTail = pHead; //pTail始終指向尾結(jié)點 pTail->pNext = NULL; //清空指針域 printf("請輸入您想要創(chuàng)建鏈表結(jié)點的個數(shù):len = "); scanf("%d", &length); for(i=0;i<length;i++) { printf("請輸入第%d個結(jié)點的值:", i+1); scanf("%d", &value); PNODE pNew = (PNODE)malloc(sizeof(NODE)); if(NULL == pHead) { printf("內(nèi)存分配失敗,程序退出!\n"); exit(-1); } pNew->data = value; //向新結(jié)點中放入值 pTail->pNext = pNew; //將尾結(jié)點指向新結(jié)點 pNew->pNext = NULL; //將新結(jié)點的指針域清空 pTail = pNew; //將新結(jié)點賦給pTail,使pTail始終指向為尾結(jié)點 } return pHead; } void traverseLinkList(PNODE pHead) { PNODE p = pHead->pNext; while(NULL != p) { printf("%d ", p->data); p = p->pNext; } printf("\n"); return; } bool isEmpty(PNODE pHead) { if(NULL == pHead->pNext) return true; else return false; } int getLength(PNODE pHead) { PNODE p = pHead->pNext; //指向首節(jié)點 int len = 0; //記錄鏈表長度的變量 while(NULL != p) { len++; p = p->pNext; //p指向下一結(jié)點 } return len; } void sort(PNODE pHead) { int len = getLength(pHead); //獲取鏈表長度 int i, j, t; //用于交換元素值的中間變量 PNODE p, q; //用于比較的兩個中間指針變量 for(i=0,p=pHead->pNext ; i<len-1 ; i++,p=p->pNext) { for(j=i+1,q=p->pNext;j<len;j++,q=q->pNext) { if(p->data > q->data) { t = p->data; p->data = q->data; q->data = t; } } } return; } bool insertElement(PNODE pHead, int pos, int val) { int i = 0; PNODE p = pHead; //判斷p是否為空并且使p最終指向pos位置的結(jié)點 while(NULL!=p && i<pos-1) { p = p->pNext; i++; } if(NULL==p || i>pos-1) return false; //創(chuàng)建一個新結(jié)點 PNODE pNew = (PNODE)malloc(sizeof(NODE)); if(NULL == pNew) { printf("內(nèi)存分配失敗,程序退出!\n"); exit(-1); } pNew->data = val; //定義一個臨時結(jié)點,指向當(dāng)前p的下一結(jié)點 PNODE q = p->pNext; //將p指向新結(jié)點 p->pNext = pNew; //將q指向之前p指向的結(jié)點 pNew->pNext = q; return true; } bool deleteElement(PNODE pHead, int pos, int * pVal) { int i = 0; PNODE p = pHead; //判斷p是否為空并且使p最終指向pos結(jié)點 while(NULL!=p->pNext && i<pos-1) { p = p->pNext; i++; } if(NULL==p->pNext || i>pos-1) return false; //保存要刪除的結(jié)點 * pVal = p->pNext->data; //刪除p后面的結(jié)點 PNODE q = p->pNext; p->pNext = p->pNext->pNext; free(q); q = NULL; return true; }
結(jié)尾語
上面實現(xiàn)的主要是單鏈表,另外還有雙鏈表、循環(huán)鏈表、非循環(huán)鏈表等其他幾種常見鏈表。雙鏈表的特殊性表現(xiàn)在每個基本結(jié)點有兩個指針域;循環(huán)鏈表的特性主要表現(xiàn)在,在循環(huán)鏈表中,通過任何一個結(jié)點可以找到其他所有結(jié)點。
謝謝大家的閱讀,希望能幫助到大家,謝謝大家對本站的支持!
- C語言創(chuàng)建和操作單鏈表數(shù)據(jù)結(jié)構(gòu)的實例教程
- C語言數(shù)據(jù)結(jié)構(gòu) 雙向鏈表的建立與基本操作
- C語言數(shù)據(jù)結(jié)構(gòu)實現(xiàn)鏈表去重的實例
- C語言數(shù)據(jù)結(jié)構(gòu) 鏈表與歸并排序?qū)嵗斀?/a>
- C語言數(shù)據(jù)結(jié)構(gòu)實現(xiàn)鏈表逆序并輸出
- C語言數(shù)據(jù)結(jié)構(gòu)之判斷循環(huán)鏈表空與滿
- C語言 數(shù)據(jù)結(jié)構(gòu)鏈表的實例(十九種操作)
- 數(shù)據(jù)結(jié)構(gòu) C語言實現(xiàn)循環(huán)單鏈表的實例
- C語言數(shù)據(jù)結(jié)構(gòu)鏈表隊列的實現(xiàn)
- C語言實現(xiàn)通用數(shù)據(jù)結(jié)構(gòu)之通用鏈表
相關(guān)文章
C++編寫DLL動態(tài)鏈接庫的步驟與實現(xiàn)方法
這篇文章主要介紹了C++編寫DLL動態(tài)鏈接庫的步驟與實現(xiàn)方法,結(jié)合實例形式分析了C++導(dǎo)出類文件及生成與調(diào)用DLL動態(tài)連接庫的相關(guān)操作技巧,需要的朋友可以參考下2016-08-08