/*本程序中所有涉及到位置的地方,下标皆从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 Double
{
int data;
struct Double *prior;
struct Double *next;
}*DList,DLinkList;
int DList_Init(DList *head)
{
DList node;
int i;
*head=(DList)malloc(sizeof(DLinkList));//申请头结点空间并判断是否成功
if(!(*head))
exit(INFEASIBLE);
(*head)->next=NULL;
(*head)->prior=NULL;//初始化头结点
printf("请输入表长:");
scanf("%d",&(*head)->data);
if((*head)->data<0)//判断输入是否合法
return ERROR;
srand(time(0));
for(i=1;i<=(*head)->data;i++)
{
node=(DList)malloc(sizeof(DLinkList));//申请节点空间并判断是否成功
if(!node)
exit(INFEASIBLE);
node->data=rand()%LIMIT;//随机给节点赋值
if(i!=1)
(*head)->next->prior=node;
node->next=(*head)->next;
(*head)->next=node;
node->prior=(*head);//插入节点
}
return OK;
}//初始化链表
int DList_Show(DList head)
{
DList p=head->next;
if(!p)
return ERROR;//判断是否为空表
while(p)//遍历输出表
{
printf("%0d ",p->data);
p=p->next;
}
printf("\n");
return OK;
}//输出表
int DList_Insert(DList head,int Data,int Pos)
{
DList p=head,q;
int i=1;
while(p&&i<=Pos)//插入位置合法性和终止循环条件:p为NULL
{
if(i==Pos)//插入条件
{
q=(DList)malloc(sizeof(DLinkList));//申请空间并判断是否成功
if(!q)
exit(INFEASIBLE);
q->data=Data;
q->next=p->next;
q->prior=p;
if(p->next!=NULL)//尾节点区别对待
p->next->prior=q;
p->next=q;//插入节点
head->data++;
return OK;
}
p=p->next;
i++;
}
return ERROR;
}//按位置插入
int DList_Delete_Pos(DList head,int *Data,int Pos)
{
DList p=head->next;
int i=1;
while(p&&i<=Pos)//删除位置合法性和终止循环条件:p为NULL
{
if(i==Pos)//删除条件
{
if(p->next!=NULL)
p->next->prior=p->prior;
p->prior->next=p->next;
*Data=p->data;//返回目标元素
free(p);//删除节点
head->data--;
return OK;
}
p=p->next;//指针移位
i++;
}
return ERROR;
}//按位置删除
int DList_Delete_Elem(DList head,int Data)
{
DList p=head->next,q;
int flag=0;
while(p)//p为NULL终止遍历
{
if(p->data==Data)//删除条件
{
flag=1;//标记置1
q=p;
p=p->next;
if(p)
p->prior=q->prior;
q->prior->next=p;
free(q);//删除元素
continue;
}
p=p->next;//指针移位
}
if(flag==0)
return ERROR;
else
return OK;
}//按元素删除
int DList_Replace_Pos(DList head,int *Data,int Pos)
{
DList p=head->next;
int i=1,data=*Data;
while(p&&i<=Pos)//替换位置合法性和终止循环条件:p为NULL
{
if(i==Pos)//替换条件
{
*Data=p->data;//返回目标元素
p->data=data;//替换
return OK;
}
p=p->next;
i++;
}
return ERROR;
}//按位置替换
int DList_Replace_Elem(DList head,int Data,int data)
{
DList 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==0)
return ERROR;
else
return OK;
}//按元素替换,data为表中的元素
int DList_Find_Pos(DList head,int *Data,int Pos)
{
DList p=head->next;
int i=1;
while(p&&i<=Pos)//查找位置合法性和终止循环条件
{
if(i==Pos)//查找条件
{
*Data=p->data;//返回目标元素
return OK;
}
p=p->next;//指针移位
i++;
}
return ERROR;
}//按位置查找
int DList_Find_Elem(DList head,int Data,int Position[],int *N)
{
DList 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 DList_Show_Length(DList head,int *Length)
{
*Length=head->data;//返回表长
}//查看表长
void DList_Destroy(DList head)
{
DList p=head;
while(head)//终止条件
{
head=head->next;//指针移位
free(p);//删除节点
p=head;
}
head=NULL;
}//销毁表
void DList_Clear(DList head)
{
DList p=head->next;
head->data=0;
head->next=NULL;//断开头结点与首元素
DList_Destroy(p);//销毁首元素后面的节点
}//清空表
int DList_Josephus(DList head,int k,int *Data)
{
int flag=1,Pos=1,State;
if(!(head->next)||k<1)//判断初始条件:表长与k值
return ERROR;
while(head->data!=1)//表长为1退出循环
{
if(flag%k==0)//删除条件
{
State=DList_Delete_Pos(head,Data,Pos);//删除节点
Pos--;
}
if(Pos==head->data)
Pos=0;
Pos++;//地址移位
flag++;
}
*Data=head->next->data;//返回剩余元素
return OK;
}//约瑟夫问题
int DList_Read(DList head)
{
FILE *fp;
DList p=head,q;
int i=1;
if((fp=fopen("Double_LinkList.txt","r"))==NULL)//打开文件并判断是否成功
exit(INFEASIBLE);
DList_Clear(head);//清空表
if((fscanf(fp,"%d",&head->data))==EOF)//判断文件是否为空
return ERROR;
for(i=1;i<=head->data;i++)
{
q=(DList)malloc(sizeof(DLinkList));//申请空间并判断是否成功
if(!q)
exit(INFEASIBLE);
fscanf(fp,"%d",&q->data);//读取数据
p->next=q;
q->prior=p;
p=q;//插入表中
}
p->next=NULL;//尾节点的指针域置空
fclose(fp);
return OK;
}//读取数据
int DList_Save(DList head)
{
FILE *fp;
DList p=head->next;
if((fp=fopen("Double_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)//判断是否为单一输入
{
fflush(stdin);
continue;
}
if(0<=result&&result<=15)//判断输入是否合法,合法则退出并返回
break;
}
return result;
}//菜单函数
int main()
{
DList head;
int State,Data,data,Pos,N,result;
int Position[LIMIT];
while(1)
{
result=menu();
switch(result)
{
case 1:
system("cls");
printf("初始化链表:\n");
State=DList_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=DList_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=DList_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=DList_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=DList_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=DList_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=DList_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=DList_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=DList_Show(head);
if(State==ERROR)
printf("空表!\n");
printf("按任意键继续......\n");
getch();
break;
case 10:
system("cls");
printf("查看表长:\n");
DList_Show_Length(head,&Data);
printf("表长为:%d\n",Data);
printf("按任意键继续......\n");
getch();
break;
case 11:
system("cls");
printf("清空表:\n");
DList_Clear(head);
printf("已清空!\n");
printf("按任意键继续......\n");
getch();
break;
case 12:
system("cls");
printf("销毁表:\n");
DList_Destroy(head);
printf("已销毁!\n");
printf("按任意键继续......\n");
getch();
break;
case 13:
system("cls");
printf("约瑟夫环:\n");
printf("请输入约瑟夫环K值:");
scanf("%d",&N);
State=DList_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=DList_Save(head);
if(State==ERROR)
printf("空表!\n");
else
printf("保存成功!\n");
printf("按任意键继续......\n");
getch();
break;
case 15:
system("cls");
printf("读取数据:\n");
State=DList_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语言) 线性表 链式存储 双链表
最新推荐文章于 2024-09-19 15:57:43 发布