資料結構之雙鏈表----增刪改查(C語言)
阿新 • • 發佈:2018-12-15
原始碼在部落格裡可下載,1C幣。或者找Q:128550014要程式碼
一、匯入標頭檔案
#include<stdlib.h>
#include<stdio.h>
二、結構體的定義
//定義一個結構體,用於表示雙鏈表的一個節點 typedef struct node { int data; //連結串列中的資料,此例中我們採用整型 struct node* Next;//本節點指向下一節點的指標 struct node* Prev;//本節點指向前一節點的指標 }D_list,*PD_list; //定義一個結構體,將雙鏈表的頭指標與尾指標放入,方便操作 typedef struct list { PD_list pHead; PD_list pTail; int length; //用於表示連結串列長度 }List,*pList;
三、功能函式的定義
本次雙鏈表共有7個函式:
//每次申請節點都要進行相同的操作,為了減少程式碼的重複書寫,我們定義一個函式 //用於申請一個新節點,並將節點的指標返回 PD_list createNode(int data); //初始化雙鏈表 void initList(pList p); //在頭結點處插入資料 void insertHead(pList p,int data); //在尾節點出插入新資料 void insertTail(pList p, int data); //在指定位置插入節點 void insertIndex(pList p, int index); //刪除指定位置出的節點 void deleteIndex(pList p, int index); //列印整個雙鏈表內的資料 void showList(pList p);
四、功能函式的依次實現
PD_list createNode(int data)
{
PD_list pnew = (PD_list)malloc(sizeof(D_list));//申請空間
pnew->data = data;//以下三局,對新節點進行初始化
pnew->Next = NULL;
pnew->Prev = NULL;
return pnew;//返回新節點指標
}
void initList(pList p) { //將頭結點和尾節點都賦值為空,長度為0 p->pHead = NULL; p->pTail = NULL; p->length = 0; }
void insertHead(pList p, int data)
{
//申請一個新節點
PD_list pnew = createNode(data);
if (p->pHead == NULL)//如果頭結點為空,說明雙鏈表為空,就將頭尾都指向新節點
{
p->pHead = pnew;
p->pTail = pnew;
p->length++;
}
else//如果頭節點不為空
{
pnew->Next = p->pHead;//先將新節點下一節點指向頭結點
p->pHead->Prev = pnew;//再將頭結點前一節點指向新節點
p->pHead = pnew;//最後將頭結點賦值給新節點,頭插法完成
p->length++;
}
}
void insertTail(pList p, int data)
{
PD_list pnew = createNode(data);//建立新節點
if (p->pHead == NULL)//判斷雙鏈表是否為空
{
p->pHead = pnew;//為空就講頭尾部節點都指向於新節點
p->pTail = pnew;
p->length++;//長度加1
}
else
{
pnew->Prev = p->pTail;//先將新節點的前指標指向原尾節點
p->pTail->Next = pnew;//再將原尾節點下一節點指標指向於新節點
p->pTail = pnew;//最後將新節點變為尾節點,功能完成
p->length++;//長度加1
}
}
void insertIndex(pList p, int index,int data)
{
PD_list pnew = createNode(data);//申請一個新節點
if (index<0 || index>p->length)//判斷下標是否有誤
{
printf("對不起,您輸入的位置有誤,無法插入!");
return;
}
else
{
PD_list ptemp = p->pHead;//定義一個輔助指標,先指向於頭部
for (int i = 0; i < index - 1; ++i)//迴圈遍歷到想要插入節點的前一節點
{
ptemp = ptemp->Next;
}
//4步連線
pnew->Next = ptemp->Next;//新節點下一節點指標指向插入位置的下一節點
pnew->Prev = ptemp;//新節點前一指標指向插入位置的前一節點
ptemp->Next->Prev = pnew;//新節點下一節點前指標再指向於新節點
ptemp->Next = pnew;//新節點前節點的下一節點指標指向於新節點
p->length++;//長度加1
}
}
void deleteIndex(pList p, int index)
{
if (index<0 || index>p->length)//判斷輸入的下標是否有誤
{
printf("對不起,您輸入的位置有誤!\n");
return;
}
else
{
PD_list ptemp = p->pHead;
for (int i = 0; i < index; ++i)//遍歷迴圈到想要刪除的下標節點處
{
ptemp = ptemp->Next;
}
//2步完成刪除並連線
ptemp->Prev->Next = ptemp->Next;//刪除位置前節點下一節點指向於刪除位置節點的下一節點
ptemp->Next->Prev = ptemp->Prev;//刪除位置的下節點前節點指標指向刪除位置的前節點
free(ptemp);//釋放掉刪除位置處的記憶體
p->length--;//長度減1
}
}
void showList(pList p)
{
//定義一個輔助指標,用於遍歷雙鏈表
PD_list ptemp = p->pHead;
while (ptemp->Next)//迴圈列印
{
printf("%d->", ptemp->data);
ptemp = ptemp->Next;
}
printf("%d\n", ptemp->data);
printf("雙鏈表長度為:%d\n", p->length);
}
五、雙鏈表的使用(main函式)
以下為我的main函式呼叫,讀者可以根據自己的需求呼叫不用函式