用C语言构建一个带头、双向、循环的链表

目录

函数头文件doublelist.h

函数定义文件doublelist.c

调试主函数文件main.c


函数头文件doublelist.h

#pragma once
#include<stdio.h>
#include<assert.h>
#define  DLTDataType  int  

typedef  struct  DListNode  DListNode;
struct  DListNode
{
	DListNode* prev;
	DListNode* next;
	DLTDataType  date;
};

DListNode* BuyDListNode(DLTDataType x);//建立一个新的节点
void DListNodePrint(DListNode* plist);//打印链表
void DListPushFront(DListNode* plist, DLTDataType x);//链表前端插入
void DListPushBack(DListNode* plist, DLTDataType x);//链表后端插入
void DListPopFront(DListNode* plist);//链表前端删除
void DListPopBack(DListNode* plist);//链表后端删除

DListNode* DListFind(DListNode* plist, DLTDataType x);//找到想要的节点地址
void DListInsertBefore( DListNode* pos, DLTDataType x);//节点前插入
void DListInsertAfter(DListNode* pos, DLTDataType x);//节点后插入
void DListEraseAfter(DListNode* plist, DListNode* pos);//节点后删除
void DListEraseBefore(DListNode* plist, DListNode* pos);//节点前删除


void DistroyDList(DListNode* plist);

函数定义文件doublelist.c

#include"doublelist.h"

DListNode* BuyDListNode(DLTDataType x)
{
	DListNode* newnode = (DListNode*)malloc(sizeof(DListNode));
	newnode->date = x;
	newnode->next = newnode;
	newnode->prev = newnode;
	return newnode;
}

void DListPushFront(DListNode* plist, DLTDataType x)
{
	assert(plist);
	DListNode* newnode = BuyDListNode(x);
	newnode->next = plist->next;
	newnode->next->prev = newnode;
	plist->next = newnode;
	newnode->prev = plist;
}
void DListPushBack(DListNode* plist, DLTDataType x)
{
	assert(plist);
	DListNode* newnode = BuyDListNode(x);
	plist->prev->next = newnode;
	newnode->prev = plist->prev;
	newnode->next = plist;
	plist->prev = newnode;
}
void DListPopFront(DListNode* plist)
{
	assert(plist);
	if (plist->next == plist)
	{
		return;
	}
	DListNode* cur = plist->next;
	plist->next = cur->next;
	cur->next->prev = plist;
	free(cur);
	cur = NULL;
}

void DListPopBack(DListNode* plist)
{
	assert(plist);
	if (plist->next == plist)
	{
		return;
	}
	DListNode* cur = plist->prev;
	plist->prev = cur->prev;
	cur->prev->next = plist;
	free(cur);
	cur = NULL;
}

void DListNodePrint(DListNode* plist)
{
	assert(plist);
	if (plist->next == plist)
	{
		return;
	}
	DListNode* cur = plist->next;
	while (cur != plist)
	{
		printf("%d->", cur->date);
		cur = cur->next;
	}
	printf("NULL\n");
}

