1. 程式人生 > 實用技巧 >雙向連結串列的增,刪,改,查

雙向連結串列的增,刪,改,查

由於單向連結串列只能從頭遍歷,那麼在做增刪改查操作時,必須從頭結點開始遍歷。特別是在尾節點做追加操作時,需要將所有節點全部遍歷一遍。在時間上花費較多。但是雙向連結串列就不存在這個問題,在對雙向連結串列做追加操作時只需要對頭結點的先序節點進行一次遍歷就到達了連結串列的尾部。這樣就大大的減少了時間上的開銷。

以下是雙向連結串列的結構示意圖:

可以看出,每個節點都有兩個指標,一個指向前面,一個指向後面。指向前面的叫先序節點,指向後面的叫後繼結點。

我們通過這兩個指標來訪問所有節點,並通過他們來對連結串列進行操作。

雙鏈表刪除節點

以下是對應程式碼:

void DeleteNode(Node *head,int num)     //刪除一個節點
{
	int i = 0;
	Node *temp = NULL;
	for(i=0;i<num;i++)
	{
		head = head->next;
	}
	temp = head;  //先暫存被刪除節點
	head->prior->next = head->next;
	head->next->prior = head->prior;
	free(temp);
	printf("刪除完畢\n");
}

雙鏈表增加節點

對應程式碼:

void InsertNode(Node *head,int num,int data)    //在第num個數後面插入一個節點
{
	int i= 0;
	Node *temp = (Node*)malloc(sizeof(Node));
	Node *tp = head;
	temp->data = data;
	
	for(i=0;i<num&&(head->next!=tp);i++)
	{
		head = head->next;	
	}
	temp->next = head->next;
	temp->prior = head;
	head->next->prior = temp;
	head->next = temp;
	printf("插入成功\n");
}

為便於測試,我在這裡貼上所有程式碼,如下:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct ListNode
{
	int data;
	struct ListNode *prior; //前驅節點
	struct ListNode *next; //後驅節點
}Node;

int AddNode(Node *head,int data)  //在連結串列尾部增加一個節點
{
	Node *temp = (Node *)malloc(sizeof(Node));
	temp->data = data;
	temp->next = head;
	temp->prior = head->prior;
	head->prior->next = temp;
	head->prior = temp;
}

void PrintList(Node *head)		//列印所有節點
{
	Node *temp = head;
	while (head->next!=temp)  //判斷連結串列是否到了尾部
	{
		head = head->next;
		printf("%d  ",head->data);
	}
	printf("\n");
}

void Reverse_PrintList(Node *head)		//倒序列印所有節點
{
	Node *temp = head;
	while (head->prior!=temp)  //判斷連結串列是否到了頭部
	{
		head = head->prior;
		printf("%d  ",head->data);
	}
	printf("\n");
}

void DeleteNode(Node *head,int num)     //刪除一個節點
{
	int i = 0;
	Node *temp = NULL;
	for(i=0;i<num;i++)
	{
		head = head->next;
	}
	temp = head;  //先暫存被刪除節點
	head->prior->next = head->next;
	head->next->prior = head->prior;
	free(temp);
	printf("刪除完畢\n");
}
 
void InsertNode(Node *head,int num,int data)    //在第num個數後面插入一個節點
{
	int i= 0;
	Node *temp = (Node*)malloc(sizeof(Node));
	Node *tp = head;
	temp->data = data;
	
	for(i=0;i<num&&(head->next!=tp);i++)
	{
		head = head->next;	
	}
	temp->next = head->next;
	temp->prior = head;
	head->next->prior = temp;
	head->next = temp;
	printf("插入成功\n");
}

int main(int argc,char *argv[])
{
	int i = 0;
	Node *head = (Node *)malloc(sizeof(Node));
	head->prior = head;
	head->next = head;

	for (i=0;i<5;i++)
	{
		AddNode(head,i);
	}
	PrintList(head);
	

	AddNode(head,99);
	PrintList(head);
	InsertNode(head,6,66);
	PrintList(head);
	InsertNode(head,3,33);
	PrintList(head);

	Reverse_PrintList(head);
	//printf("Hello World!\r\n");
	system("pause");
	return 0;
}



還有些資料可以給學習的夥伴參考

迴圈連結串列及線性表的應用

http://www.makeru.com.cn/course/details/1902?s=45051

單鏈表

http://www.makeru.com.cn/live/5413_1924.html?s=45051

C語言程式設計基礎

http://www.makeru.com.cn/live/1758_311.html?s=45051

C語言(系列“點標題下的開始學習就可以看了”)

http://www.makeru.com.cn/course/details/2233?s=45051

提升C程式設計能力

http://www.makeru.com.cn/live/1392_1166.html?s=45051