【数据结构】【循环单链表】

2.循环单链表

2.1循环单链表的创建
//定义一个单链表
typedef struct LNode
{
	int data;
	struct LNode* next;
}CLNode, * CircleLinkList;
2.2循环单链表的初始化
//初始化循环单链表
void InitCircleLinkList(CircleLinkList* L)
{
	*L = (CircleLinkList)malloc(sizeof(CLNode));//为头结点分配空间
	if (*L == NULL)
	{
		printf("开辟内存空间失败,初始化头结点失败\n");
		return -1;
	}
	(*L)->next =*L;
	printf("循环单链表初始化成功....\n");
}
2.3打印循环循环单链表
//打印循环单链表
void PrintCircleList(CircleLinkList* L)
{
	CLNode* head = *L;
	//判空操作
	CircleEmpty(L);
	while (head->next != *L) {    // 遍历链表          
		head = head->next;  // 还未到达表尾则进行结点读取后移
		printf("%d ", head->data);
	}
	printf("\n");
}
2.4头插法建立循环单链表
2.4.1原理图

在这里插入图片描述

2.4.2代码
//头插法建立循环单链表
int HeadInsertCircleList(CircleLinkList* L, int n)
{
	CLNode* head = *L;//头指针
	CLNode* pnew = NULL;//新的结点
	for (int i = 1; i <= n; i++)
	{
		pnew = (CircleLinkList)malloc(sizeof(CLNode));//申请空间
		if (pnew == NULL)
		{
			printf("error");
			return -1;
		}
		int num = 0;
		printf("请输入插入的第%d个元素:",i);
		scanf("%d", &num);
		pnew->data = num;
		pnew->next = head->next;
		head->next = pnew;
	}
	return 0;
}
2.4.3测试代码
int main()
{
	CircleLinkList* h = NULL;
	InitCircleLinkList(&h);
	//头插法建立循环单链表
	int n = 5;//头插,尾插结点数
	//头插法建立循环单链表
	HeadInsertCircleList(&h, n);
	return 0;
}
2.4.4运行结果

在这里插入图片描述

2.5头删
2.5.1原理图

在这里插入图片描述

2.5.2代码
//头删
int DelHeadCircleList(CircleLinkList* L,int *e)
{
	//判断是否为空表
	if (CircleListLength(L)==0)
	{
		return -1;
	}
	CLNode* head = *L;
	CLNode* p = head->next;//被删除节点
	head->next = p->next;
	*e = p->data;
	free(p);
	return 0;
}
2.5.3测试代码
int main()
{
	CircleLinkList* h = NULL;
	InitCircleLinkList(&h);
	int n = 5;//头插节点数
	//头插法建立循环单链表
	HeadInsertCircleList(&h, n);
	printf("头删之前\n");
	PrintCircleList(&h);
	int e = 0;
	DelHeadCircleList(&h,&e);
	printf("删除的元素为:%d\n", e);
	PrintCircleList(&h);
	return 0;
}
2.5.4运行结果

先头插了5个元素后进行一次头删

在这里插入图片描述

2.6尾插
2.6.1原理图

在这里插入图片描述

2.6.2代码
//尾插法建立循环单链表
int TailInsertCircleList(CircleLinkList* L,int n)
{
	CLNode* rear = *L;//尾指针
	CLNode* pnew = NULL;//新的结点
	for (int i = 1; i <= n; i++)
	{
		pnew = (CircleLinkList)malloc(sizeof(CLNode));//申请空间
		if (pnew == NULL)
		{
			printf("error");
			return -1;
		}
		int num = 0;
		printf("请输入插入的第%d个元素:", i);
		scanf("%d", &num);
		pnew->data = num;
		rear->next = pnew;
		pnew->next = *L;//将头结点与新的结点相连
		rear = pnew;//尾指针移动
	}
	return 0;
}
2.6.3测试代码
int main()
{
	CircleLinkList* h = NULL;
	InitCircleLinkList(&h);
	int n = 5;//尾插节点数
	//尾插法建立循环单链表
	TailInsertCircleList(&h, n);
	PrintCircleList(&h);
	return 0;
}
2.6.4运行结果

