ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

双向链表和循环链表并用

2021-01-17 15:34:05  阅读:175  来源: 互联网

标签:count struct 并用 next 链表 int pend 双向


双向链表和循环链表并用

双向链表使用前驱指针以及后继指针
循环链表就是尾指针指向头
约瑟夫环问题:n个人围成一个圈,指定一个数字v,从第一个人开始报数,每轮报到v的选手出局,由下一个人接着从头开始报,最后一个人是赢家。其中n>1,v>2。
下面是循环链表(单向)在约瑟夫环中的应用,测试数据只用了615,答案是546231,可能程序还有其他错误,望指正。
以下变量中:n是总人数,s是第几个人,最后一个程序默认s是1,v是指定数字即循环次数;

#include <stdio.h>
#include<malloc.h>
/*单向的话需要两个指针,双向的话,一个指针就够了*/
struct s{
int m;
struct s*next;};
int count=0;
struct s*create(int n)
{
    struct s*p,*phead,*pend;
    p=((struct s*)malloc(sizeof(struct s)));
    p->m=count+1;
    while(count<n)
    {
        if(count==0)
        {
            phead=p;
            pend=p;
            pend->next=NULL;
            count ++;
        }
        else
        {
            pend->next=p;
            pend=p;
            pend->next=NULL;
            count ++;
        }
         p=((struct s*)malloc(sizeof(struct s)));
        p->m=count+1;
    }
    pend->next=phead;
    return phead;
}
int main(void)
{
    struct s*p,*p0;
    int n,s,v,a[100],j,i;
    scanf("%d%d%d",&n,&s,&v);
    p=create(n);
    p0=p;
    for(i=0;i<(s+v-3);i++)
        p0=p0->next;
    p=p0->next;
    a[j]=p->m;j++;
    p0->next=p->next;
    while(n>1)
    {
        i=0;
        while(i<v-1){p0=p0->next;i++;}
        p=p0->next;
        a[j]=p->m;j++;
        p0->next=p->next;
        p=p0->next;
        n--;
    }
    for(i=0;i<j;i++)
        printf("%d ",a[i]);
}

下面是循环链表(双向)在约瑟夫环的应用,测试数据只用了615,答案是546231,程序可能还有其他错误,若有不当请指正

#include<stdio.h>
#include<malloc.h>
struct s
{
int m;
struct s*prior;
struct s*next;
};
int count=0;
struct s*create(int n)
{
    struct s*p,*phead,*pend;
    p=((struct s*)malloc(sizeof(struct s)));
    p->m=count+1;
    while(count<n)
    {
        if(count==0)
        {
            pend=p;
            phead=p;
            p->next=NULL;
            p->prior=NULL;
            count++;
        }
        else
        {
            pend->next=p;
            p->prior=pend;
            pend=p;
            pend->next=NULL;
            count ++;
        }
       p=((struct s*)malloc(sizeof(struct s)));
    p->m=count+1;
    }
    pend->next=phead;
    phead->prior=pend;
    return phead;
}
int main(void)
{
    int n,s,v,a[100]={0},j=0,i;
    struct s*p;
    scanf("%d%d%d",&n,&s,&v);
    p=create(n);
    while(n>0)
    {
        i=0;
        while(i<v-1)
        {  i++;
        p=p->next;
        }
        a[j]=p->m;j++;
    p->prior->next=p->next;
    p->next->prior=p->prior;/*双向链表删除一个节点时,修改后继指针的时候也要把前驱指针给修改了*/
    p=p->next;
    n--;
    }
    for(i=0;i<j;i++)
    {
        printf("%d",a[i]);
    }
}

下面是没有链表的循环程序,个人认为还比较简单,不用链表也没有十分繁琐,主要涉及到数组中的坐标问题,其余的不是很复杂
测试数据只有615,答案是546231,若有不当请指正

#include<stdio.h>
void del(int a[],int n,int i);

int main(void)
{

    int n,s,m,i,j=0,c,t;
    int a[100]={0},b[100]={0};

    scanf("%d%d%d",&n,&s,&m);
    t=n;
    for(i=0;i<n;i++)
    {
        a[i]=i+1;
    }
    for(c=m+s-2;j<t;j++)
    {
        c=c%n;
        b[j]=a[c];
        del(a,t,c);
        n--;
        c=c+m-1;
    }

    for(i=0;i<t;i++)
    {
        printf("%2d\n",b[i]);
    }
    return 0;

}
void del(int a[],int n,int i)
{
    for(;i<n-1;i++)
    {
        a[i]=a[i+1];
    }
}

注,数组删除元素:
1.字符数组删除元素每次删除一个到了末尾让\0往上补,\0也不会显示出来,以此达到删除的目的
2.整形数组删除时示例如下
输入 12345678
删除45
得到结果(若全部输出)
为12367888,最后的数字一定会赘余,因此要控制输出元素个数
如果输出的元素个数为6,则为123678,可以达到删除元素的目的。

标签:count,struct,并用,next,链表,int,pend,双向
来源: https://blog.csdn.net/weixin_52205764/article/details/112746345

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有