_數據結構_雙向鏈表

雙向鏈表結點

單鏈表的鏈式儲存只有一個指示後繼的指針域,因此,從某個結點出發只能順指針日後尋查其餘結點。若要尋查結點的直接前端,則須要從表頭指針出發。
    爲了克服單鏈表的單向性缺點,在雙向鏈表的結點中有兩個指針域,一個指向直接後繼,一個指向直接前趨。前端

typedef struct double_list
{
	int val; //結點的值
	struct double_list* next; //後繼結點的指針域
	struct double_list* pre;//前趨結點的指針域
}double_list;

在這裏插入圖片描述

雙向鏈表初始化

首先malloc一個結點的空間,剛剛初始化的頭節點,其前指針與後指針都賦值爲空。node

void inite(double_list** head)
{
	*head = (double_list*)malloc(sizeof(double_list));
	(*head)->next = NULL;
	(*head)->pre = NULL;	
}

這裏有一個坑,爲何參數是二級指針?
    由於結點中還有先後的指針域,因此若是傳遞一級指針,則出了函數做用域,先後指針仍是會返回默認的隨機地址。
web

雙向鏈表的插入

當新結點插入到鏈表當中時,與單鏈表操做相同,只不過多了一個前趨指針的指向,先將新結點的後指針指向後一個結點,前指針指向前一個結點,再將後結點的前指針指向新結點,前結點的後指針指向新結點,便可完成插入
在這裏插入圖片描述svg

頭插法

頭插法就是每當有新結點生成時,始終插入到頭節點後,頭插的實現相對簡單,可是頭插的順序與鏈表的輸出順序是相反的。
在這裏插入圖片描述函數

void push_front(double_list* head,int val)
{
	double_list* node = (double_list*)malloc(sizeof(double_list));
	node->val = val;
	head->next->pre = node;
	node->next = head->next;
	head->next = node;
	node->pre = head;
}

尾插法

尾插法也就是先將指針遍歷到鏈表尾部,再從尾部插入新結點
在這裏插入圖片描述spa

void push_back(double_list* head, int val)
{
	double_list* phead = head;
	double_list* node = (double_list*)malloc(sizeof(double_list));
	while (phead->next!= NULL)
	{
		phead = phead->next;
	}
	node->val = val;
	phead->next = node;
	node->next = NULL;
	node->pre = phead;
	
}

鏈表中刪除結點

結點的刪除相對簡單,只須要將要刪除的結點,前一個結點的後指針指向後一個結點,後一個結點的前指針指向前一個結點,再釋放掉該結點的內存便可。
在這裏插入圖片描述3d

void erase(double_list* node)
{
	node->next->pre = node->pre;
	node->pre->next = node->next;
	free(node);
	node = NULL;
}

頭刪

頭刪也就是每次都從頭節點的下一個結點刪除,每次刪除的都是鏈表中的第一個結點。指針

void pop_front(double_list* head)
{
	double_list* temp = head->next;
	head->next->next->pre = head;
	head->next = head->next->next;
	free(temp);
	temp = NULL;
}

尾刪

尾刪也就是每次都遍歷到鏈表結尾出,每次刪除鏈表的最後一個結點。code

void pop_back(double_list* head)
{
	double_list* phead = head;
	while (phead->next != NULL)
	{
		phead = phead->next;
	}
	phead->pre->next = NULL;
	free(phead);
	phead = NULL;
}

查找元素

double_list* find(double_list* head, int val)
{
	double_list* phead = head;
	while (phead != NULL)
	{
		if (phead->val == val)
			return phead;
		phead = phead->next;
	}
	return NULL;
}

遍歷整個鏈表,當找到與值相同的結點時,返回該結點xml

打印鏈表

void print_list(double_list* head)
{
	double_list* phead = head->next;
	while (phead->next != NULL)
	{
		printf("%d->", phead->val);
		phead = phead->next;
	}
	printf("%d", phead->val);
}