单循环链表实际上只是在单链表的基础上,多加了个尾指针的概念,将尾结点的指针指向头结点,构成一个单循环,难度并不难。许多功能跟单循环都是一样的,不解释,上代码。
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
int Sdata; //链表数据数量
#define LEN sizeof(struct listdata)
typedef struct listdata
{
int data;
struct listdata *next;
}node;
node* Ilist() /* 初始化链表 */
{
node *head; //头指针
node *temp,*tail; //中间指针,尾指针
int data;
head = NULL;
printf("请输入数据,输入0为结束\n");
while(1)
{
scanf("%d",&data);
fflush(stdin);
if(data == 0)
{
printf("退出初始化···\n");
goto end;
}
if(head == NULL)
{
head = (node*)malloc(LEN);
if(!head)
{
printf("内存分配失败,退出程序···\n");
exit(0);
}
head->data = data;
head->next = head;
Sdata++;
}
else
{
for(temp = head;temp->next != head;temp = temp->next)
{
;
}
tail = (node*)malloc(LEN);
if(!tail)
{
printf("内存分配失败,退出程序···\n");
exit(0);
}
tail->data = data;
temp->next = tail;
tail->next = head;
Sdata++;
}
}
end:return head;
}
void Plist(node *L) /*打印链表*/
{
int i = 0;
node *P;
if(L == NULL)
{
printf("此链表为空!\n");
return;
}
for(P = L;i != Sdata;i++)
{
printf("\t%d",P->data);
P = P->next;
}
}
node* Nlist(node *L)
{
int data,x,i;
node *P1,*P2;
LOOP:printf("请输入想要插入的数据、位置:");
scanf("%d %d",&data,&x);
if(x < 0 || x-1 > Sdata)
{
printf("插入的位置有误!\n");
goto LOOP;
}
if(L == NULL) //空链表,直接插入
{
printf("空链表,直接插入\n");
P1 = (node*)malloc(LEN);
if(!P1)
{
printf("内存分配失败,退出程序···\n");
exit(0);
}
P1->data = data;
P1->next = L;
L = P1;
Sdata++;
goto END;
}
if(x == 1) //插入位置为第一时
{
P1 = (node*)malloc(LEN);
if(!P1)
{
printf("内存分配失败,退出程序···\n");
exit(0);
}
P1->data = data;
for(P2 = L;P2->next != L;P2 = P2->next) //P2此时为尾指针
{
;
}
P1->next = L;
P2->next = P1;
L = P1;
Sdata++;
}
else
{
P1 = L;
for(i = 1;i < (x-1);i++)//P1指向即将插入的前一个位置
{
P1 = P1->next;
}
P2 = (node*)malloc(LEN);
if(!P2)
{
printf("内存分配失败\n");
exit(0);
}
P2->data = data;
P2->next = P1->next;
P1->next = P2;
Sdata++;
}
END:return L;
}
node* Dlist(node* L) /*删除结点*/
{
node *P1,*P2;
int x;
int i;
LOOP:printf("请输入删除结点的位置:");
scanf("%d",&x);
if(L == NULL)
{
printf("空链表,无法进行此操作\n");
return L;
}
if(x < 0 || x > Sdata)
{
printf("删除结点的位置有误!\n");
goto LOOP;
}
P1 = P2 = L;
if(Sdata == 1)
{
free(L);
L = NULL;
Sdata--;
}
else if(x == 1)
{
for(;P2->next != L;P2 = P2->next)
{
;
}
L = L->next;
P2->next = L;
free(P1);
Sdata--;
}
else
{
for(i = 1;i < (x-1);i++)
{
P1 = P1->next;
}
P2 = P1->next;
P1->next = P2->next;
free(P2);
Sdata--;
}
return L;
}
void main()
{
node *L;
int x;
Sdata = 0; //链表数据记录
system("color 0A");
printf("/************************/\n");
printf(" 数据结构: 单循环链表 \n");
printf(" 编写者: H \n");
printf(" 欢饮交流: 云客联盟 \n");
printf("/************************/\n");
printf("功能选择: \n");
printf("\t0:退出\n \t1:初始化链表\n \t2.打印链表\n \t3.插入结点\n \t4.查看结点数\n \t5.删除结点\n");
printf("\t6:关于程序\n");
while(1)
{
printf("\n请输入功能:");
scanf("%d",&x);
fflush(stdin);
if(x == 0)
{
printf("\n让编程改变世界!\n");
printf("退出程序···\n");
exit(0);
}
switch(x)
{
case 1:L = Ilist();
break;
case 2:Plist(L);
break;
case 3:L = Nlist(L);
break;
case 4:printf("此时单循环链表的结点数为:%d",Sdata);
break;
case 5:L = Dlist(L);
break;
case 6:printf("\t单循环链表本质其实只是在单链表上加了尾指针这个概念,\n");
printf("\t将尾结点的指针指向头,构成一个单循环,程序难度: *** \n");
printf("\t本程序为防止恶意输入多写了许多检查,另外多了个全局 \n");
printf("\t变量,用于存储链表结点数,有一定的作用. \n");
break;
default:printf("sorry,没有这个选项!\n");
}
}
}