数据结构 双向链表的简单操作

以下是有关双向链表的一些简单操作,例如增删查改。

link.h
#pragma once

#include <stdio.h>

#define TITLE printf("\n========================%s======================\n",__FUNCTION__);

typedef char DLinkType;

typedef struct DLinkNode
{
	DLinkType data;
	struct DLinkNode* next;
	struct DLinkNode* prev;
}DLinkNode;

DLinkNode* CreateNode(DLinkType value); //创建结点
void DestroyNode(DLinkNode** to_delete);//销毁结点

void DLinkListInit(DLinkNode** head);  //初始化
void DLinkListPrint(DLinkNode* head,const char *msg); //链表打印
void DLinkListPushBack(DLinkNode* head, DLinkType value);//尾插一个元素
void DLinkListPopBack(DLinkNode* head);//尾删
void DLinkListPushFront(DLinkNode* head, DLinkType value);//头插一个元素
void DLinkListPopFront(DLinkNode* head);//头删
DLinkNode* DLinkListFind(DLinkNode* head, DLinkType to_find);//查找元素
void DLinkListInsert(DLinkNode*head,DLinkNode* pos, DLinkType value);//指定位置前插入一个元素
void DLinkListInsertAfter(DLinkNode*head,DLinkNode* pos, DLinkType value);//指定位置后插入一个元素
void DLinkListErase(DLinkNode* head,DLinkNode* pos);//删除结点pos
void DLinkListRemove(DLinkNode* head,DLinkType value);//删除指定元素结点
void DLinkListRemoveAll(DLinkNode* head,DLinkType value);//删除指定元素所有结点 
size_t DLinkListSize(DLinkNode* head);//返回链表结点数
int DLinkListEmpty(DLinkNode* head);//判断链表是否为空,链表为空返回0,链表不为空返回1
link.c
#include "link.h"
#include <stdlib.h>
#include <stddef.h>


DLinkNode* CreateNode(DLinkType value)
{
	DLinkNode* new_node = (DLinkNode*)malloc(sizeof(DLinkNode));
	new_node->data = value;
	new_node->next = new_node;
	new_node->prev = new_node;
	return new_node;
}

void DestroyNode(DLinkNode** to_delete)
{
	free(*to_delete);
}


void DLinkListPrint(DLinkNode* head,const char* msg)
{
	printf("[%s]:\n",msg);
	if(head == NULL)
	{
		return;
	}
	DLinkNode* cur = head->next;
	while(cur != head)
	{
		printf("[%c|%p] ",cur->data,cur);
		cur = cur->next;
	}
	printf("\n");
	cur = head->prev;
	while(cur != head)
	{
		printf("[%c|%p] ",cur->data,cur);	
		cur = cur->prev;
	}
	printf("\n");
}

void DLinkListInit(DLinkNode** head)
{
	if(head == NULL)
	{
		//非法输入
		return;
	}
	*head = CreateNode(0);
}


void DLinkListPushBack(DLinkNode* head, DLinkType value)
{
	if(head == NULL)
	{
		//非法输入
		return;
	}
	DLinkNode* tail = head->prev;
	DLinkNode* new_node = CreateNode(value);
	//tail vs new_node
	tail->next = new_node;
	new_node->prev = tail;
	//head vs new_node
	new_node->next = head;
	head->prev = new_node;
	return;
}

void DLinkListPopBack(DLinkNode* head)
{
	if(head == NULL)
	{
		//非法输入
		return;
	}
	if(head->next == head)
	{
		DestroyNode(&head);
		return;
	}
	DLinkNode* tail = head->prev;
	DLinkNode* Prev = tail->prev;

	//Prev vs head
	Prev->next = head;
	head->prev = Prev;

}

void DLinkListPushFront(DLinkNode* head, DLinkType value)
{
	if(head == NULL)
	{
		return;
	}
	DLinkNode* new_node = CreateNode(value);
	DLinkNode* Prev = head->next;

	//new_node vs Prev
	new_node->next = Prev;
	Prev->prev = new_node;

	//new_node vs head
	head->next = new_node;
	new_node->prev = head;
	return;
}

void DLinkListPopFront(DLinkNode* head)
{
	if(head == NULL)
	{
		return;
	}
	if(head->next == head)
	{
		DestroyNode(&head);
		return;
	}
	DLinkNode* to_delete = head->next;
	DLinkNode* next = to_delete->next;
	head->next = next;
	next->prev = head;
	DestroyNode(&to_delete);
	return;
}

