线性表-circularLinkList(循环链表练习题)

1:设计一个算法用于判断带头结点的循环双链表是否对称

复制代码
int judgebalance(pNode **head)
{
    pNode *p,*q;
    p=*head->next;//指向下一个正序
    q=*head->prev;//指向前一个逆序
    /*我的思路
    while(p->data==q->data)//对应的位置值相等
    {
        p=p->next;
        q=q->next;
        if(p==q)//奇数个数指向同一地址
        {
            printf("对称");
            return 1;
            break;
        }
        else if(p->next==q&&q->prev==p)//偶数个数
        {
            printf("对称");
            return 1;
            break;
        }
    }
    return 0;
    */
    //另一种书上的
    while(p!=q&&p->next!=q->prev)
    {
        if(p->data==q->data)
        {
            p=p->next;
            q=q->prev;
        }
        else return 0;
    }
    return 1;
}
复制代码

2:有两个循环单链表,链表头指针针分别为h1和h2,编写一个函数将链表h2链接到链表h1之后,要求链接后的链表仍保持循环链表形式。

单链表定义

struct Nodet
{
    int a;
    struct Nodet* next;
}

正文

复制代码
void mergeh(Nodet &h1,Nodel &h2)
{
    Nodet *p,*q,*pp,*qq;
    p=pp=h1;
    q=qq=h2;
    while(p->next!=pp)
    {
        p=p->next;
    }
    p->next=q;
    while(q->next!=qq)
    {
        q=q->next;
    }
    q->next=p;

}
复制代码

3:设有一个带头结点的循环单链表,其结点值均为正整数、设计一个算法,反复找出单链表中结点值最小的结点并输出,然后将该节点从中删除。直到单链表空为止,再删除表头结点。

在不空时循环,每循环一次查找一个最小节点,,记录其前驱节点,删除改点

复制代码
void de(Nodet &L)
{
    Nodet *p,*pre,*minp,*minpre;
    while(L->next!=L)//表不空 循环
    {
        p=L->next;pre=L;
        minp=p;minpre=pre;
        while(p!=L)//循环一趟,找最小值
        {
            if(p->a<minp->a)//找到
            {
                minp=p;
                minpre=pre;
            }
            pre=p;//找下个节点
            p=p->next;
        }
        printf("%d",minp->a);
        minpre->next=minp->next;
        free(minp);
    }
    free(L);

}
复制代码

 3:对某电码文进行加密形成密码文,加密算法原文为C1C2C3...Cn加密后S1S2S3...Sn(一个环)。 关键字为key

s1顺时针计数,数到key将c1放入密文字符位置,从环中去除该字符位置,从环中下一字符计数,
到key个字符位置,将c2放入其中,直到全部放入密文环中产生s串,

将c串逐个放入已建好的循环链表中,每放入一个位置,去除一个位置

