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

/*本程序中所有涉及到位置的地方,下标皆从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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值