DLinkNode* DLinkListFind(DLinkNode* head, DLinkType to_find)
{
	if(head == NULL)
	{
		return NULL;
	}
	DLinkNode* cur = head->next;
	while(cur != head)
	{
		if(cur->data == to_find)
		return cur;
		cur = cur->next;
	}
	return NULL;

}


void DLinkListInsert(DLinkNode*head,DLinkNode* pos, DLinkType value)
{
	if(head == NULL)
	{
		return;
	}
	if(pos == NULL)
	{
		return;
	}
	DLinkNode* new_node = CreateNode(value);
	DLinkNode* pos_prev = pos->prev;
	//new_node vs pos_prev
	pos_prev->next = new_node;
	new_node->prev = pos_prev;

	//new_node vs pos
	new_node->next = pos;
	pos->prev = new_node;
}

void DLinkListInsertAfter(DLinkNode*head,DLinkNode* pos, DLinkType value)
{
	if(head == NULL)
	{
		return;
	}
	if(pos == NULL)
	{
		return;
	}
	DLinkNode* new_node = CreateNode(value);
	DLinkNode* pos_next = pos->next;
	//new_node vs pos
	pos->next = new_node;
	new_node->prev = pos;

	//new_node vs pos->next
	new_node->next = pos_next;
	pos_next->prev = new_node;
}

void DLinkListErase(DLinkNode* head,DLinkNode* pos)
{
	if(head == NULL)
	{
		return;
	}
	if(pos == NULL)
	{
		return;	
	}
	DLinkNode* next = pos->next;
	DLinkNode* prev = pos->prev;
	//prev vs next
	prev->next = next;
	next->prev = prev;
	DestroyNode(&pos);
	return;
}

void DLinkListRemove(DLinkNode* head,DLinkType value)
{
	if(head == NULL)	
	{
		return;	
	}
	DLinkNode* cur = head->next;
	while(cur != head)
	{
		if(cur->data == value)
		{
			DLinkNode* prev = cur->prev;
			DLinkNode* next = cur->next;
			prev->next = next;
			next->prev = prev;
			DestroyNode(&cur);
			return;
		}
		cur = cur->next;
	}
	return;
}


 void DLinkListRemoveAll(DLinkNode* head,DLinkType value)
{
	if(head == NULL)
	{
		return;
	}
	DLinkNode* cur = head->next;
	while(cur != head)
	{
		if(cur->data == value)	
		{
			DLinkNode* prev = cur->prev;
			DLinkNode* next = cur->next;
			prev->next = next;
			next->prev = prev;
			DLinkNode* to_delete = cur;
			DestroyNode(&to_delete);
			cur = prev;	
		}
		cur = cur->next;
	}
}

size_t DLinkListSize(DLinkNode* head)
{
	if(head == NULL)
	{
		return 0;
	}
	size_t count = 0;
	DLinkNode* cur = head->next;
	while(cur != head)
	{
		count++;
		cur = cur->next;
	}
	return count;
}

int DLinkListEmpty(DLinkNode* head)
{
	if(head == NULL)
	{
		return 0;	
	}
	if(head->next == head && head->prev == head)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}


//                               以下为测试代码                               //


void TestInit()
{
	TITLE;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPrint(head,"打印空链表");
}

void TestDLinkListPushBack()
{	
	TITLE;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head,'a');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'c');
	DLinkListPushBack(head,'d');
	DLinkListPrint(head,"尾插4个元素");
}

void TestDLinkListPopBack()
{
	TITLE;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head,'a');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'c');
	DLinkListPushBack(head,'d');
	DLinkListPrint(head,"尾插4个元素");
	DLinkListPopBack(head);
	DLinkListPopBack(head);
	DLinkListPrint(head,"尾删2个元素");
	DLinkListPopBack(head);
	DLinkListPopBack(head);
	DLinkListPrint(head,"再尾删2个元素");
	DLinkListPrint(head,"对空链表进行尾删");
}

void TestDLinkListPushFront()
{
	TITLE;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushFront(head,'a');
	DLinkListPushFront(head,'b');
	DLinkListPushFront(head,'c');
	DLinkListPushFront(head,'d');
	DLinkListPrint(head,"头插4个元素");
}

