链式存储结构-单向循环链表的初始化、头插、尾插、合并,打印(C语言)


单向循环链表概念

简单来说,单向循环链表就是在单链表的基础上,将最后一个结点的next指针域指向头指针。

单链表的许多操作与单链表相同或相似,接下来,我将举几个有代表性的操作。

单向循环链表定义

#include<stdio.h>
#include<stdlib.h>
#define OK 1;
#define ERROR 0;

typedef int ElemType;
typedef struct Lnode {
	ElemType data;
	struct Lnode* next;
}Lnode;
typedef struct Lnode* Clist;

初始化

/* 初始化单向循环链表 */
int InitClist(Clist* L)
{
	(*L) = (Clist)malloc(sizeof(Lnode));
	(*L)->next = (*L);
	return OK;
}

头插法

初始化后,适用于第一次插入及其他情况

/* 单向循环链表头插法 */
int Inserthead(Clist* L, ElemType i)
{
	int j,data;
	for (j = 0; j < i; j++)
	{
		Clist p = (Clist)malloc(sizeof(Lnode));
		scanf("%d", &data);
		p->data = data;

		p->next = (*L)->next;
		(*L)->next = p;
	}
	return OK;
}

尾插法

初始化后,适用于第一次插入及其他情况

/* 单向循环链表尾插法 */
int Inserttail(Clist* L, ElemType i)
{
	int j,data;
	Clist p = (Clist)malloc(sizeof(Lnode));
	Clist tailplace ;   //用于定位尾位置
	for (j = 0; j < i; j++)
	{
		Clist p = (Clist)malloc(sizeof(Lnode));
		scanf("%d", &data);
		p->data = data;

		//定位尾结点
		for (tailplace = *L; tailplace->next != *L; tailplace = tailplace->next);
			
		p->next = tailplace->next;
		tailplace->next = p;
	}
	return OK;
}

合并两个单向链表

/* 两个单向循环链表的和并 */
int connect(Clist* L1, Clist* L2)
{
	Clist p;

	Clist rear1;   //用于指向L1的尾结点
	Clist rear2;   //用于指向L2的尾结点

	//定位尾结点
	for (rear1 = *L1; rear1->next != *L1; rear1 = rear1->next);
	for (rear2 = *L2; rear2->next != *L2; rear2 = rear2->next);

	p = rear1->next;    //p存表头结点
	rear1->next = rear2->next->next;   //L2表头连接到L1表尾
	free(rear2->next);      //释放L2表头结点
	rear2->next = p;       //将L2尾结点连接到L1
	return OK;
}

打印

/* 打印链表 */
void prinfClist(Clist L)
{
	Clist p = (Clist)malloc(sizeof(Lnode));
	p = L->next;
	while (p->next != L->next)
	{
		printf("* %d\n", p->data);
		p = p->next;
	}
}

全部代码

#define _CRT_SECURE_NO_WARNINGS 1 //VS不支持scanf(),需加上这一行
#include<stdio.h>
#include<stdlib.h>
#define OK 1;
#define ERROR 0;

typedef int ElemType;
typedef struct Lnode {
	ElemType data;
	struct Lnode* next;
}Lnode;
typedef struct Lnode* Clist;




int InitClist(Clist *L);   //初始化单向循环链表
int Inserthead(Clist* L, ElemType i);  //单向循环链表头插法
int Inserttail(Clist* L, ElemType i);  //单向循环链表尾插法
int connect(Clist* L1, Clist* L2);     //两个单向循环链表的和并
void prinfClist(Clist L);   //打印链表

int main(void)
{
	Clist Ta, Tb;
	printf("InitClist Ta %d\n",InitClist(&Ta));
	printf("InitClist Tb %d\n", InitClist(&Tb));
		
	printf("Inserthead Ta %d\n",Inserthead(&Ta, 5));
	printf("Inserttail Tb %d\n", Inserttail(&Tb, 5));
	printf("connect %d\n", connect(&Ta, &Tb));
	prinfClist(Ta);

	return 0;
}

/* 初始化单向循环链表 */
int InitClist(Clist* L)
{
	(*L) = (Clist)malloc(sizeof(Lnode));
	(*L)->next = (*L);
	return OK;
}

/* 单向循环链表头插法 */
int Inserthead(Clist* L, ElemType i)
{
	int j,data;
	for (j = 0; j < i; j++)
	{
		Clist p = (Clist)malloc(sizeof(Lnode));
		scanf("%d", &data);
		p->data = data;

		p->next = (*L)->next;
		(*L)->next = p;
	}
	return OK;
}
/* 单向循环链表尾插法 */
int Inserttail(Clist* L, ElemType i)
{
	int j,data;
	Clist p = (Clist)malloc(sizeof(Lnode));
	Clist tailplace ;   //用于定位尾位置
	for (j = 0; j < i; j++)
	{
		Clist p = (Clist)malloc(sizeof(Lnode));
		scanf("%d", &data);
		p->data = data;

		//定位尾结点
		for (tailplace = *L; tailplace->next != *L; tailplace = tailplace->next);
			
		p->next = tailplace->next;
		tailplace->next = p;
	}
	return OK;
}
/* 两个单向循环链表的和并 */
int connect(Clist* L1, Clist* L2)
{
	Clist p;

	Clist rear1;   //用于指向L1的尾结点
	Clist rear2;   //用于指向L2的尾结点

	//定位尾结点
	for (rear1 = *L1; rear1->next != *L1; rear1 = rear1->next);
	for (rear2 = *L2; rear2->next != *L2; rear2 = rear2->next);

	p = rear1->next;    //p存表头结点
	rear1->next = rear2->next->next;   //L2表头连接到L1表尾
	free(rear2->next);      //释放L2表头结点
	rear2->next = p;       //将L2尾结点连接到L1
	return OK;
}
/* 打印链表 */
void prinfClist(Clist L)
{
	Clist p = (Clist)malloc(sizeof(Lnode));
	p = L->next;
	while (p->next != L->next)
	{
		printf("* %d\n", p->data);
		p = p->next;
	}
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Mirror_zz

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

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

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

打赏作者

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

抵扣说明:

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

余额充值