数据结构——使用C语言 线性表之循环双向单链表实现

循环双向单链表基本操作有

/*初始化单链表*/
void ListInitinate(DLNode** head);


/*插入数据元素*/
int ListInsert(DLNode* head, int i, DataType x);
//在带头结点的双向循环链表head的第i个结点前插入一个存放数据x的结点
//插入成功返回1,否则返回0


/*删除数据元素*/
int ListDelete(DLNode* head, int i, DataType* x);
//删除在带头结点的双向循环链表head的第i个结点,被删除的结点数据元素域由x带回
//删除成功返回1,否则返回0


/*求当前链表长度*/
int ListLength(DLNode* head);

/*取数据元素*/
int ListGet(DLNode* head, int i, DataType* x);
//取头结点为head的双向循环链表的第i个结点,将取出结点有x带回
//取出成返回1,否则返回0


/*撤销循环单链表*/
void ListDestroy(DLNode** head);

双向链表与单向链表不同的是双向链表每个结点都有有前驱和后继指针域,连接的删除的时候要考虑将每个节点的前驱和后继指针域都考虑到

1.定义数据元素

typedef int DataType;
typedef struct Node
{
	DataType data;
	struct Node* next;
	struct Node* prior;
}DLNode;

2.初始化链表

/*初始化单链表*/
void ListInitinate(DLNode** head)
{
	*head = (DLNode*)malloc(sizeof(DLNode));
	(*head)->prior = *head;//构成前驱指针循环链表
	(*head)->next = *head;//构成后继指针循环链表
}

3.插入数据元素

/*插入数据元素*/
//在带头结点的双向循环链表head的第i个结点前插入一个存放数据x的结点
//插入成功返回1,否则返回0
int ListInsert(DLNode* head, int i, DataType x)
{
	DLNode* p,*s;
	int j;
	p = head->next;
	j = 0;
	while (p != head && j < i)
	{
		p = p->next;
		j++;
	}
	if (j != i)
	{
		printf("插入位置出错");
		return 0;
	}
	s = (DLNode*)malloc(sizeof(DLNode));//生成新结点
	s->data = x;//新节点的数据域值
	
	/*将s结点插入到p(i)结点之前*/
	s->prior = p->prior;  //将s的前驱连接到p结点的前一个
	p->prior->next = s;   //将p结点的前一个节点的next域赋值为s
	s->next = p;          //将s的的next域赋值为p
	p->prior = s;         //将p的前驱结点赋值为s
	return 1;
}

4.求当前链表长度

/*求当前链表长度*/
int ListLength(DLNode* head)
{
	int size = 0;
	DLNode* p;
	p = head;
	while (p->next != head)
	{
		p = p->next;
		size++;
	}
	return size;
}

5.删除数据元素

/*删除数据元素*/
//删除在带头结点的双向循环链表head的第i个结点,被删除的结点数据元素域由x带回
//删除成功返回1,否则返回0
int ListDelete(DLNode* head, int i, DataType* x)
{
	DLNode* p;
	int j;
	p = head->next;
	j = 0;
	while (p->next != head && j < i)
	{
		p = p->next;
		j++;
	}
	if (j != i)
	{
		printf("删除位置出错");
		return 0;
	}
	*x = p->data;                 //将要删除的元素由x带回
	p->prior->next = p->next;     //将p的前一个节点的next域赋值为p的后一个结点
	p->next->prior = p->prior;    //将p的后一个结点的前驱赋值为p的前一个节点
	return 1;
}

6.取数据元素

/*取数据元素*/
//取头结点为head的双向循环链表的第i个结点,将取出结点有x带回
//取出成返回1,否则返回0
int ListGet(DLNode* head, int i, DataType* x)
{
	DLNode* p;
	p = head;
	int j = -1;
	while (p->next != head&&j<i)
	{
		p = p->next;
		j++;
	}
	if (j != i)
	{
		printf("取元素错误");
		return 0;
	}
	*x = p->data;
	return 1;
}

7.撤销循环单链表

/*撤销循环单链表*/
void ListDestroy(DLNode** head)
{
	DLNode* p, * q;
	int i, n = ListLength(*head);
	p = *head;
	for(i=0;i<=n;i++)
	{
		q = p;
		p = p->next;
		free(q);
	}
	*head = NULL;
}

例题:

建立数值分别为 1,2,3,„,10 的单链表,然后删除数值 4, 最后输出该单链表。使用循环单链表

#include<stdio.h>
#include"dlist.h"  //包含循环单链表的头文件
int main()
{
	DLNode* head;
	int i, x;
	ListInitinate(&head);
	for (i = 0; i < 10; i++)
	{
		ListInsert(head, i, i + 1);
	}
	printf("删除前:  ");
	for (i = 0; i < ListLength(head); i++)
	{
		ListGet(head, i, &x);
		printf("%d  ", x);
	}
	ListDelete(head, 3, &x);
	printf("\n");
	printf("删除后:  ");
	for (i = 0; i < ListLength(head); i++)
	{
		ListGet(head, i, &x);
		printf("%d  ", x);
	}
}

程序结果运行如下

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值