C实现带头节点带环双向链表的操作

Dlinklist.h

#pragma once 

#include <stdio.h>
#include <windows.h>
#include <stdlib.h>

typedef char DLinkType;

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


linkpoint Get_NewNode(DLinkType data);//开辟新的节点
void Destory_Node(linkpoint To_Delete);//删除节点
void DLinkListInit(linkpoint* head);//初始化双向链表
void DLinkListPushBack(linkpoint head, DLinkType value);//双向链表尾插
void DLinListPopBack(linkpoint head);//双向链表尾删
void DLinkListDisplay(linkpoint head);//链表打印(顺序和逆序)
void DLinkListPushFront(linkpoint head, DLinkType value);//双向链表头插
void DLinkListPopFront(linkpoint head);//双向链表头删
linkpoint DLinkListFind(linkpoint head, DLinkType to_find);//按照数值寻找节点
void DLinkListInsert(linkpoint pos, DLinkType value);//往指定位置之前插入一个元素
void DLinkListInsertAfter(linkpoint pos, DLinkType value);//往指定位置之后插入一个节点
void DLinkListErase(linkpoint pos);//删除指定位置的节点
void DLinkListRemove(linkpoint head, DLinkType value);//删除指定数值的元素(所有的)
size_t DLinkListSize(linkpoint head);//求双向链表的长度
int DLinkListEmpty(linkpoint head);//判断链表是否为空


Dlinklist.c

#include "Dlinklist.h"

linkpoint Get_NewNode(DLinkType data)//开辟新的节点
{
	linkpoint ret = (linkpoint)malloc(sizeof(DLinkNode));
	ret->data = data;
	ret->next = ret;
	ret->prev = ret;
	return ret;
}

void Destory_Node(linkpoint To_Delete)//删除节点
{
	free(To_Delete);
}

void DLinkListInit(linkpoint* head)//初始化双向链表
{
	*head = Get_NewNode('D');
}

void DLinkListPushBack(linkpoint head, DLinkType value)//双向链表尾插
{
	if (head == NULL)
	{
		return;
	}
	linkpoint New_Tail = Get_NewNode(value);
	linkpoint Old_Tail = head->prev;
	//New_tail vs head
	New_Tail->next = head;
	head->prev = New_Tail;
	//Old_Tail vs New_Tail
	Old_Tail->next = New_Tail;
	New_Tail->prev = Old_Tail;
}

void DLinListPopBack(linkpoint head)//双向链表尾删
{
	if (head == NULL)//非法输入
	{
		return;
	}
	if (head->next == head)//只有空节点
	{
		return;
	}
	linkpoint Delete_Tail = head->prev;
	linkpoint New_Tail = head->prev->prev;
	Destory_Node(Delete_Tail);
	//New_Tail vs head
	head->prev = New_Tail;
	New_Tail->next = head;
}

void DLinkListDisplay(linkpoint head)//链表打印(顺序和逆序)
{
	if (head == NULL)//非法输入
	{
		return;
	}
	if (head->next == head)//链表为空
	{
		return;
	}
	linkpoint cur = head->next;
	while (cur != head)
	{
		printf("%c ", cur->data);
		cur = cur->next;
	}
	printf("\n");
	cur = head->prev;
	while (cur != head)
	{
		printf("%c ", cur->data);
		cur = cur->prev;
	}
}

void DLinkListPushFront(linkpoint head, DLinkType value)//双向链表头插
{
	if (head == NULL)//非法输入
	{
		return;
	}
	linkpoint New_Head = Get_NewNode(value);
	linkpoint Old_Head = head->next;
	//head vs New_Head
	head->next = New_Head;
	New_Head->prev = head;
	//New_Head vs Old_Head
	New_Head->next = Old_Head;
	Old_Head->prev = New_Head;
}

void DLinkListPopFront(linkpoint head)//双向链表头删
{
	if (head == NULL)
	{
		return;
	}
	if (head->next == head)
	{
		return;
	}
	linkpoint To_Delete = head->next;
	linkpoint New_Head = head->next->next;
	//New_Head vs head
	head->next = New_Head;
	New_Head->prev = head;
	Destory_Node(To_Delete);
}