在这里插入图片描述

2.7尾删
2.7.1原理图

在这里插入图片描述

2.7.2代码
//尾删
int DelTailCircleList(CircleLinkList* L, int* e)
{
	//判断是否为空表
	if (CircleEmpty(L) == 0)
	{
		return -1;
	}
	//找到最后一个结点
	CLNode* rear = *L;//尾指针
	CLNode* pre = NULL;//被删除结点的前一个结点
	//找到尾节点
	while (rear->next != *L)
	{
		pre = rear;
		rear = rear->next;
		
	}
	pre->next = rear->next;
	*e = rear->data;
	free(rear);
	return 0;
}
2.7.3测试代码
int main()
{
	CircleLinkList* h = NULL;
	InitCircleLinkList(&h);
	int n = 5;//尾插结点数
	//尾插法建立循环单链表
	TailInsertCircleList(&h, n);
	printf("尾删之前\n");
	PrintCircleList(&h);
	int e = 0;
	DelTailCircleList(&h, &e);
	printf("删除的元素为:%d\n", e);
	PrintCircleList(&h);
	return 0;
}
2.7.4运行结果

尾插5个元素后,进行一次尾删

在这里插入图片描述

2.8求表长
2.8.1代码
//求表长
int CircleListLength(CircleLinkList* h)
{
	CLNode* p = NULL;
	p = *h;
	int len = 0;
	/*if (p->next == p)
	{
		printf("空表...\n");
		return 0;
	}*/
	if (CircleEmpty(h)==0)
	{
		return 0;
	}
	while (p->next != *h)
	{
		p = p->next;
		len = len + 1;
	}
	return len;

}
2.8.2测试代码
int main()
{
	CircleLinkList* h = NULL;
	InitCircleLinkList(&h);
	int n = 5;
	//尾插法建立循环单链表
	TailInsertCircleList(&h, n);
	PrintCircleList(&h);
	int len = CircleListLength(&h);
	printf("表的长度为%d", len);
	return 0;
}
2.8.3运行结果

在这里插入图片描述

2.9判空操作
2.9.1循环单链表空表

在这里插入图片描述

2.9.2代码
//判空
int CircleEmpty(CircleLinkList* h)
{
	CLNode* head = *h;
	if (head->next == head)
	{
		printf("空表...\n");
		return 0;
	}
	return 1;
}
2.9.3测试代码

这里我们并没有插入任何节点,只是进行了初始化循环单链表操作

int main()
{
	CircleLinkList* h = NULL;
	InitCircleLinkList(&h);
	CircleEmpty(&h);
	return 0;
}
2.9.4运行结果

在这里插入图片描述

3.0按照位置查找元素
3.0.1代码
//按照位置查找(按照位置查找)
int GetElem(CircleLinkList* L,int i,int* e)
{
	CLNode* p = *L;//定义指向i-1个结点的指针变量,起始地址为首元节点
	int j = 0;
	if (i<1 || i > CircleListLength(L))
	{
		printf("查询位置不合法\n");
		return -1;
	}
	//查询i-1个位置
	while (p != NULL && j < i) {
        p = p->next;
        j++;
    }
	*e = p->data;
	printf("查找的元素的下标为%d,元素为%d\n", i-=1, *e);
	return 0;
}
3.0.2测试代码
int main()
{
	CircleLinkList* h = NULL;
	InitCircleLinkList(&h);
	int n = 5;
	//尾插法建立循环单链表
	TailInsertCircleList(&h, n);
	int e = 0;//找到该元素后赋值给e
	int index = 5;//查找元素的位置
	printf("循环单链表中的元素为:\n");
	PrintCircleList(&h);
	GetElem(&h,index,&e);
	return 0;
}
3.0.3运行结果

在这里插入图片描述