DListNode* DListFind(DListNode* plist, DLTDataType x)
{
	assert(plist);
	DListNode* cur = plist->next;
	while (cur != plist)
	{
		if (cur->date == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

void DListInsertBefore( DListNode* pos, DLTDataType x)
{
	DListNode* prev = pos->prev;
	DListNode* newnode = BuyDListNode(x);
	newnode->prev = prev;
	newnode->next = pos;
	prev->next = newnode;
	pos->prev = newnode;
}

void DListInsertAfter(DListNode* pos, DLTDataType x)
{
	DListNode* next = pos->next;
	DListNode* newnode = BuyDListNode(x);
	newnode->prev = pos;
	newnode->next = next;
	pos->next = newnode;
	next->prev = newnode;
}

void DListEraseAfter(DListNode* plist, DListNode* pos)
{
	if (pos->next == plist)
	{
		return;
	}
	DListNode* after = pos->next->next;
	DListNode* cur = pos->next;
	pos->next = after;
	after->prev = pos;
	free(cur);
	cur = NULL;
}

void DListEraseBefore(DListNode* plist, DListNode* pos)
{
	if (pos->prev == plist)
	{
		return;
	}
	DListNode* before = pos->prev->prev;
	DListNode* cur = pos->prev;
	before->next = pos;
	pos->prev = before;
	free(cur);
	cur = NULL;
}
void DistroyDList(DListNode* plist)
{
	assert(plist);
	while (plist->next != plist)
	{
		DListPopBack(plist);
	}
	free(plist);
	plist = NULL;
}

调试主函数文件main.c

#define  _CRT_SECURE_NO_WARNINGS 1
#include"doublelist.h"

void test1()
{
	DListNode* plist = BuyDListNode(-1);
	DListPushFront(plist, 1);
	DListPushFront(plist, 2);
	DListPushFront(plist, 3);
	DListPushFront(plist, 4);
	DListNodePrint(plist);

	DListPushBack(plist, 1);
	DListPushBack(plist, 2);
	DListPushBack(plist, 3);
	DListPushBack(plist, 4);
	DListNodePrint(plist);

	DListPopFront(plist);
	DListPopFront(plist);
	DListPopFront(plist);
	DListPopFront(plist);
	DListPopFront(plist);
	DListPopFront(plist);
	DListNodePrint(plist);

	DListPopBack(plist);
	DListNodePrint(plist);

	DListNode* pos = DListFind(plist, 3);
	DListInsertBefore(pos, 6);
	DListInsertBefore(pos, 7);
	DListInsertBefore(pos, 8);
	DListInsertBefore(pos, 9);
	DListNodePrint(plist);

	DListInsertAfter(pos, 5);
	DListInsertAfter(pos, 1);
	DListNodePrint(plist);

	DListEraseAfter(plist, pos);
	DListNodePrint(plist);

	DListEraseBefore(plist, pos);
	DListNodePrint(plist);

	DistroyDList(plist);
	plist = NULL;
}


int main()
{
	test1();
	return 0;
}

下面是一个简单的C语言代码示例,用于构建一个双向循环链表: ```c #include <stdio.h> #include <stdlib.h> /* 定义链表节点结构体 */ typedef struct node { int data; struct node *prev; struct node *next; } Node; /* 初始化链表 */ void init_list(Node **head) { *head = NULL; } /* 创建新节点 */ Node *create_node(int data) { Node *new_node = (Node *)malloc(sizeof(Node)); if (new_node == NULL) { printf("Error: memory allocation failed!\n"); exit(1); } new_node->data = data; new_node->prev = NULL; new_node->next = NULL; return new_node; } /* 将节点插入链表尾部 */ void insert_tail(Node **head, Node *new_node) { if (*head == NULL) { /* 如果链表为空,则新节点就是头结点 */ *head = new_node; (*head)->prev = *head; (*head)->next = *head; } else { /* 找到链表尾部节点,将新节点插入其后面 */ Node *tail = (*head)->prev; new_node->prev = tail; new_node->next = *head; tail->next = new_node; (*head)->prev = new_node; } } /* 将节点插入链表头部 */ void insert_head(Node **head, Node *new_node) { if (*head == NULL) { /* 如果链表为空,则新节点就是头结点 */ *head = new_node; (*head)->prev = *head; (*head)->next = *head; } else { /* 将新节点插入头结点之前 */ Node *old_head = *head; new_node->prev = old_head->prev; new_node->next = old_head; old_head->prev->next = new_node; old_head->prev = new_node; *head = new_node; } } /* 删除指定节点 */ void delete_node(Node **head, Node *node) { if (*head == NULL || node == NULL) { /* 链表为空或指定节点为空,直接返回 */ return; } if (*head == node) { /* 如果要删除的是头结点,则将新的头结点指向下一个节点 */ *head = node->next; } node->prev->next = node->next; node->next->prev = node->prev; free(node); } /* 打印链表元素 */ void print_list(Node *head) { if (head == NULL) { printf("List is empty!\n"); return; } printf("List: "); Node *p = head; do { printf("%d ", p->data); p = p->next; } while (p != head); printf("\n"); } /* 主函数 */ int main() { Node *head; init_list(&head); /* 创建新节点并插入链表尾部 */ Node *node1 = create_node(1); insert_tail(&head, node1); print_list(head); /* 创建新节点并插入链表头部 */ Node *node2 = create_node(2); insert_head(&head, node2); print_list(head); /* 创建新节点并插入链表头部 */ Node *node3 = create_node(3); insert_head(&head, node3); print_list(head); /* 删除节点2 */ delete_node(&head, node2); print_list(head); /* 删除节点1 */ delete_node(&head, node1); print_list(head); /* 删除节点3 */ delete_node(&head, node3); print_list(head); return 0; } ``` 该程序定义了一个节点结构体,包括数据、前驱节点和后继节点三个成员。然后定义了几个链表操作函数,包括初始化链表、创建新节点、插入节点到链表尾部、插入节点到链表头部、删除指定节点和打印链表元素。主函数中通过这些操作函数构建一个双向循环链表,并进行了一些操作,最终输出链表的元素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JDSZGLLL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值