linkpoint DLinkListFind(linkpoint head, DLinkType to_find)//按照数值寻找节点
{
	if (head == NULL)
	{
		return NULL;
	}
	if (head->next == head)
	{
		return NULL;
	}
	linkpoint cur = head->next;
	while (cur != head)
	{
		if (cur->data == to_find)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

void DLinkListInsert(linkpoint pos, DLinkType value)//往指定位置之前插入一个元素
{
	if (pos == NULL)
	{
		return;
	}
	linkpoint Before_Pos = pos->prev;
	linkpoint New_Node = Get_NewNode(value);
	//NewNode vs Before_Pos
	Before_Pos->next = New_Node;
	New_Node->prev = Before_Pos;
	//New_Node vs pos
	New_Node->next = pos;
	pos->prev = New_Node;
}

void DLinkListInsertAfter(linkpoint pos, DLinkType value)//往指定位置之后插入一个节点
{
	if (pos == NULL)
	{
		return;
	}
	linkpoint After_pos = pos->next;
	linkpoint New_Node = Get_NewNode(value);
	//New_Node vs After_pos
	New_Node->next = After_pos;
	After_pos->prev = New_Node;
	//New_Node vs pos
	New_Node->prev = pos;
	pos->next = New_Node;
}

void DLinkListErase(linkpoint pos)//删除指定位置的节点
{
	if (pos == NULL)
	{
		return;
	}
	if (pos->next == pos && pos->prev == pos)
	{
		return;
	}
	linkpoint Before_pos = pos->prev;
	linkpoint After_pos = pos->next;
	//Before_pos vs After_pos 
	Before_pos->next = After_pos;
	After_pos->prev = Before_pos;
	Destory_Node(pos);
}

void DLinkListRemove(linkpoint head, DLinkType value)//删除指定数值的元素
{
	if (head == NULL)
	{
		return;
	}
	if (head->next == head && head->prev == head)
	{
		return;
	}
	linkpoint cur = head->next;
	while (cur != head)
	{
		linkpoint temp = cur->next;
		if (cur->data == value)
		{
			DLinkListErase(cur);//删除指定位置的节点
		}
		cur = temp;
	}
}

size_t DLinkListSize(linkpoint head)//求双向链表的长度
{
	if (head == NULL)
	{
		return -1;
	}
	int count = 0;
	linkpoint cur = head->next;
	while (cur != head)
	{
		count++;
		cur = cur->next;
	}
	return count;
}

int DLinkListEmpty(linkpoint head)//判断链表是否为空
{
	if (head == NULL)
	{
		return -1;
	}
	if (head->next == head && head->prev == head)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}

test.c

#include "Dlinklist.h"

int main()
{
	linkpoint head = NULL;
	DLinkListInit(&head);//初始化双向链表
	DLinListPopBack(head);//双向链表尾删
	DLinkListPushBack(head, 'a');//双向链表尾插
	DLinkListPushBack(head, 'b');//双向链表尾插
	DLinkListPushBack(head, 'c');//双向链表尾插
	DLinkListPushBack(head, 'd');//双向链表尾插
	DLinkListPushBack(head, 'b');//双向链表尾插
	DLinkListPushBack(head, 'b');//双向链表尾插
	DLinListPopBack(head);//双向链表尾删
	DLinkListDisplay(head);//链表打印(顺序和逆序)
	printf("\n");
	DLinkListPushFront(head, '8');//双向链表头插7
	DLinkListPushFront(head, '7');//双向链表头插
	DLinkListPushFront(head, '6');//双向链表头插
	DLinkListPopFront(head);//双向链表头删
	linkpoint listfind_ret = DLinkListFind(head, 'c');//按照数值寻找节点
	DLinkListInsert(listfind_ret, '0');//往指定位置之前插入一个元素
	DLinkListInsertAfter(listfind_ret, '1');//往指定位置之后插入一个节点
	DLinkListDisplay(head);//链表打印(顺序和逆序)
	printf("\n");
	DLinkListRemove(head, 'b');//删除指定数值的元素
	DLinkListDisplay(head);//链表打印(顺序和逆序)
	size_t len_ret = DLinkListSize(head);//求双向链表的长度
	int Empty_ret = DLinkListEmpty(head);//判断链表是否为空
	if (Empty_ret == -1)
	{
		printf("输入非法");
	}
	else if (Empty_ret == 0)
	{	
		printf("链表为空");
	}
	else
	{
		printf("链表不为空");
	}
	system("pause");
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值