C語(yǔ)言 數(shù)據(jù)結(jié)構(gòu)之鏈表實(shí)現(xiàn)代碼
前言
最近在復(fù)習(xí)數(shù)據(jù)結(jié)構(gòu)的相關(guān)知識(shí),感覺(jué)在初學(xué)的時(shí)候還是有很多東西沒(méi)有掌握,不過(guò)現(xiàn)在終于算是搞得比較有頭緒了,所以就在寫(xiě)出來(lái)和大家一起分享!
什么是鏈表
簡(jiǎn)單的說(shuō),鏈表就是由多個(gè)結(jié)點(diǎn)離散分配,彼此通過(guò)指針相連,每個(gè)結(jié)點(diǎn)只有一個(gè)前驅(qū)結(jié)點(diǎn)和后繼結(jié)點(diǎn)。首節(jié)點(diǎn)無(wú)前驅(qū)結(jié)點(diǎn),為結(jié)點(diǎn)無(wú)后繼結(jié)點(diǎn)的一種存儲(chǔ)結(jié)構(gòu)。
鏈表的結(jié)構(gòu)
頭結(jié)點(diǎn):鏈表的第一個(gè)有效結(jié)點(diǎn)前面的結(jié)點(diǎn),頭結(jié)點(diǎn)并不存放有效數(shù)據(jù),也就是數(shù)據(jù)域?yàn)榭?,加頭結(jié)點(diǎn)的主要目的是為了方便鏈表的操作。
首節(jié)點(diǎn):鏈表的第一個(gè)有效結(jié)點(diǎn),結(jié)點(diǎn)包含數(shù)據(jù)域和指針域。
尾結(jié)點(diǎn):尾結(jié)點(diǎn)的指針域?yàn)榭铡?br />
頭指針:指向頭結(jié)點(diǎn)的指針變量,它存放了頭結(jié)點(diǎn)的地址(在這里注意一下,指針變量存放的是地址,也就是說(shuō)頭指針存放的是
頭結(jié)點(diǎn)的地址,一般通過(guò)頭指針對(duì)鏈表進(jìn)行操作)。
具體實(shí)現(xiàn)
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
//定義鏈表節(jié)點(diǎn)
typedef struct Node
{
 int data;  //數(shù)據(jù)域
 struct Node * pNext; //指針域
}NODE, * PNODE;  //NODE等價(jià)于struct Node, PNODE等價(jià)于struct Node *
//函數(shù)聲明
PNODE createLinkList(void);    //創(chuàng)建鏈表的函數(shù)
void traverseLinkList(PNODE pHead);   //遍歷鏈表的函數(shù)
bool isEmpty(PNODE pHead);    //判斷鏈表是否為空的函數(shù)
int getLength(PNODE pHead);    //獲取鏈表長(zhǎng)度的函數(shù)
bool insertElement(PNODE pHead, int pos, int val); //向鏈表中插入元素的函數(shù),三個(gè)參數(shù)依次為鏈表頭結(jié)點(diǎn)、要插入元素的位置和要插入元素的值
bool deleteElement(PNODE pHead, int pos, int * pVal); //從鏈表中刪除元素的函數(shù),三個(gè)參數(shù)依次為鏈表頭結(jié)點(diǎn)、要?jiǎng)h除的元素的位置和刪除的元素的值
void sort(PNODE pHead);     //對(duì)鏈表中的元素進(jìn)行排序的函數(shù)(基于冒泡排序)
int main(void)
{
 int val;   //用于保存刪除的元素
 PNODE pHead = NULL;  //PNODE等價(jià)于struct Node *
 pHead = createLinkList(); //創(chuàng)建一個(gè)非循環(huán)單鏈表,并將該鏈表的頭結(jié)點(diǎn)地址賦給pHead
 traverseLinkList(pHead); //調(diào)用遍歷鏈表的函數(shù)
 if(isEmpty(pHead))
 printf("鏈表為空!\n");
 else
 printf("鏈表不為空!\n");
 printf("鏈表的長(zhǎng)度為:%d\n", getLength(pHead));
 //調(diào)用冒泡排序函數(shù)
 sort(pHead);
 //重新遍歷
 traverseLinkList(pHead);
 //向鏈表中指定位置處插入一個(gè)元素
 if(insertElement(pHead, 4, 30))
 printf("插入成功!插入的元素為:%d\n", 30);
 else
 printf("插入失敗!\n");
 //重新遍歷鏈表
 traverseLinkList(pHead);
 //刪除元素測(cè)試
 if(deleteElement(pHead, 3, &val))
 printf("元素刪除成功!刪除的元素是:%d\n", val);
 else
 printf("元素刪除失敗!\n");
 traverseLinkList(pHead);
 system("pause");
 return 0;
}
PNODE createLinkList(void)
{
 int length; //有效結(jié)點(diǎn)的長(zhǎng)度
 int i;
 int value; //用來(lái)存放用戶(hù)輸入的結(jié)點(diǎn)的值
 //創(chuàng)建了一個(gè)不存放有效數(shù)據(jù)的頭結(jié)點(diǎn)
 PNODE pHead = (PNODE)malloc(sizeof(NODE));
 if(NULL == pHead)
 {
 printf("內(nèi)存分配失敗,程序退出!\n");
 exit(-1);
 }
 PNODE pTail = pHead; //pTail始終指向尾結(jié)點(diǎn)
 pTail->pNext = NULL; //清空指針域
 printf("請(qǐng)輸入您想要?jiǎng)?chuàng)建鏈表結(jié)點(diǎn)的個(gè)數(shù):len = ");
 scanf("%d", &length);
 for(i=0;i<length;i++)
 {
 printf("請(qǐng)輸入第%d個(gè)結(jié)點(diǎn)的值:", i+1);
 scanf("%d", &value);
 PNODE pNew = (PNODE)malloc(sizeof(NODE));
 if(NULL == pHead)
 {
  printf("內(nèi)存分配失敗,程序退出!\n");
  exit(-1);
 }
 pNew->data = value; //向新結(jié)點(diǎn)中放入值
 pTail->pNext = pNew; //將尾結(jié)點(diǎn)指向新結(jié)點(diǎn)
 pNew->pNext = NULL; //將新結(jié)點(diǎn)的指針域清空
 pTail = pNew;  //將新結(jié)點(diǎn)賦給pTail,使pTail始終指向?yàn)槲步Y(jié)點(diǎn)
 }
 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é)點(diǎn)
 int len = 0;   //記錄鏈表長(zhǎng)度的變量
 while(NULL != p)
 {
 len++;
 p = p->pNext;  //p指向下一結(jié)點(diǎn)
 }
 return len;
}
void sort(PNODE pHead)
{
 int len = getLength(pHead); //獲取鏈表長(zhǎng)度  
 int i, j, t;   //用于交換元素值的中間變量
 PNODE p, q;   //用于比較的兩個(gè)中間指針變量
 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é)點(diǎn)
 while(NULL!=p && i<pos-1)
 {
 p = p->pNext;
 i++;
 }
 if(NULL==p || i>pos-1)
 return false;
 //創(chuàng)建一個(gè)新結(jié)點(diǎn)
 PNODE pNew = (PNODE)malloc(sizeof(NODE));
 if(NULL == pNew)
 {
 printf("內(nèi)存分配失敗,程序退出!\n");
 exit(-1);
 }
 pNew->data = val;
 //定義一個(gè)臨時(shí)結(jié)點(diǎn),指向當(dāng)前p的下一結(jié)點(diǎn)
 PNODE q = p->pNext;
 //將p指向新結(jié)點(diǎn)
 p->pNext = pNew;
 //將q指向之前p指向的結(jié)點(diǎn)
 pNew->pNext = q;
 return true;
}
bool deleteElement(PNODE pHead, int pos, int * pVal)
{
 int i = 0;
 PNODE p = pHead;
 //判斷p是否為空并且使p最終指向pos結(jié)點(diǎn)
 while(NULL!=p->pNext && i<pos-1)
 {
 p = p->pNext;
 i++;
 }
 if(NULL==p->pNext || i>pos-1)
 return false;
 //保存要?jiǎng)h除的結(jié)點(diǎn)
 * pVal = p->pNext->data;
 //刪除p后面的結(jié)點(diǎn)
 PNODE q = p->pNext;
 p->pNext = p->pNext->pNext;
 free(q);
 q = NULL;
 return true;
}
結(jié)尾語(yǔ)
上面實(shí)現(xiàn)的主要是單鏈表,另外還有雙鏈表、循環(huán)鏈表、非循環(huán)鏈表等其他幾種常見(jiàn)鏈表。雙鏈表的特殊性表現(xiàn)在每個(gè)基本結(jié)點(diǎn)有兩個(gè)指針域;循環(huán)鏈表的特性主要表現(xiàn)在,在循環(huán)鏈表中,通過(guò)任何一個(gè)結(jié)點(diǎn)可以找到其他所有結(jié)點(diǎn)。
謝謝大家的閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
上一篇:C語(yǔ)言實(shí)現(xiàn)的猴子吃桃問(wèn)題算法解決方案
欄 目:C語(yǔ)言
下一篇:C語(yǔ)言實(shí)現(xiàn)的猴子分桃問(wèn)題算法解決方案
本文標(biāo)題:C語(yǔ)言 數(shù)據(jù)結(jié)構(gòu)之鏈表實(shí)現(xiàn)代碼
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/2021.html
您可能感興趣的文章
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用函數(shù)刪除字符
 - 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)式函數(shù)庫(kù)
 - 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
 - 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)數(shù)怎么表達(dá)
 - 04-02c語(yǔ)言用函數(shù)寫(xiě)分段 用c語(yǔ)言表示分段函數(shù)
 - 04-02c語(yǔ)言編寫(xiě)函數(shù)冒泡排序 c語(yǔ)言冒泡排序法函數(shù)
 - 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
 - 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段函數(shù)
 - 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎么打出三角函數(shù)的值
 - 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求階乘
 


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
 - 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
 - 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
 - 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
 - 5c語(yǔ)言計(jì)算三角形面積代碼
 - 6什么是 WSH(腳本宿主)的詳細(xì)解釋
 - 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
 - 8正則表達(dá)式匹配各種特殊字符
 - 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
 - 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
 
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
 - 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
 - 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
 - 04-02c語(yǔ)言用函數(shù)寫(xiě)分段 用c語(yǔ)言表示分段
 - 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
 - 04-02c語(yǔ)言編寫(xiě)函數(shù)冒泡排序 c語(yǔ)言冒泡排
 - 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
 - 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
 - 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
 - 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
 
隨機(jī)閱讀
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
 - 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
 - 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
 - 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
 - 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
 - 01-10C#中split用法實(shí)例總結(jié)
 - 04-02jquery與jsp,用jquery
 - 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
 - 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
 - 01-10delphi制作wav文件的方法
 


