XHXD. 2024-01-04 09:38 采纳率: 100%
浏览 10
已结题

c语言双循环链表敢死队问题

请问如何加一个双循环链表实现敢死队问题,以下是用单循环链表,顺序存储,循环队列实现

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>
//顺序表
#define MAXSIZE 100
#define LISTINCCREMENT 10
#define OK 1
#define ERROR 0
typedef int ElemType;
typedef struct KList //定义数据结构体类型
{
    ElemType *elem;//储存空间基址
    int length ; //当前长度
    int listsize;//当前分配的存储容量(以sizeof(ElemType)为单位)
}SqList;
int InitList(SqList &L)//创建线性表函数
{
    L.elem=(ElemType *)malloc(MAXSIZE *sizeof(ElemType));//动态分配一个大小为MAXSIZE的数组空间 
    if(!L.elem)
    {
        printf("存储分配失败");
        return ERROR;
    }
    else
    {
        L.length=0;//空表长度为0
        L.listsize=MAXSIZE;
        return OK;//初始存储容量
    }
}
int ListInsert_Sq(SqList &L)//线性表再分配函数
{
    //SqList L;
    int *newbase;
    newbase=(ElemType *)realloc(L.elem,(L.listsize+LISTINCCREMENT)*sizeof(ElemType));
    //为顺序表增加一个大小为存储LISTNCCREMENT 个数据元素的空间
    if(!newbase)
    {
        printf("存储分配失败");
        return ERROR;
    }
    else
    {
        L.elem=newbase;//新基址
        L.listsize+=LISTINCCREMENT;
        //增加存储容量
        return OK;
    }
}
 
//循环单链表
typedef struct node
{
    int data;
    struct node *next ;
}LNode;//定义结点类型
LNode *CREAT(int n)//创建循环单链表(n个敢死队队员) 
{
    LNode *s,*q,*T;
    int i;
    if(n!=0)
    {
        T=q=(LNode *)malloc(sizeof(LNode));//生成第一个结点
        q->data=1;//使其data值为1
        for(i=2;i<=n;i++)
        {
            s=(LNode*)malloc(sizeof(LNode));//自动生成结点
            q->next=s;
            q->next->data=i;//赋值
            q=q->next;
        }    
        q->next=T;
    }
    return T;//返回头结点,形成循环链表
}
DELETE (LNode *T)//链表的删除
{
    LNode *a;
    int i;
    while(T->next!=T)
    {
        for(i=1;i<4;i++)//查找要删除节点的前一个结点
        {
          T=T->next;    
        }    
        a=T->next;
        T->next=a->next;//删除数据
        free(a);
        T=T->next ;
    }
    printf("\n");
    return (T->data );
}
 
//循环队列
#define QueueSize 1000//假定预分配的队列空间最多为1000个元素
//typedef int DataType;//假定队列元素的数据类型为字符
typedef struct{
    int data[QueueSize];
    int front;//头指针
    int rear;//尾指针
    int count; //计数器,记录队中元素总数
}SqQueue;
 
// 循环队列初始化 
void InitQueue(SqQueue *Q)
{//构造空队列Q 
    Q->front=Q->rear=0;
    Q->count=0; //计数器置0
}
 
// 判队列空
int IsEmpty(SqQueue *Q)
{
    return Q->front==Q->rear;
}
 
//判队列满
int IsFull(SqQueue *Q)
{
    return Q->rear==QueueSize-1+Q->front;
}
 
//进队列
void EnQueue(SqQueue *Q,int x)
{
    if (IsFull(Q))
    {
        printf("队列上溢"); //上溢,退出运行
        exit(0);
    }
    Q->data[Q->rear]=x; //新元素插入队尾
    Q->rear=(Q->rear+1)%QueueSize; //循环意义下将尾指针加1
    Q->count ++; //队列数加1
}
 