3.1查询指定元素(按照值查找)
3.1.1代码
//查询指定元素(按值查找)
int LocateElem(CircleLinkList* L,int e)
{
	CLNode* p = *L;//头指针
	int i = 0;
	int temp = 0;
	while (p!=NULL)
	{
		p = p->next;
		if (p->data==e)
		{			
			temp = e;
			printf("查找的元素为:%d,在链表的下标为:%d\n", temp,i);
			return -1;
		}
		i++;
		if (p == *L)
		{
			printf("未找到%d\n",e);
			return -1;
		}
	}
	return 0;
}
3.1.2测试代码
int main()
{
	CircleLinkList* h = NULL;
	InitCircleLinkList(&h);
	//头插法建立循环单链表
	int n = 5;//头插,尾插结点数
	//尾插法建立循环单链表
	TailInsertCircleList(&h, n);
	LocateElem(&h,6);
	return 0;
}
3.1.3运行结果

在这里插入图片描述

3.2删除指定结点
3.2.1原理图

在这里插入图片描述

3.2.2代码
//删除指定结点
int DelCircleList(CircleLinkList* L,int i,int *e)
{
	CLNode* pre, * p; //pre指向被删除结点的前一个结点,p指向被删除节点
	pre = *L;
	int j = 0;
	//判断删除位置是否合法
	if (i<1 || i>CircleListLength(L))
	{
		printf("删除位置不合法....");
		return -1;
	}
    //查找第i-1个节点
    while (pre != NULL && j < i-1) {
        pre = pre->next;
        j++;
    }
	p = pre->next;//要删除的结点
	pre->next = p->next;
	*e = p->data;
	free(p);
	return 0;
}
3.2.3测试代码
int main()
{
	CircleLinkList* h = NULL;
	InitCircleLinkList(&h);
	int n = 5;
	//尾插法建立循环单链表
	TailInsertCircleList(&h, n);
	//CircleEmpty(&h);
	printf("删除之前\n");
	PrintCircleList(&h);
	int e = 0;//存储所删除元素
	DelCircleList(&h,3,&e);
	printf("删除的元素为:%d\n", e);
	PrintCircleList(&h);
	return 0;
}
3.2.4运行结果

在这里插入图片描述

3.3指定位置插入结点
3.3.1原理图

在这里插入图片描述

3.3.2代码
//按照位置插入结点
int InsertList(CircleLinkList* L, int i, int e)
{
	CLNode* pre = *L;
	CLNode* pnew = NULL;//新的结点
	int j = 0;
	//判断插入位置是否合法
	if (i<1 || i > CircleListLength(L))
	{
		printf("插入位置不合法\n");
		return -1;
	}
	//查找第i-1个节点
	while (pre != NULL && j < i - 1) {
		pre = pre->next;
		j++;
	}
	pnew = (CircleLinkList)malloc(sizeof(CLNode));//申请空间
	if (pnew == NULL)
	{
		printf("error");
		return -1;
	}
	pnew->data = e;
	pnew->next = pre->next;
	pre->next = pnew;
	return 0;
}
3.3.3测试代码
int main()
{
	CircleLinkList* h = NULL;
	InitCircleLinkList(&h);
	int n = 5;
	//尾插法建立循环单链表
	TailInsertCircleList(&h, n);
	int index = 5;//插入元素的位置
	InsertList(&h, index, 66);
	printf("插入后循环单链表中的元素为:\n");
	PrintCircleList(&h);
	return 0;
}
3.3.4运行结果

在这里插入图片描述

3.4清空循环单链表
3.4.1代码
//清空循环单链表
int ClearCircleList(CircleLinkList* L)
{
	CLNode* p = *L;
    CLNode* q = NULL;
    while (p->next != *L)
    {
        q = p->next;
        p->next = q->next;
        free(q);
    }
	return 0;
}
3.4.2测试代码
int main()
{
	CircleLinkList* h = NULL;
	InitCircleLinkList(&h);
	int n = 5;
	//尾插法建立循环单链表
	TailInsertCircleList(&h, n);
	printf("清空前:\n");
	PrintCircleList(&h);
	ClearCircleList(&h);
	printf("清空后:\n");
	PrintCircleList(&h);
	return 0;
}
3.4.3运行结果

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值