1. 程式人生 > >資料結構之雙鏈表----增刪改查(C語言)

資料結構之雙鏈表----增刪改查(C語言)

原始碼在部落格裡可下載,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函式呼叫,讀者可以根據自己的需求呼叫不用函式 在這裡插入圖片描述