//出队列
int DeQueue(SqQueue *Q)
{
    int temp;
    if(IsEmpty(Q))
    {
        printf("队列为空"); //队列空,退出运行
        exit(0);
    }
    temp=Q->data[Q->front];
    Q->front=(Q->front+1)%QueueSize; //循环意义下的头指针加1
    Q->count--; //队列数减1
    return temp;
}
 
 
int main()
{
    SqList L;
    int s,i,count=0;//声明变量
    LNode *p;
    int z ,y,e=1,c=1;
    int num;
    int opt;
    while(c)
    {
    printf("\n————敢死队问题————\n");    
    printf("1.顺序表\n");
    printf("2.循环单链表\n");
    printf("3.循环队列\n");
    printf("4.退出\n");
    printf("请选择使用的存储结构:(1~4)\n\n");
    scanf("%d",&opt);
    if(opt >4||opt <1)
    {
        printf("输入有误请重新输入\n");
        continue;
    }
    switch(opt)
    {
    case 1:
        printf("您使用的是顺序表存储结构\n\n");
        while(e)
        {
            printf("请输入敢死队的人数:\n");
            scanf("%d",&num);
            if(num<1)
            {
                printf("输入有误请重新输入\n");
                continue;
            }
            InitList(L);
            while(num>L.listsize)//当顺序表当前分配的存储空间大小不足时进行再分配
                ListInsert_Sq(L);
            for(i=0;i<num;i++) L.elem[i]=i+1;//为队员赋值
            s=num;
            i=0;
            while(s>1)//当所剩敢死队员总数为1时,总循环结束
            {
                for(i=0;i<num;i++)
                    if(L.elem[i]!=0)
                    {
                        count++;
                        if(count==5)//报数循环
                        {
                            L.elem[i]=0;//表示队员出列
                            count =0;//计数器清零
                            s--;//敢死队员数-1
                        }
                    }
            }
            for(i=0;i<num;i++)//输出从一开始最后剩余队员的位置为 L.elem[i]
                if(L.elem[i]!=0)
                    if((num-L.elem[i]+2)%num==0)
                        printf("从第%d号开始计数能让排长最后一个留下。\n",num);
                    else
                        printf("从第%d号开始计数能让排长最后一个留下。\n",(num-L.elem[i]+2)%num);
            break;
        }
        break;
    
    case 2:
        e=1;
        printf("您使用的是循环单链表存储结构\n");
        while(e)
        {
            printf("请输入敢死队的人数:\n");
            scanf("%d",&num);
            if(num<1)
            {
                printf("输入有误重新输入\n");
                continue;
            }
            else
            {
                p=CREAT(num);
                y=DELETE(p);//计算从根结点出发剩下的y
                z=num-y+2;//计算从谁出发剩下根结点,公式1+num-y+1
                if(z%num==0)
                    printf("从第%d号开始计数能让排长最后一个留下。\n",z);
                else
                    printf("从第%d号开始计数能让排长最后一个留下。\n",(num-y+2)%num);
            }
            break;
        }
        break;
        
    case 3:
        e=1;
        printf("您使用的是循环队列存储结构\n\n");
        int start,count,j;
        SqQueue s;
        while(e)
        {
            printf("请输入敢死队的人数 :\n");
            scanf("%d",&num);
            if(num<1)
            {
                printf("输入有误请重新输入\n");
                continue;
            }
            for(start=1;start<=num;start++)//start为测试起点
            {
                InitQueue(&s);
                for(i=1;i<=num;i++)
                {
                    EnQueue(&s,i);
                }//初始化
                for(i=1;i<start;i++)
                {
                    j=DeQueue(&s);
                    EnQueue(&s,j);
                }//将队头元素放到队尾,这样循环后start就会在队头
                count=1;
                while(count<num)
                {
                    for(i=1;i<5;i++)
                    {
                        j=DeQueue(&s);
                        EnQueue(&s,j);
                    }//4个放到队尾
                j=DeQueue(&s);//删除队头
                count++;
                }
                if(s.data[s.front]==1)
                    break;
            }
            printf("从第%d号开始计数能让排长最后一个留下。\n",start);
            break;
        }
        break;
    case 4:
        exit(0);
    }
    }
}

  • 写回答

2条回答 默认 最新

  • 泡沫o0 2023年度博客之星上海赛道TOP 1 2024-01-04 10:03
    关注

    要使用双循环链表来解决敢死队问题,首先需要理解双循环链表的结构。双循环链表是一种特殊的链表,其中每个节点有两个指针,一个指向前一个节点,另一个指向后一个节点。链表的最后一个节点指向第一个节点,形成一个环,而第一个节点的前驱指针指向最后一个节点,也形成一个环。这种结构允许从任何节点开始双向遍历整个链表。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 4月5日
  • 已采纳回答 3月28日
  • 创建了问题 1月4日

悬赏问题

  • ¥15 hexo安装这种情况怎么办
  • ¥100 找hCaptcha图形验证码自动识别解决方案
  • ¥15 启动pycharm出错
  • ¥15 Windows Script Host 无法找到脚本文件"C:\ProgramData\Player800\Cotrl.vbs”
  • ¥15 matlab自定义损失函数
  • ¥15 35114 SVAC视频验签的问题
  • ¥15 impedancepy
  • ¥15 求往届大挑得奖作品(ppt…)
  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程