数据结构(C语言) 线性表 链式存储 循环链表

来源:互联网 发布:apache开源项目 编辑:程序博客网 时间:2024/06/08 02:27
/*本程序中所有涉及到位置的地方,下标皆从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 -2typedef 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;}
阅读全文
0 0