void TestDLinkListPopFront()
{	
	TITLE;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushFront(head,'a');
	DLinkListPushFront(head,'b');
	DLinkListPushFront(head,'c');
	DLinkListPushFront(head,'d');
	DLinkListPrint(head,"头插4个元素");
	DLinkListPopFront(head);
	DLinkListPopFront(head);
	DLinkListPrint(head,"头删2个元素");
	DLinkListPopFront(head);
	DLinkListPopFront(head);
	DLinkListPrint(head,"再头删2个元素");
	DLinkListPrint(head,"头删空链表");
}

void TestDLinkListFind()
{
	TITLE;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head,'a');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'c');
	DLinkListPushBack(head,'d');
	DLinkListPrint(head,"尾插4个元素");
	DLinkNode* find = DLinkListFind(head,'x');
	printf("[查找元素x]:%p\n",find);
	find = DLinkListFind(head,'c');
	printf("[查找元素c]:%p\n",find);
}

void TestDLinkListInsert()
{
	TITLE;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head,'a');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'c');
	DLinkListPushBack(head,'d');
	DLinkListPrint(head,"尾插4个元素");
	DLinkNode* pos_a = DLinkListFind(head,'a');
	DLinkListInsert(head,pos_a,'x');
	DLinkListPrint(head,"元素a之前插入x");
	DLinkNode* pos_c = DLinkListFind(head,'c');
	DLinkListInsert(head,pos_c,'h');
	DLinkListPrint(head,"元素c之前插入h");
}

void TestDLinkListInsertAfter()
{
	TITLE
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head,'a');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'c');
	DLinkListPushBack(head,'d');
	DLinkListPrint(head,"尾插4个元素");
	DLinkNode* pos_a = DLinkListFind(head,'a');
	DLinkListInsertAfter(head,pos_a,'x');
	DLinkListPrint(head,"元素a之后插入x");
	DLinkNode* pos_d = DLinkListFind(head,'d');
	DLinkListInsertAfter(head,pos_d,'h');
	DLinkListPrint(head,"元素d之后插入h");
}

void TestDLinkListErase()
{
	TITLE
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head,'a');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'c');
	DLinkListPushBack(head,'d');
	DLinkListPrint(head,"尾插4个元素");
	DLinkNode* pos_b = DLinkListFind(head,'b');
	DLinkListErase(head,pos_b);
	DLinkListPrint(head,"删除结点b");
}


void TestDLinkListRemove()
{
	TITLE
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head,'a');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'c');
	DLinkListPushBack(head,'d');
	DLinkListPrint(head,"尾插4个元素");
	DLinkListRemove(head,'b');
	DLinkListPrint(head,"删除元素b结点");
}

void TestDLinkListRemoveAll()
{
	TITLE
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head,'a');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'c');
	DLinkListPushBack(head,'d');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'b');
	DLinkListPrint(head,"尾插4个元素");
	DLinkListRemoveAll(head,'b');
	DLinkListPrint(head,"删除所有元素b结点");
}


void TestDLinkListSize()
{
	TITLE
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head,'a');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'c');
	DLinkListPushBack(head,'d');
	DLinkListPrint(head,"尾插4个元素");
	int t = DLinkListSize(head);
	printf("[链表长度为]:\nexpect is 4,actul is %d\n",t);
}

void TestDLinkListEmpty()
{
	TITLE
	DLinkNode* head;
	DLinkListInit(&head);
	int t = DLinkListEmpty(head);	
	printf("[链表是否为空]:\nexpect is 0,actul is %d\n",t);
	DLinkListPushBack(head,'a');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'c');
	DLinkListPushBack(head,'d');
	DLinkListPrint(head,"尾插4个元素");
	t = DLinkListEmpty(head);
	printf("[链表是否为空]:\nexpect is 1,actul is %d\n",t);
}
int main()
{
	TestInit();
	TestDLinkListPushBack();
	TestDLinkListPopBack();
	TestDLinkListPushFront();
	TestDLinkListPopFront();
	TestDLinkListFind();
	TestDLinkListInsert();
	TestDLinkListInsertAfter();
	TestDLinkListErase();
	TestDLinkListRemove();
	TestDLinkListRemoveAll();
	TestDLinkListSize();
	TestDLinkListEmpty();
	return 0;
}

以下为程序运行结果:






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值