引言
学完循环单链表不知道干什么?这篇文章带你熟练掌握单链表。实现了循环单链表的增、删、改、查,请宝子们仔细观看。正在火速更新中~~
学习目的
- 掌握单循环链表的存储结构
- 掌握单循环链表的基本操作
- 掌握单循环链表的基本特性
环境与设备
操作系统:Windows 10
编译器:DevC++
算法描述
- 尾插法输入n个元素算法描述:
- 获取第i个数据元素算法描述:
- 获取值为x的数据元素的位序号算法描述:
- 在x值的后面插入一个值y算法描述:
- 删除值为x的数据元素算法描述:
这些下去自己学习了,下面,直接上干货~~
存储结构
typedef int DataType;
typedef struct node //结点类型定义
{
DataType data; //结点的数据域
struct node *next; //结点的指针域
}ListNode,*LinkList;
函数原型
1. void InitList(LinkList head)//初始化
2. int Length(LinkList head)//求长度
3. void CreateList(LinkList head)//尾插法输入n个元素
4. void DispList(LinkList head)//显示数据元素
5. void CreateList2(LinkList head)//头插法输入n个元素
6. DataType Get(LinkList head,int i)//获取第i个数据元素
7. int Locate(LinkList head,DataType x)//获取值为x的数据元素的位序号
8. void insert_before(LinkList head,DataType x))//在x值的前面插入一个值y
9. void insert_after(LinkList head,DataType x)//在x值的后面插入一个值y
10. int Delete(LinkList head,DataType x)//删除值为x的数据元素
核心代码
#include<stdio.h>
#include<stdlib.h>
typedef int DataType;
typedef struct node //结点类型定义
{
DataType data; //结点的数据域
struct node *next; //结点的指针域
}ListNode,*LinkList;
LinkList head;
void InitList(LinkList head);//初始化
int Length(LinkList head);//求长度
void CreateList(LinkList head);//尾插法输入n个元素
void DispList(LinkList head);//显示数据元素
void CreateList2(LinkList head);//头插法输入n个元素
void Get(LinkList head);//获取第i个数据元素
int Locate(LinkList head);//获取值为x的数据元素的位序号
void Insert_before(LinkList head);//在x值的前面插入一个值y
LinkList Find(LinkList head,int x); //查找函数
void insert_after(LinkList head);//在x值的后面插入一个值y
int Delete(LinkList head);//删除值为x的数据元素
void rank(LinkList head);//排序
void menu();
void menu1();
#主函数
int main()
{
head=(LinkList)malloc(sizeof(ListNode));
head->next=head;
Length(head);
menu();
}
void menu()
{
system("color 30");
printf("\t-------------------------------------------------------------\n");
printf("\t* 循环单链表 *\n");
printf("\t-------------------------------------------------------------\n");
printf("\t*\t\t 1.初始化 *\n");
printf("\t*\t\t 2.求长度 *\n");
printf("\t*\t\t 3.尾插法输入n个元素 *\n");
printf("\t*\t\t 4.显示数据元素 *\n");
printf("\t*\t\t 5.头插法输入n个元素 *\n");
printf("\t*\t\t 6.获取第i个数据元素 *\n");
printf("\t*\t\t 7.获取值为x的数据元素的位序号 *\n");
printf("\t*\t\t 8.在x值的前面插入一个值y *\n");
printf("\t*\t\t 9.在x值的后面插入一个值y *\n");
printf("\t*\t\t 10.删除值为x的数据元素 *\n");
printf("\t*\t\t 11.排序 *\n");
printf("\t-------------------------------------------------------------\n");
printf("\t\t请选择功能\n");
int a;
scanf("%d",&a);
while(a)
{
switch(a)
{
case 1:InitList(head);break;
case 2:printf("当前链表长度为:\t%d\n\n",Length(head));break;
case 3:CreateList(head);break;
case 4:DispList(head);break;
case 5:CreateList2(head);break;
case 6:Get(head);break;
case 7:Locate(head);break;
case 8:Insert_before(head);break;
case 9:insert_after(head);break;
case 10:Delete(head);break;
case 11:rank(head);break;
case 12:menu1();break;
default:printf("输入错误!!");
}
printf("\t\t请选择功能\n");
printf("\t\t温馨提示输入12可查看菜单\n");
scanf("%d",&a);
system("cls");
}
}
//初始化
void InitList(LinkList head)
{
head->next=head;
printf("初始化成功\n");
}
//求长度
int Length(LinkList head)
{
LinkList p=head;
int count=0;
while(p->next!=head)
{
p=p->next;
count++;
}
return count;
}
//尾插法输入n个元素
void CreateList(LinkList head)
{
LinkList p1,p2;
p1=(LinkList)malloc(sizeof(ListNode));
p2=head;
while(p2->next!=head)
{
p2=p2->next;
}
printf("请输入数据元素0结束输入\n");
scanf("%d",&p1->data);
while(p1->data!=0)
{
p2->next=p1;
p2=p1;
p1=(LinkList)malloc(sizeof(ListNode));
printf("请输入数据元素0结束输入\n");
scanf("%d",&p1->data);
}
p2->next=head;
free(p1);
}
//显示数据元素
void DispList(LinkList head)
{
LinkList p=head->next;
printf("单链表数据如下\n");
while(p!=head)
{
printf("%d\t",p->data);
p=p->next;
}
printf("\n");
}
//头插法输入n个元素
void CreateList2(LinkList head)
{
LinkList p1,p2;
p1->next=head;
p2=(LinkList)malloc(sizeof(ListNode));
while(p1->next!=head)
{
p1=p1->next;
}
printf("输入想要插入的数0结束\n");
scanf("%d",&p2->data);
while(p2->data!=0)
{
p2->next=p1;
p2=p1;
p2=(LinkList)malloc(sizeof(ListNode));
printf("输入想要插入的数0结束\n");
scanf("%d",&p2->data);
}
}
//获取第i个数据元素
void Get(LinkList head)
{
int i,sign=1;
printf("请输入需要获取数据元素的位置\n");
scanf("%d",&i);
LinkList p1;
p1=head->next;
for(int k=1;k<=Length(head);k++)
{
if(k==i)
{
printf("查找成功\n");
printf("该数据元素为:");
printf("%d\n",p1->data);
sign=0;
}
p1=p1->next;
}
if(sign) printf("查找失败\n");
}
//获取值为x的数据元素的位序号
int Locate(LinkList head)
{
int x,sign=1;
printf("请输入需要获取数据元素的值\n");
scanf("%d",&x);
LinkList p1;
p1=head->next;
for(int k=1;k<=Length(head);k++)
{
if(p1->data==x)
{
printf("该数据元素位置为:");
printf("%d\n",k);
sign=0;
}
p1=p1->next;
}
if(sign) printf("输入有误\n");
}
//查找函数
LinkList find(LinkList head,int x)
{
LinkList p1;
p1=head->next;
while(p1!=head)
{
if(p1->data==x)
{
return p1;
}
p1=p1->next;
}
return 0;
}
//在x值的前面插入一个值y
void Insert_before(LinkList head)
{
int x,y;
printf("请输入X和Y的值\n");
scanf("%d %d",&x,&y);
LinkList phead=find(head,x) ;
LinkList p1,p2;
p1=head;
p2=(LinkList )malloc(sizeof(ListNode)) ;
p2->data=y;
if(phead==NULL) printf("输入有误\n");
else
{
while(p1->next!=phead) //找到目标的前一个结点
{
p1=p1->next;
}
p2->next=p1->next;
p1->next=p2;
printf("插入成功\n");
}
}
//在x值的后面插入一个值y
void insert_after(LinkList head)
{
int x,y;
printf("请输入X和Y的值\n");
scanf("%d %d",&x,&y);
LinkList phead=find(head,x) ;
LinkList p2;
p2=(LinkList )malloc(sizeof(ListNode)) ;
p2->data=y;
if(phead==NULL) printf("输入有误\n");
else
{
p2->next=phead->next;
phead->next=p2;
printf("插入成功\n");
}
}
//删除值为x的数据元素
int Delete(LinkList head)
{
int x;
printf("请输入删除数据元素的值\n");
scanf("%d",&x);
LinkList target=find(head,x) ;
LinkList p1,p2;
p1=head;
if(target==NULL) printf("输入有误\n");
else
{
while(p1->next!=target) //找到目标的前一个结点
{
p1=p1->next;
}
p1->next=target->next;
free(target);
printf("删除成功\n");
}
}
//排序
void rank(LinkList head)
{
LinkList p1,p2,p3;
p3=(LinkList )malloc(sizeof(ListNode)) ;
p2=(LinkList )malloc(sizeof(ListNode)) ;
ListNode temp;
p1=head->next;
int max;
while(p1!=head)
{
max=p1->data;
p3=p1;
for(p2=p1
->next;p2!=head;p2=p2->next)
{
if(max>=p2->data)
{
max=p2->data;
p3=p2;
}
}
temp.data=p3->data;
p3->data=p1->data;
p1->data=temp.data;
p1=p1->next;
}
printf("排序成功\n");
}
void menu1()
{
system("color 30");
printf("\t-------------------------------------------------------------\n");
printf("\t*\t\t 1.初始化 *\n");
printf("\t*\t\t 2.求长度 *\n");
printf("\t*\t\t 3.尾插法输入n个元素 *\n");
printf("\t*\t\t 4.显示数据元素 *\n");
printf("\t*\t\t 5.头插法输入n个元素 *\n");
printf("\t*\t\t 6.获取第i个数据元素 *\n");
printf("\t*\t\t 7.获取值为x的数据元素的位序号 *\n");
printf("\t*\t\t 8.在x值的前面插入一个值y *\n");
printf("\t*\t\t 9.在x值的后面插入一个值y *\n");
printf("\t*\t\t 10.删除值为x的数据元素 *\n");
printf("\t*\t\t 11.排序 *\n");
printf("\t-------------------------------------------------------------\n");
}
调试界面
总结
通过此次实验,进一步熟悉了循环链表操作的有关知识,对书本上的知识又有了更进一步的认识。
另一方面,通过编写程序也让对C语言课程中学习到的有关知识进行了一次复习。
由于在大一时对C语言的学习并不太好,尤其对结构体指针的理解并深,所以在编写程序的初期遇到了一些困难。
为了解决问题,我又对C语言的相关章节进行了复习,在复习的过程中加深了对结构体、指针、字符数组、字符串函数、for循环、while循环、函数的理解。
谢谢宝子们的一件三连~~
谢谢大家!