带头结点的单向循环链表的定义,初始化,加工(插入,删除,修改),遍历,实例

带头节点的单向循环链表

头指针指向第一个结点的地址,当头指针为空时,链表为空。

建立
typedef struct
{
	char name[20];
	float score;
} STD;
typedef STD ElemType;
typedef struct Londe
{
	ElemType data;    //data是一个STD类型的变量
	struct Lnode *next;
}LNode,*LinkList;    //LNode是结点数据类型,LinkList为指向节点的指针类型

初始化

带头结点的链表更加常用

int initList(LinkList *L)
{
	*L = (LinkList)malloc(sizeof(Lnode));    //L是指向头指针的指针变量,(*L)是头指针,头指针指向头结点位置 
	if(*L == NULL)
	return 0;
	(*L)->next = NULL;    //头结点为空 
    return 1;
}

调用:

int main()
{
	LinkList L;
	if(LinkList(&L))
	printf("初始化成功!\n");
	else
	printf("初始化失败!\n");
}

插入

主要变化就是原本的判断是否为空变成了判断是否为头结点

  • 任意位置插入
int insertList(LinkList L, int i, ElemType e)
{
	LinkList p = L, s;    //p指向头结点 
	int pos = 0;    //记住p
	while (p->next != L && pos < i - 1)
	{
		p = p->next;
		pos++;
	}
	if (p->next == L && pos<i-1|| pos > i - 1)
		return 0;
	s = (LinkList)malloc(sizeof(Lnode));
	s->data = e;
	s->next = p->next;
	p->next = s;
	return 1;
}

调用:

			ElemType e;
			printf("请输入需要插入的数据\n:");
			scanf("%s%f", &e.name, &e.score);
			int pos;
			printf("请输入需要插入的位置:\n");
			scanf("%d", &pos);
			if (insertList(&L, pos, e) != 0)
				printf("插入成功!\n");
			else
				printf("插入位置不合理,失败!\n");
  • 头插

头指针指向新节点,新节点下一个为原来的头结点,没有遍历

int frontinsertList(LinkList L,ElemType e)
{
	LinkList p;
	p = (LinkList)malloc(sizeof(Lnode));
	p->data = e;
	p->next = L->next;
	L->next = p;
	return 1;
}
  • 尾插
int rearinsertList(LinkList L, ElemType e)
{
	LinkList p,q = L;
	p = (LinkList)malloc(sizeof(Lnode));
	p->data = e;
	while (q->next != L)
		q = q->next;
	q->next = p;
	p->next = L;
	return 1;
}
删除

删除指定位置:

int deleteList(LinkList L, int i)
{
	LinkList q,p = L;
	int pos = 0;
	if (p->next == L)
		return 0;
	while (p->next != L && pos<i-1)
	{
		p = p->next;
		pos++;
	}
	q = p->next;
	p->next = q->next;
	free(q);
	return 1;
}

调用:

				ElemType e;
				int pos;
				printf("请输入需要删除的数据的位置:\n");
				scanf("%d", &pos);
				if (deleteList(L, pos))
					printf("删除成功!\n");
				else
					printf("删除失败!\n");
				printf("最新的数据表为:\n");
修改
int reviseList(LinkList L, int i, ElemType e)
{
	LinkList p = L->next;
	int n = 1;
	while (p != L && n < i)
	{
		p = p->next;
		n++;
	}
	if (p == L || n > i)
		return 0;
	p->data = e;
	return i;
}

调用:

        	ElemType e;
			printf("请输入需要修改的数据的位置:");
			int pos;
			scanf("%d", &pos);
			printf("请输入需要修改的数据:");
			scanf("%s%d"& e.name, &e.time);
			if (reviseList(L, pos, e))
				printf("修改成功!");
			else
				printf("修改失败!");
		
遍历(打印)
int printList(LinkList L)
{
	LinkList p = L->next;
	if (p == L)
		return 0;
	while (p!=L)
	{
		printf("%s%d\n", p->data.name, p->data.time);
		p = p->next;
	}
	return 1;
}

