带头节点的双向链表

双向链表

  • 前言
  • 带头+双向+循环链表增删查改实现
    • 创建返回链表的头结点
    • 双向链表销毁
    • 双向链表打印
    • 双向链表尾插
    • 双向链表尾删
    • 双向链表头插
    • 双向链表头删
    • 双向链表查找
    • 双向链表在pos的前面进行插入
    • 双向链表删除pos位置的节点
    • 测试函数功能
  • 完整代码

前言

  带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了,后面我们代码实现了就知道了。

带头+双向+循环链表增删查改实现

创建返回链表的头结点

ListNode* ListCreate()
{
     
	ListNode* pHead = BuyListNode(0);
	pHead->next = pHead;
	pHead->prev = pHead;
	return pHead;
}

双向链表销毁

void ListDestory(ListNode** pHead)
{
     
	assert(pHead);
	ListNode* cur = (*pHead)->next;

	while (cur!=*pHead)
	{
     
		(*pHead)->next = cur->next;
		free(cur);
		cur = (*pHead)->next;
	}

	free(*pHead);
	*pHead = NULL;
}

双向链表打印

void ListPrint(ListNode* pHead)
{
     
	assert(pHead);
	ListNode* cur = pHead->next;
	while (cur != pHead)
	{
     
		printf("%d--->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

双向链表尾插

void ListPushBack(ListNode* pHead, LTDataType x)
{
     
	//ListNode* newNode = BuyListNode(x);
	//newNode->next = pHead;
	//newNode->prev = pHead->prev;
	//pHead->prev->next = newNode;
	//pHead->prev = newNode;

	ListInsert(pHead, x);
}

双向链表尾删

void ListPopBack(ListNode* pHead)
{
     
	assert(pHead);
	ListNode* DelNode = pHead->prev;
	DelNode->prev->next = pHead;
	pHead->prev = DelNode->prev;
	free(DelNode);
}

双向链表头插

void ListPushFront(ListNode* pHead, LTDataType x)
{
     
	
	//ListNode* newNode = BuyListNode(x);
	//newNode->next = pHead->next;
	//newNode->prev = pHead;
	//pHead->next = newNode;
	//pHead->next->prev = newNode;

	ListInsert(pHead->next, x);
}

双向链表头删

void ListPopFront(ListNode* pHead)
{
     
	assert(pHead);
	ListNode* DelNode = pHead->next;
	pHead->next = DelNode->next;
	DelNode->next->prev = pHead;
	free(DelNode);
}

双向链表查找

ListNode* ListFind(ListNode* pHead, LTDataType x)
{
     
	assert(pHead);
	ListNode* cur = pHead->next;
	while (cur != pHead)
	{
     
		if (cur->data == x)
		{
     
			return cur;
		}
		cur = cur->next;
	}
	printf("没有这个数\n");
	return NULL;
}

双向链表在pos的前面进行插入

void ListInsert(ListNode* pos, LTDataType x)
{
     
	if (NULL == pos)
	{
     
		return ;
	}
	ListNode* newNode = BuyListNode(x);
	newNode->next = pos;
	newNode->prev=pos->prev;
	pos->prev->next = newNode;
	pos->prev = newNode;
}

双向链表删除pos位置的节点

void ListErase(ListNode* pos)
{
     
	if (NULL == pos)
	{
     
		return ;
	}
	pos->prev->next = pos->next;
	pos->next->prev = pos->prev;
	free(pos);
}

测试函数功能

void TestList()
{
     
	ListNode* head = ListCreate();

	ListPushBack(head, 1);
	ListPushBack(head, 2);
	ListPushBack(head, 3);
	ListPushBack(head, 4);
	ListPushBack(head, 5);
	ListPrint(head);

	ListInsert(head->next, 0);
	ListPrint(head);

	ListInsert(ListFind(head, 5), 6);
	ListPrint(head);

	ListErase(ListFind(head, 6));
	ListPrint(head);

	ListDestory(&head);
}

结果为:
带头节点的双向链表_第1张图片

完整代码

ListNode.h

#pragma once

#include
#include
#include
#include

// 带头+双向+循环链表增删查改实现
typedef int LTDataType;
typedef struct ListNode
{
     
	LTDataType data;
	struct ListNode* next;
	struct ListNode* prev;
}ListNode;

// 创建返回链表的头结点.
ListNode* ListCreate();
// 双向链表销毁
void ListDestory(ListNode** pHead);
// 双向链表打印
void ListPrint(ListNode* pHead);
// 双向链表尾插
void ListPushBack(ListNode* pHead, LTDataType x);
// 双向链表尾删
void ListPopBack(ListNode* pHead);
// 双向链表头插
void ListPushFront(ListNode* pHead, LTDataType x);
// 双向链表头删
void ListPopFront(ListNode* pHead);
// 双向链表查找
ListNode* ListFind(ListNode* pHead, LTDataType x);
// 双向链表在pos的前面进行插入
void ListInsert(ListNode* pos, LTDataType x);
// 双向链表删除pos位置的节点
void ListErase(ListNode* pos);

void TestList();

ListNode.c

#include"ListNode.h"

// 申请链表的一个新结点.
ListNode* BuyListNode(LTDataType data)
{
     
	ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
	if (NULL == newNode)
	{
     
		assert(0);
		return NULL;
	}
	newNode->data=data;
	newNode->next = NULL;
	newNode->prev = NULL;
	return newNode;
}

//创建返回链表的头结点
ListNode* ListCreate()
{
     
	ListNode* pHead = BuyListNode(0);
	pHead->next = pHead;
	pHead->prev = pHead;
	return pHead;
}

// 双向链表销毁
void ListDestory(ListNode** pHead)
{
     
	assert(pHead);
	ListNode* cur = (*pHead)->next;

	while (cur!=*pHead)
	{
     
		(*pHead)->next = cur->next;
		free(cur);
		cur = (*pHead)->next;
	}

	free(*pHead);
	*pHead = NULL;
}

// 双向链表打印
void ListPrint(ListNode* pHead)
{
     
	assert(pHead);
	ListNode* cur = pHead->next;
	while (cur != pHead)
	{
     
		printf("%d--->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

// 双向链表尾插
void ListPushBack(ListNode* pHead, LTDataType x)
{
     
	//ListNode* newNode = BuyListNode(x);
	//newNode->next = pHead;
	//newNode->prev = pHead->prev;
	//pHead->prev->next = newNode;
	//pHead->prev = newNode;

	ListInsert(pHead, x);
}

// 双向链表尾删
void ListPopBack(ListNode* pHead)
{
     
	assert(pHead);
	ListNode* DelNode = pHead->prev;
	DelNode->prev->next = pHead;
	pHead->prev = DelNode->prev;
	free(DelNode);
}

// 双向链表头插
void ListPushFront(ListNode* pHead, LTDataType x)
{
     
	
	//ListNode* newNode = BuyListNode(x);
	//newNode->next = pHead->next;
	//newNode->prev = pHead;
	//pHead->next = newNode;
	//pHead->next->prev = newNode;

	ListInsert(pHead->next, x);
}

// 双向链表头删
void ListPopFront(ListNode* pHead)
{
     
	assert(pHead);
	ListNode* DelNode = pHead->next;
	pHead->next = DelNode->next;
	DelNode->next->prev = pHead;
	free(DelNode);
}

// 双向链表查找
ListNode* ListFind(ListNode* pHead, LTDataType x)
{
     
	assert(pHead);
	ListNode* cur = pHead->next;
	while (cur != pHead)
	{
     
		if (cur->data == x)
		{
     
			return cur;
		}
		cur = cur->next;
	}
	printf("没有这个数\n");
	return NULL;
}

// 双向链表在pos的前面进行插入
void ListInsert(ListNode* pos, LTDataType x)
{
     
	if (NULL == pos)
	{
     
		return ;
	}
	ListNode* newNode = BuyListNode(x);
	newNode->next = pos;
	newNode->prev=pos->prev;
	pos->prev->next = newNode;
	pos->prev = newNode;
}

// 双向链表删除pos位置的节点
void ListErase(ListNode* pos)
{
     
	if (NULL == pos)
	{
     
		return ;
	}
	pos->prev->next = pos->next;
	pos->next->prev = pos->prev;
	free(pos);
}

void TestList()
{
     
	ListNode* head = ListCreate();

	ListPushBack(head, 1);
	ListPushBack(head, 2);
	ListPushBack(head, 3);
	ListPushBack(head, 4);
	ListPushBack(head, 5);
	ListPrint(head);

	ListInsert(head->next, 0);
	ListPrint(head);

	ListInsert(ListFind(head, 5), 6);
	ListPrint(head);

	ListErase(ListFind(head, 6));
	ListPrint(head);

	ListDestory(&head);
}

main.c

#include"ListNode.h"

int main()
{
     
	TestList();
	system("pause");
	return 0;
}

你可能感兴趣的:(数据结构与算法,c语言,链表)