1:获取c的长度,初始化循环链表,初值为0
2:从s1开始计数,遇到节点值为0,k=key-1
3:将c赋值于k的下一个节点,每赋值一个节点计数加一,直到等于字符长度

   (1)书上方法(有点迷

复制代码
typedef struct node
{
    char ch;
    struct node *forw;
    struct node *backw;
}CODE;
char *decode(char *ocode,int key)
{
    char *ncode; int length ,count,i;
    CODE *loop, *p;
    Length=-strlen (ocode);
    //动态分配密文环
    1oop=(CODE *)malloc(length*sizeof (CODE))
    //构建双向循环链表
    for(i=1;i<length;i++)
    {
        loop[i].forw=&loop[i+1];
        loop[i].backw=&loop[i-1];
    }
    loop[0].backw=&loop[length-1];
    loop[0].forw=&loop[1];
    loop[length-1].forw=loop;
    loop[length-1].backw=&loop[length-2];
    for(p=loop,i=0;i<length;i++)
    {
        for(count=1;count<key;count++)
        {
           p=p->forw;
        }
        p->ch=*ocode++;
        p->backw->forw=p->forw;
        p->forw->backw=p->backw;
        P=p->forw;
    }
    ncode=(char *)malloc((length)+1*sizeof(char));
    for(i=0;i<length;i++)
    {
        ncode[i]=loop[i].ch;
    }
    ncode[length]='\0';
    return ncode;
}
void main()
{
    char ocode[256];
    int key,num=0;
    printf("输入电文:");
    while(num<255&&(ocode[num++]=getchar())!='\n');
    ocode[(num==255)?num:num-1]='\0';
    scanf("%d",&key);
    printf("%s",decode(ocode,key));
}
复制代码

      (2)我的方法:

复制代码
struct node1
{
    char data[2];
    int no;
    struct node1 *next;
};
struct node1 *ncreat(int n)
{
    int i;
    struct node1 *a,*b,*c;
    a=(struct node1 *)malloc(sizeof(struct node1));
    //a->data="m";
    strcpy(a->data,"0");
    a->no=1;
    printf("a->data %s \n",a->data);
    b=a;//头结点
   for(i=2;i<=n;i++)
   {
       c=(struct node1 *)malloc(sizeof(struct node1));
       strcpy(c->data,"0");
       c->no=i;
       printf("c->data %s \n",c->data);
       b->next=c;
       b=c;
   }
   b->next=a;//构成循环
   return a;//返回最后一个节点作为开始赋值的头结点,以便从s1开始计数
}
//2:从s1开始计数,遇到节点值为0 k+1,直到k=key
//3:将c赋值于k的下一个节点,没赋值一个节点计数加一,直到等于字符长度
struct node1 *ope(struct node1 *m,char *s,int len,int key)
{
    struct node1 *h,*beg,*use,*ret;
    char t[10];
    int i,k,l;
    beg=m;//起始点
    //ret=m->next;
    i=0;
    int lenn;
    printf("1\n");
    while(i<len)
    {
        printf("2\n");
        h=beg;//开头
        use=m;
        k=0;lenn=len,l=0;
        t[0]=s[i];
        while(k<key-1)
        {
            h=h->next;
            if(strcmp(h->data,"0")==0)
            {
                k++;
            }
        }
        printf("no %d\n",h->no);
        t[0]=s[i];
        strcpy(h->data,t);
        //h->data=*(t+i);//赋值
        printf("h->data %s \n",h->data);i++;
        //beg指向下一个为0位置
        h=h->next;
        while(strcmp(h->data,"0")!=0&&l<len)
        {
            h=h->next;
            l++;
        }
        beg=h;
        while(lenn>0)
        {
            printf("%s ",use->data);
            use=use->next;
            lenn--;
        }
        printf("\n");
    }
    return m;
};
int main()
{
    char s[]="asdfghjkl";//要加密字符
    int slen=strlen(s),key=5;
    int h;
    struct node1 *p,*q,*n;
    p=ncreat(slen);//初始化链表

    h=slen;
    n=p;
    printf("新建链表\n");
    while(h>0)
    {
        printf("%s ",n->data);
        n=n->next;
        h--;
    }
    printf("\n");
    q=ope(p,s,slen,key);
    h=slen;
    n=q;
    printf("加密输出\n");
    while(h>0)
    {
        printf("%s ",n->data);
        n=n->next;
        h--;
    }


}
复制代码

4:求约瑟夫问题 n个小孩围一圈,从1开始编号,指定从第w个小孩开始报数,报道第s个出列,从下一个开始报数,重复下去,知道所有小孩都出列,求出列顺序

循环列表,头尾相连
每指向下一个节点时,计数加一,为s时输出,删除该节点,前一节点指向该节点的下一节点
直到删除个数为n

复制代码
struct node
{
    int data;
    struct node *next;
};
struct node *ncreat(int n)
{
    int i;
    struct node *a,*b,*c;
    a=(struct node *)malloc(sizeof(struct node));
    a->data=1;
    b=a;//头结点
   for(i=2;i<=n;i++)
   {
       c=(struct node *)malloc(sizeof(struct node));
       c->data=i;
       b->next=c;
       b=c;
   }
   b->next=a;//构成循环
   return a;
}
void ope(struct node *p,int n,int w,int s)
{
    //p链表,n个数,w开始,s间隔
    struct node *a,*b,*beg,*pre,*cur;
    int i=n,k;
    a=p;
    while(i>0)
    {
        if(a->data==w)
        {
            beg=a;
            break;
        }
        a=a->next;
        i--;
    }
    while(n>0)//删除一个数 n-1
    {
        b=beg;
        //1:从begin开始走s-1个节:2:输出下一个节点值3:begin指向下下个节点 n-1
        for(k=0;k<s-1;k++)
        {
            b=b->next;
        }
        pre=b;
        cur=pre->next;
        printf("%d ",cur->data);
        pre->next=cur->next;//出列
        beg=cur->next;
        n--;
    }
}
int main(){
    int n,w,s,h;
    struct node *p,*u;
    printf("请输入n,w,s;以空格间隔开\n");
    scanf("%d %d %d",&n,&w,&s);
    p=ncreat(n);//创建链表
    u=p;
    h=n;
    while(h>0)
    {
        printf("%d ",u->data);
        u=u->next;
        h--;
    }
    printf("\n");
    ope(p,n,w,s);
}
复制代码

 

posted on   Y-flower  阅读(159)  评论(0编辑  收藏  举报

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示