/*本程序中所有涉及到位置的地方,下标皆从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 Single
{
int data;
struct Single *next;
}*SList,SLinkList;
int SList_Init(SList *head)
{
SList node;
int i;
*head=(SList)malloc(sizeof(SLinkList));//申请头结点空间并判断是否成功
if(!(*head))
exit(INFEASIBLE);
(*head)->next=NULL;
printf("请输入表长:");
scanf("%d",&(*head)->data);
if((*head)->data<0)//判断输入是否合法
return ERROR;
srand(time(0));
for(i=1;i<=(*head)->data;i++)
{
node=(SList)malloc(sizeof(SLinkList));//申请节点空间
if(!node)
exit(INFEASIBLE);
node->data=rand()%LIMIT;
node->next=(*head)->next;
(*head)->next=node;//依次插入连接
}
return OK;
}//初始化链表
int SList_Show(SList head)
{
SList p=head->next;
if(!p)//判断是否为空表
return ERROR;
while(p)//依次遍历输出
{
printf("%0d ",p->data);
p=p->next;
}
printf("\n");
return OK;
}//输出表
int SList_Insert(SList head,int Data,int Pos)
{
SList p=head,q;
int i=0;
while(p&&i<Pos-1)//插入位置合法性和终止循环条件:p为NULL
{
p=p->next;//指针移位
i++;
}
if(!p||i>Pos-1)//非法条件
return ERROR;
q=(SList)malloc(sizeof(SLinkList));//申请节点空间并判断是否成功
if(!q)
exit(INFEASIBLE);
q->data=Data;
q->next=p->next;
p->next=q;//插入节点
head->data++;
return OK;
}//按位置插入
int SList_Delete_Pos(SList head,int *Data,int Pos)
{
SList p=head,q;
int i=0;
while(p->next&&i<Pos-1)//删除位置合法性和终止循环条件:p->next为NULL
{
p=p->next;//指针移位
i++;
}
if(!(p->next)||i>Pos-1)//非法条件
return ERROR;
q=p->next;
p->next=q->next;
*Data=q->data;//返回目标元素
free(q);//删除节点
head->data--;
return OK;
}//按位置删除
int SList_Delete_Elem(SList head,int Data)
{
SList p=head,q;
int flag=0;
while(p->next)//p->next为NULL终止循环
{
if(p->next->data==Data)//删除条件
{
flag=1;//标记置1
q=p->next;
p->next=q->next;
free(q);//删除节点
head->data--;
continue;
}
p=p->next;//指针移位
}
if(flag==1)
return OK;
else
return ERROR;
}//按元素删除
int SList_Replace_Pos(SList head,int *Data,int Pos)
{
SList p=head->next;
int i=1,data=*Data;
while(p&&i<Pos)//替换位置合法性和终止循环条件:p为NULL
{
p=p->next;//指针移位
i++;
}
if(!p||i>Pos)//非法条件
return ERROR;
*Data=p->data;//返回目标元素
p->data=data;//替换
return OK;
}//按位置替换
int SList_Replace_Elem(SList head,int Data,int data)
{
SList p=head->next;
int flag=0;
while(p)//p为NULL终止循环
{
if(p->data==data)//替换条件
{
flag=1;//标记置1
p->data=Data;//替换
}
p=p->next;//指针移位
}
if(flag==1)
return OK;
else
return ERROR;
}//按元素替换,data为表中的元素
int SList_Find_Pos(SList head,int *Data,int Pos)
{
SList p=head->next;
int i=1;
while(p&&i<Pos)//查找位置合法性和终止循环条件:p为NULL
{
p=p->next;//指针移位
i++;
}
if(!p||i>Pos)//非法条件
return ERROR;
*Data=p->data;
return OK;
}//按位置查找
int SList_Find_Elem(SList head,int Data,int Position[],int *N)
{
SList p=head->next;
int j=1,flag=0;
*N=0;
while(p)//p为NULL终止循环条件
{
if(p->data==Data)//查找条件
{
flag=1;//标记置1
Position[*N]=j;//存储位置
(*N)++;
}
j++;
p=p->next;//指针移位
}
if(flag==1)
return OK;
else
return ERROR;
}//按元素查找
void SList_Show_Length(SList head,int *Length)
{
*Length=head->data;//返回表长
}//查看表长
void SList_Destroy(SList head)
{
SList p=head;
while(head)
{
head=head->next;//指针移位
free(p);//删除节点
p=head;
}
head=NULL;//释放头结点
}//销毁表
void SList_Clear(SList head)
{
SList p=head->next;
head->data=0;
head->next=NULL;//断开头结点
SList_Destroy(p);//销毁头结点后面的节点
}//清空表
int SList_Josephus(SList head,int k,int *Data)
{
int flag=1,Pos=1,State;
if(k<1||!(head->next))//判断条件是否合法:表长和k值大小
return ERROR;
while(head->data!=1)//当表长为1是终止循环
{
if(flag%k==0)//删除节点条件
{
State=SList_Delete_Pos(head,Data,Pos);//删除节点
Pos--;
}
if(Pos==head->data)
Pos=0;
Pos++;//位置移位
flag++;
}
*Data=head->next->data;//返回剩余元素
return OK;
}//约瑟夫问题
int SList_Read(SList head)
{
FILE *fp;
SList p=head,q;
int i=1;
if((fp=fopen("Single_LinkList.txt","r"))==NULL)//打开文件并判断是否成功
exit(INFEASIBLE);
SList_Clear(head);//清空表
if((fscanf(fp,"%d",&head->data))==EOF)//判断文件是否为空
return ERROR;
for(i=1;i<=head->data;i++)
{
q=(SList)malloc(sizeof(SLinkList));//申请节点空间并判断是否成功
if(!q)
exit(INFEASIBLE);
fscanf(fp,"%d",&q->data);//读取节点元素
p->next=q;
p=q;//插入节点元素
}
p->next=NULL;//尾节点指针域置空
fclose(fp);
return OK;
}//读取数据
int SList_Save(SList head)
{
FILE *fp;
SList p=head->next;
if((fp=fopen("Single_LinkList.txt","w"))==NULL)//打开文件并判断是否成功
exit(INFEASIBLE);
if(!p)//判断是否为空表
return ERROR;
fprintf(fp,"%0d ",head->data);//写入表长
while(p)
{
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)//判断输入是否为1
{
fflush(stdin);
continue;
}
if(0<=result&&result<=15)//判断输入是否合法,合法则退出并返回
break;
}
return result;
}//菜单函数
int main()
{
SList head;
int State,Data,data,Pos,N,result;
int Position[LIMIT];
while(1)
{
result=menu();
switch(result)
{
case 1:
system("cls");
printf("初始化链表:\n");
State=SList_Init(&head);
if(State==ERROR)
printf("初始化失败!\n");
else
printf("初始化成功!\n");
printf("按任意键继续......\n");
getch();
break;
case 2:
system("cls");
printf("按位置插入:\n");
printf("请输入插入位置(1-%d):",head->data+1);
scanf("%d",&Pos);
printf("请输入插入元素:");
scanf("%d",&Data);
State=SList_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=SList_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=SList_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=SList_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=SList_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=SList_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=SList_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=SList_Show(head);
if(State==ERROR)
printf("空表!\n");
printf("按任意键继续......\n");
getch();
break;
case 10:
system("cls");
printf("查看表长:\n");
SList_Show_Length(head,&Data);
printf("表长为:%d\n",Data);
printf("按任意键继续......\n");
getch();
break;
case 11:
system("cls");
printf("清空表:\n");
SList_Clear(head);
printf("已清空!\n");
printf("按任意键继续......\n");
getch();
break;
case 12:
system("cls");
printf("销毁表:\n");
SList_Destroy(head);
printf("已销毁!\n");
printf("按任意键继续......\n");
getch();
break;
case 13:
system("cls");
printf("约瑟夫环:\n");
printf("请输入约瑟夫环K值:");
scanf("%d",&N);
State=SList_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=SList_Save(head);
if(State==ERROR)
printf("空表!\n");
else
printf("保存成功!\n");
printf("按任意键继续......\n");
getch();
break;
case 15:
system("cls");
printf("读取数据:\n");
State=SList_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 发布