引入

我们学习了这么多单循环链表的知识,那么该如何运用到生活中呢?或者该如何灵活的使用这些单循环链表的知识呢?

魔术师发牌问题

大概的情景是这样得

  • 13张牌

  • 从1~13,A~K

  • 数一张,放下是 A,把 A 放桌面上

  • 数两张,第一张放到牌堆最下面,第二张放下是2 ,把2放桌面上

  • 数三张,第一张、第二张放到牌堆最下面,第三张放下是3 ,把3放桌面上

  • 以此类推,所有13张牌都发完,桌面上正好是A~K

    大概思路

    • 跟约瑟夫问题类似
    • 移动指针,找到牌
    • 删除结点,重新构成链表
    • 再次移动指针,找到出牌顺序
    • 赋值 A~K,顺序输出即可

代码

#include <stdio.h>
#include <stdlib.h>
#define NUM 13
#define LEN sizeof(struct Poker)

struct Poker{
    int num;
    struct Poker *next;
};

struct Poker *create(void){
    struct Poker *a,*b,*head;
    int n=0;
    while(n<NUM){
        n++;
        a=(struct Poker *)malloc(LEN);
        a->num=n;
        if(n==1){
            head=a;
            b=a;
        }else{
            b->next=a;
            b=a;
        }
    }
    b->next=head;
    head=b;
    return head;
}

char * poker_init(struct Poker *loop){
    int n=0;
    int i=0;
    char poker_name[13]={'A','2','3','4','5','6','7','8','9','0','J','Q','K'};
    static char poker_card[13];
    do{
        if(n==i){
            poker_card[loop->next->num-1]=poker_name[i];
            loop->next=loop->next->next;
            n=0;
            i++;
        }
        loop=loop->next;
        n++;
    }while(loop->next!=loop);
    poker_card[loop->next->num-1]=poker_name[i];
    return poker_card;
}

int main(){
    struct Poker *card;
    card=create();
    char *p=poker_init(card);
    int i=0;
    printf("扑克准备顺序是:\n");
    while(i<13){
        printf("黑桃 %c\n",*(p+i));
        i++;
    }
}

代码大概思路

  • 利用约瑟夫问题的逻辑,间隔不是2人,而是 n-1,然后n++
  • 这样输出得结果就是出牌得顺序
  • 按照这个顺序将 A~K 赋值
  • 然后按照这个输出 A~K即可

尾巴

这是我的个人学习笔记,主要是应付考研复习使用,充斥着一些吐槽和个人观点,并不严谨,欢迎大家参考、指正。