调用:

printList(L);

其余操作也同理,只是把判断条件换成了p != L

实例

采用循环单单链表保存图书信息(书名,书号),完成以下功能:1)初始化创建包含3个数据元素的表(按书号升序排列);2)按书号有序插入数据元素;3)按书号删除数据元素;4)输出。

#include<string.h>
#include<stdio.h>
#include<stdlib.h>
typedef struct
{
	char name[20];
	int no;
} BOOK;
typedef BOOK ElemType;
typedef struct Lnode
{
	ElemType data;
	struct Lnode* next;
}Lnode, * LinkList;
int initList(LinkList* L)
{
	*L = (LinkList)malloc(sizeof(Lnode));    //L是指向头指针的指针变量,(*L)是头指针,头指针指向头结点位置 
	if (*L == NULL)
		return 0;
	(*L)->next = *L;    //头结点是头指针 
	return 1;
}
int ListLength(LinkList L)
{
	LinkList p = L->next;
	int n = 0;
	if (p == L)
		return 0;
	while (p != L)
	{
		p = p->next;
		n++;
	}
	return n;
}
int sortinsertList(LinkList *L, ElemType e)
{
	LinkList p = *L, s;    //p指向头结点 
	int pos = 0;    //记住p
	while (p->next != *L && pos < ListLength(*L) - 1 && e.no > p->next->data.no)
	{
		p = p->next;
		pos++;
	}
	if (p->next == *L || pos > ListLength(*L) - 1)
		return 0;
	s = (LinkList)malloc(sizeof(Lnode));
	s->data = e;
	s->next = p->next;
	p->next = s;
	return 1;
}
int deleteList(LinkList L, int i)
{
	LinkList q,p = L;
	int pos = 0;
	if (p->next == L)
		return 0;
	while (p->next != L && pos<i-1)
	{
		p = p->next;
		pos++;
	}
	q = p->next;
	p->next = q->next;
	free(q);
	return 1;
}
int creatList(LinkList *L)
{
	initList(L);
	LinkList p,q = *L;
	ElemType e[3];
	e[0] = { "第一本书",3 };
	e[1] = { "第二本书",6 };
	e[2] = { "第三本书",9 };

	int n = 0;
	do
	{
		p = (LinkList)malloc(sizeof(Lnode));
		p->data = e[n];
		p->next = (*L);
		q->next = p;
		q = p;
		n++;
	} while (n < 3);
	return 1;
}
int printList(LinkList  L)
{
	LinkList p = L->next;
	if (p ==  L)
		return 0;
	while (p!= L)
	{
		printf("%s的编号为:%d\n", p->data.name, p->data.no);
		p = p->next;
	}
	return 1;
}
int main()
	{
		LinkList L;
		creatList(&L);
		printf("创建成功!\n最新的数据表为:\n");
		printList( L);
		printf("\n请选择你要执行的操作\n");
		printf("1 : 插入新数据\n");
		printf("2 : 删除数据\n");
		printf("3 : 根据事件修改\n");
		printf("4 : 根据事件查询\n");

		int op;
		while (scanf("%d", &op) && op) {
			if (op == 1) {
				ElemType e;
				printf("请输入需要插入的数据:\n");
				scanf("%s%d", &e.name, &e.no);
				if (sortinsertList(&L, e) != 0)
					printf("插入成功!\n");
				else
					printf("插入位置不合理,失败!\n");
				printf("最新的数据表为:\n");
				printList( L);
			}
		    else if (op == 2) {
				ElemType e;
				int pos;
				printf("请输入需要删除的数据的位置:\n");
				scanf("%d", &pos);
				if (deleteList(L, pos))
					printf("删除成功!\n");
				else
					printf("删除失败!\n");
				printf("最新的数据表为:\n");
				printList(L);
			}
      }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值