【数据结构 05】双链表

一、原理

双链表又称双向链表,通常情况下是带头循环结构,在C++STL标准模板库中封装的头文件就是带头双向循环链表。

特性:增删灵活且高效,支持随机增删但不支持随机访问

【数据结构 05】双链表_第1张图片

设计思路:

  1. 链表包含一个头节点head,不存储数据,用于链表的维护,提高数据增删效率
  2. 每一个链表节点Node都包含一个数据和两个指针(前驱指针prev和后继指针next)
  3. 前驱指针prev指向前一个节点,后继指针next指向后一个节点
  4. 当链表为空时,头结点head的prev指针和next指针都指向head自身
  5. 节点的增删通过前后指针指向的改变即可完成,无需数据移动,效率高

二、DoubleList.h

#define _CRT_SECURE_NO_WARNINGS 1

#include 
#include 
#include 

typedef int DataType;

typedef struct Node
{
	DataType data;
	struct Node* next;
	struct Node* prev;
}Node;

typedef struct List
{
	Node* head;
}List;

void Init(List* plist)
{
	plist->head = (Node*)malloc(sizeof(Node));
	plist->head->prev = plist->head;
	plist->head->next = plist->head;
}

bool Empty(List* plist)
{
	return plist->head == plist->head->next;
}

Node* BuyNode(DataType x)
{
	Node* node = (Node*)malloc(sizeof(Node));
	node->data = x;
	node->next = NULL;
	node->prev = NULL;
}

void PushFront(List* plist, DataType x)
{
	Node* node = BuyNode(x);

	if (Empty(plist))
	{
		node->next = plist->head;
		node->prev = plist->head;
		plist->head->next = node;
		plist->head->prev = node;
	}
	else
	{
		Node* next = plist->head->next;
		node->prev = plist->head;
		node->next = next;
		next->prev = node;
		plist->head->next = node;
	}
}

void PushBack(List* plist, DataType x)
{
	Node* node = BuyNode(x);

	if (Empty(plist))
	{
		node->next = plist->head;
		node->prev = plist->head;
		plist->head->next = node;
		plist->head->prev = node;
	}
	else
	{
		Node* prev = plist->head->prev;
		node->next = plist->head;
		node->prev = prev;
		prev->next = node;
		plist->head->prev = node;
	}
}

void PopFront(List* plist)
{
	if (Empty(plist))
	{
		printf("双链表为空,头删失败\n");
		return;
	}

	Node* cur = plist->head->next;
	plist->head->next = cur->next;
	cur->next->prev = plist->head;

	free(cur);
	cur = NULL;
}

void PopBack(List* plist)
{
	if (Empty(plist))
	{
		printf("双链表为空,尾删失败\n");
		return;
	}

	Node* cur = plist->head->prev;
	plist->head->prev = cur->prev;
	cur->prev->next = plist->head;

	free(cur);
	cur = NULL;
}

Node* Find(List* plist, DataType x)
{
	Node* cur = plist->head->next;
	while (cur != plist->head)
	{
		if (cur->data == x)
			return cur;
		cur = cur->next;
	}
	return NULL;
}

void InsertFront(Node* pos, DataType x)
{
	if (pos == NULL)
	{
		printf("pos为空,插入失败\n");
		return;
	}

	Node* node = BuyNode(x);

	Node* prev = pos->prev;
	prev->next = node;
	node->prev = prev;
	node->next = pos;
	pos->prev = node;
}

void Delete(Node* pos)
{
	if (pos == NULL)
	{
		printf("pos为空,Delete失败\n");
		return;
	}
	
	Node* next = pos->next;
	Node* prev = pos->prev;

	next->prev = prev;
	prev->next = next;

	free(pos);
	pos = NULL;
}

void Destroy(List* plist)
{
	while (!Empty(plist))
	{
		PopFront(plist);
	}
	free(plist->head);
	plist->head = NULL;
	printf("双链表销毁成功\n");
}

void Print(List* plist)
{
	if (plist->head == NULL)
	{
		printf("双链表不存在\n");
		return;
	}

	Node* cur = plist->head->next;
	printf("head -> ");
	while (cur != plist->head)
	{
		printf("%2d -> ", cur->data);
		cur = cur->next;
	}
	printf("head\n");
}

三、test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "DoubleList.h"

int main()
{
	List list;
	Init(&list);
	Print(&list);	// head -> head

	// 尾插数据
	PushBack(&list, 1);
	PushBack(&list, 3);
	PushBack(&list, 5);
	PushBack(&list, 7);
	Print(&list); // head -> 1 -> 3 -> 5 -> 7 -> head

	// 头插数据
	PushFront(&list, 2);
	PushFront(&list, 4);
	PushFront(&list, 6);
	PushFront(&list, 8);
	Print(&list); // head -> 8 -> 6 -> 4 -> 2 -> 1 -> 3 -> 5 -> 7->head

	// 尾删数据
	PopBack(&list);
	PopBack(&list);
	PopBack(&list);
	Print(&list); // head -> 8 -> 6 -> 4 -> 2 -> 1 -> head

	// 头删数据
	PopFront(&list);
	PopFront(&list);
	PopFront(&list);
	Print(&list); // head -> 2 -> 1 -> head

	// 在查询的节点前插入数据
	InsertFront(Find(&list, 1), 11);
	InsertFront(Find(&list, 11), 111);
	Print(&list); // head -> 2 -> 111 -> 11 -> 1 -> head

	// 删除查询的节点
	Delete(Find(&list, 1));
	Delete(Find(&list, 11));
	Delete(Find(&list, 111));
	Print(&list); // head -> 2 -> head

	// 销毁链表
	Destroy(&list); // 链表销毁成功
	Print(&list); // 链表不存在
	return 0;
}

你可能感兴趣的:(数据结构,数据结构)