数据结构(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 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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值