/*本程序中所有涉及到位置的地方,下标皆从1开始*/
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<conio.h>
#define LIMIT 100
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -1
#define INFEASIBLE -2
typedef struct Cycle
{
int data;
struct Cycle *next;
}*CList,CLinkList;
int CList_Init(CList *head)
{
CList node,temp;
int i;
temp=*head=(CList)malloc(sizeof(CLinkList));//申请空间
if(!(*head))
exit(INFEASIBLE);
(*head)->next=(*head);
printf("请输入表长:");
scanf("%d",&(*head)->data);
if((*head)->data<0)//判断输入合法性
return ERROR;
srand(time(0));
for(i=1;i<=(*head)->data;i++)
{
node=(CList)malloc(sizeof(CLinkList));
if(!node)
exit(INFEASIBLE);
node->data=rand()%LIMIT;//随机赋值
temp->next=node;
temp=node;//节点链接
}
temp->next=(*head);//尾节点指向头结点,构成环
return OK;
}//初始化链表
int CList_Show(CList head)
{
CList p=head->next;
if(p==head)
return ERROR;
while(p!=head)//遍历终止条件,p和head指向同一个空间
{
printf("%0d ",p->data);
p=p->next;//指针移位
}
printf("\n");
return OK;
}//输出表
int CList_Insert(CList head,int Data,int Pos)
{
CList p=head,q;
int i=1;
while(!(p==head&&i!=1)&&i<=Pos)
//插入位置合法性判断以及终止循环条件://非第一次p和head指向同一空间
{
if(i==Pos)//插入条件
{
q=(CList)malloc(sizeof(CLinkList));//申请空间
if(!q)
exit(INFEASIBLE);
q->data=Data;
q->next=p->next;
p->next=q;//插入节点
head->data++;
return OK;
}
p=p->next;//指针移位
i++;
}
return ERROR;
}//按位置插入
int CList_Delete_Elem(CList head,int Data)
{
CList p=head,q;
int i=1,flag=0;
while(!(p==head&&i!=1))//终止循环条件:非第一次p和head指向同一空间
{
if(p->next->data==Data)//删除条件
{
flag=1;//标记置1
q=p->next;
p->next=q->next;
free(q);//删除节点
head->data--;
}
i++;
p=p->next;
}
if(flag==1)
return OK;
else
return ERROR;
}//按元素删除
int CList_Delete_Pos(CList head,int *Data,int Pos)
{
CList p=head,q;
int i=1;
while(!(p==head&&i!=1)&&i<=Pos)
// //删除位置合法性判断以及终止循环条件://非第一次p和head指向同一空间
{
if(i==Pos&&p->next!=head)//删除条件
{
q=p->next;
p->next=q->next;
*Data=q->data;
free(q);//删除节点
head->data--;
return OK;
}
p=p->next;
i++;
}
return ERROR;
}//按位置删除
int CList_Replace_Pos(CList head,int *Data,int Pos)
{
CList p=head->next;
int i=1,data=*Data;
while(p!=head&&i<=Pos)//替换位置合法性判断和终止循环条件
{
if(i==Pos)//替换条件
{
*Data=p->data;//返回目标元素
p->data=data;//替换
return OK;
}
p=p->next;//指针移位
i++;
}
return ERROR;
}//按位置替换
int CList_Replace_Elem(CList head,int Data,int data)
{
CList p=head->next;
int flag=0;
while(p!=head)//终止循环的条件:p和head指向同一内存空间
{
if(p->data==data)//替换条件
{
flag=1;//标记置1
p->data=Data;//替换
}
p=p->next;//指针移位
}
if(flag==0)
return ERROR;
else
return OK;
}//按元素替换,data为表中的元素
int CList_Find_Pos(CList head,int *Data,int Pos)
{
CList p=head->next;
int i=1;
while(p!=head&&i<=Pos)//查找位置条件和终止循环条件:p和head指向同一段内存空间
{
if(i==Pos)//查找目标元素条件
{
*Data=p->data;
return OK;
}
p=p->next;//指针移位
i++;
}
return ERROR;
}//按位置查找
int CList_Find_Elem(CList head,int Data,int Position[],int *N)
{
CList p=head->next;
int j=1,flag=0;
*N=0;
while(p!=head)//终止循环条件:p和head指向同一段内存空间
{
if(p->data==Data)//查找目标元素条件
{
flag=1;//标记置1
Position[*N]=j;//存储地址
(*N)++;
}
j++;
p=p->next;//指针移位
}
if(flag==1)
return OK;
else
return ERROR;
}//按元素查找
void CList_Show_Length(CList head,int *Length)
{
*Length=head->data;//返回表长
}//查看表长
void CList_Clear(CList head)
{
int Data;
while(head->data!=0)
Data=CList_Delete_Pos(head,&Data,1);//逐个删除首元素
}//清空表
void CList_Destroy(CList head)
{
CList_Clear(head);//清空表
free(head);//释放头结点
}//销毁表
int CList_Josephus(CList head,int k,int *Data)
{
int flag=1,Pos=1,State;
if(head->next==head||k<1)//判断初始条件:元素个数以及k值大小
return ERROR;
while(head->data!=1)//终止条件:只剩下一个元素的时候
{
if(flag%k==0)//删除元素条件
{
State=CList_Delete_Pos(head,Data,Pos);//删除元素
Pos--;
}
if(Pos==head->data)
Pos=0;
Pos++;//地址移位
flag++;
}
*Data=head->next->data;//返回剩余元素
return OK;
}//约瑟夫问题
int CList_Read(CList head)
{
FILE *fp;
int i=1;
CList p=head,q;
if((fp=fopen("Cycle_LinkList.txt","r"))==NULL)//打开文件并判断是否成功
{
printf("文件打开错误!/n");
exit(INFEASIBLE);
}
CList_Clear(head);//清空表
if((fscanf(fp,"%d",&head->data))==EOF)//判断文件是否为空
return ERROR;
for(i=1;i<=head->data;i++)//依次创建节点并读取元素,插入表中
{
q=(CList)malloc(sizeof(CLinkList));
if(!q)
exit(INFEASIBLE);
fscanf(fp,"%d",&q->data);
p->next=q;
p=q;
}
q->next=head;//尾节点的指针域指向头结点
fclose(fp);
return OK;
}//读取数据
int CList_Save(CList head)
{
FILE *fp;
CList p=head->next;
if((fp=fopen("Cycle_LinkList.txt","w"))==NULL)//打开文件并判断是否成功
{
printf("文件打开错误!/n");
exit(INFEASIBLE);
}
if(!p)//判断是否为空表
return ERROR;
fprintf(fp,"%0d ",head->data);//读取表长
while(p!=head)//依次读取节点
{
fprintf(fp,"%0d ",p->data);
p=p->next;
}
fclose(fp);
return OK;
}//保存数据
int menu()
{
int result;
while(1)//显示菜单
{
system("cls");
printf("*****************菜单*****************\n");
printf("01.初始化链表 02.按位置插入\n");
printf("03.按位置删除 04.按元素删除\n");
printf("05.按位置替换 06.按元素替换\n");
printf("07.按位置查找 08.按元素查找\n");
printf("09.查看表元素 10.查看表长\n");
printf("11.清空表 12.销毁表\n");
printf("13.约瑟夫环 14.保存数据\n");
printf("15.读取数据 00.退出程序\n");
printf("**************************************\n");
printf("请选择:");
while(scanf("%d",&result)!=1)//判断是否得到单一输入
{
fflush(stdin);
continue;
}
if(0<=result&&result<=15)//输入合法则退出并返回出入值
break;
}
return result;
}//菜单函数
int main()
{
CList head;
int State,Data,data,Pos,N,result;
int Position[LIMIT];
while(1)
{
result=menu();
switch(result)
{
case 1:
system("cls");
printf("初始化链表:\n");
State=CList_Init(&head);
if(State==ERROR)
printf("初始化失败!\n");
else
printf("初始化成功!\n");
printf("按任意键继续......\n");
getch();
break;
case 2:
system("cls");
printf("按位置插入(1-%d):\n",head->data+1);
printf("请输入插入位置:");
scanf("%d",&Pos);
printf("请输入插入元素:");
scanf("%d",&Data);
State=CList_Insert(head,Data,Pos);
if(State==ERROR)
printf("插入位置错误!\n");
else
printf("插入成功!\n");
printf("按任意键继续......\n");
getch();
break;
case 3:
system("cls");
printf("按位置删除:\n");
printf("请输入删除位置(1-%d):",head->data);
scanf("%d",&Pos);
State=CList_Delete_Pos(head,&Data,Pos);
if(State==ERROR)
printf("删除位置错误!\n");
else
{
printf("删除成功!\n");
printf("被删除元素为:%d\n",Data);
}
printf("按任意键继续......\n");
getch();
break;
case 4:
system("cls");
printf("按元素删除:\n");
printf("请输入删除元素:");
scanf("%d",&Data);
State=CList_Delete_Elem(head,Data);
if(State==ERROR)
printf("目标元素不存在!\n");
else
printf("删除成功!\n");
printf("按任意键继续......\n");
getch();
break;
case 5:
system("cls");
printf("按位置替换:\n");
printf("请输入替换位置(1-%d):",head->data);
scanf("%d",&Pos);
printf("请输入替换元素:");
scanf("%d",&Data);
State=CList_Replace_Pos(head,&Data,Pos);
if(State==ERROR)
printf("替换位置错误!\n");
else
{
printf("替换成功!\n");
printf("目标位置元素为:%d\n",Data);
}
printf("按任意键继续......\n");
getch();
break;
case 6:
system("cls");
printf("按元素替换:\n");
printf("请输入替换前元素:");
scanf("%d",&data);
printf("请输入替换后元素:");
scanf("%d",&Data);
State=CList_Replace_Elem(head,Data,data);
if(State==ERROR)
printf("目标元素不存在!\n");
else
printf("替换成功!\n");
printf("按任意键继续......\n");
getch();
break;
case 7:
system("cls");
printf("按位置查找:\n");
printf("请输入查找位置(1-%d):",head->data);
scanf("%d",&Pos);
State=CList_Find_Pos(head,&Data,Pos);
if(State==ERROR)
printf("查找位置错误!\n");
else
printf("目标位置元素为:%d\n",Data);
printf("按任意键继续......\n");
getch();
break;
case 8:
system("cls");
printf("按元素查找:\n");
printf("请输入查找元素:");
scanf("%d",&Data);
State=CList_Find_Elem(head,Data,Position,&N);
if(State==ERROR)
printf("目标元素不存在!\n");
else
{
printf("目标元素在表中的所有位置为:\n");
for(Pos=0;Pos<=N-1;Pos++)
printf("%0d ",Position[Pos]);
printf("\n");
}
printf("按任意键继续......\n");
getch();
break;
case 9:
system("cls");
printf("查看表元素:\n");
State=CList_Show(head);
if(State==ERROR)
printf("空表!\n");
printf("按任意键继续......\n");
getch();
break;
case 10:
system("cls");
printf("查看表长:\n");
CList_Show_Length(head,&Data);
printf("表长为:%d\n",Data);
printf("按任意键继续......\n");
getch();
break;
case 11:
system("cls");
printf("清空表:\n");
CList_Clear(head);
printf("已清空!\n");
printf("按任意键继续......\n");
getch();
break;
case 12:
system("cls");
printf("销毁表:\n");
CList_Destroy(head);
printf("已销毁!\n");
printf("按任意键继续......\n");
getch();
break;
case 13:
system("cls");
printf("约瑟夫环:\n");
printf("请输入约瑟夫环K值:");
scanf("%d",&N);
State=CList_Josephus(head,N,&Data);
if(State==ERROR)
printf("K值错误!\n");
else
printf("最终存留的元素为:%d\n",Data);
printf("按任意键继续......\n");
getch();
break;
case 14:
system("cls");
printf("保存数据:\n");
State=CList_Save(head);
if(State==ERROR)
printf("空表!\n");
else
printf("保存成功!\n");
printf("按任意键继续......\n");
getch();
break;
case 15:
system("cls");
printf("读取数据:\n");
State=CList_Read(head);
if(State==ERROR)
printf("暂无数据!\n");
else
printf("读取数据成功!\n");
printf("按任意键继续......\n");
getch();
break;
case 0:
printf("确定退出程序?Y/N\n");
fflush(stdin);
if(getchar()=='Y')
{
printf("谢谢使用!\n");
exit(0);
}
printf("按任意键继续......\n");
getch();
break;
}
}
return 0;
}
数据结构(C语言) 线性表 链式存储 循环链表
最新推荐文章于 2023-01-06 13:40:33 发布