如何单链表实现约瑟夫

单链表实现约瑟夫,不是很好做,我试过很多方法单链表实现约瑟夫

img

供参考:

#include <stdio.h>
#include <stdlib.h>
typedef int Elemtype;
typedef struct LNode{
    Elemtype data;
    struct LNode *next;
}LNode,*Linklist;

void Createlist(Linklist* L,int n)
{
    Linklist p,tail;
    (*L) = (Linklist)malloc(sizeof(LNode));
    (*L)->next = (*L);//先使其循环
    p = (*L);
    p->data = 1;//创建首节点先给首节点赋值
    tail = (*L);
    for(int i = 2;i <= n;i++)
    {
        p = (Linklist)malloc(sizeof(LNode));
        p->data = i;
        p->next = (*L);
        tail->next = p;
        tail = p;
    }
}
void Listtrave(Linklist L,int n)//遍历函数
{
    Linklist p;
    p = L;
    for(int i = 1;i <= n;i++)
    {
        printf("%4d",p->data);
        p = p->next;
    }
    printf("\n");
}
Linklist Solution(Linklist L,int n,int b)
{
    Linklist p = L,s = L;
    int count = 1;
    while(n > 2)
    {
        if(count != b)//不等于 b 时的移位
        {
            count++;
            p = p->next;
        }
        else
        {
            Linklist q = p;//用q保存p所指的位置,方便进行节点的删除
            count = 1;//将count重置为1
            printf(n == 3 ? "%4d\n" : "%4d", p->data);//打印出局的值
            while(s->next != p) s = s->next;//将s移位到p的前驱节点处
            p = p->next;//使p指向自己的下一个节点
            s->next = p;//进行删除
            free(q);
            n--;  //人数减一
        }
    }
    if(s->data > p->data)
        return p;
    else
        return s;
}


int main()
{
    Linklist L;
    int n , b;
    scanf("%d%d",&n , &b);
    Createlist(&L,n);
    printf("创建的约瑟夫环为:\n");
    Listtrave(L,n);
    printf("依次出局的结果为:\n");
    L = Solution(L,n,b);
    Listtrave(L,2);

    return 0;
}

img


#include <stdio.h>
#include<malloc.h>
#include <stdlib.h>
typedef struct Node
{
    int data;
    struct Node* next;
}Node, *LinkList; //循环单链表
Node* IntCLinkList()
{
    int n, i;
    LinkList head, tail, temp;
    printf("输入n:");
    scanf("%d", &n);
    tail = head = NULL;
    for (i = 1; i <= n; i++)
    {
        temp = (Node*)malloc(sizeof(Node));//开辟新节点
        temp->data = i;//给节点的值域赋值成i的值
        if (head == NULL)//空链表
        {
            head = temp;
        }
        else
        {
            tail->next = temp;
        }
        tail = temp;  //尾指针指向新的节点; 
    }
    tail->next = head; //指向头,形成环
    return head;
}
int main()
{
    LinkList q = NULL;


    LinkList p = IntCLinkList();
    int m;//循环变量
    int i = 1;//起始位置
    int j = 3;//开始遍历的位置

    printf("请输入开始循环的m值为:");
    scanf("%d", &m);
    printf("出队列的位置为: ");
    while (p->next != p)
    {
        while (j > 1)//指针走到开始遍历位置
        {
            q = p;
            p = p->next;
            --j;
        }
        q = p;
        p = p->next;
        i++;
        if (i == m)
        {
            printf("  %d ", p->data);
            q->next = p->next;
            free(p);
            p = q->next;
            i = 1; //重新计数    
        }
    }
    printf("\n");
    printf("最后一个位置为:%d", p->data);
    free(p);
    return 0;
}