C语言循环链表练习:约瑟夫环

C语言循环链表练习:约瑟夫环_第1张图片

1、问题描述

建立一个有n个结点的循环链表,每个人用链表的一一个结点描述。用指针p指向第一个报数的人的位置(编号为k),用链表模拟从1到m的报数,然后删除报数为m的结点,直至链表中仅剩下一个结点时结束,最后依次输出被删除结点的编号值。

  1. 编码实现

#include "stdio.h"
#include 
//定义一个循环链表的结构体
typedef struct Node {
    int data;//储存的数据
    struct Node* next;//指向下一个链表元素的指针
}Node;

//定义一个用于构建链表的函数,返回值为该链表的头指针
Node* start(int num) {
    // 定义一个头指针、尾指针以及中间变量的指针
    Node* head, * end, * p;
    //开辟内存空间
    head = (Node*)malloc(sizeof(Node));
    //使end与head指向同一地址,因为head不能动,而end会变化
    end = head;
    //提示可以开始录入数据了
    printf("\n开始录入一个%d位数组……\n", num);
    //用一个循环来建立规定个数的链表元素
    for (int i = 0;i < num;i++) {
        printf("请输入第%d个数据:", i + 1);
        //给新的元素分配一片内存空间
        p = (Node*)malloc(sizeof(Node));
        //接收输入的数据,并放Node结构体中的data中去
        scanf("%d", &p->data);
        // 使end指向p的位置
        end->next = p;
        end = p;
    }
    // 使链表头尾相连,形成循环链表
    end->next = head->next;
    return head;
}

//定义一个用来寻找符合条件的元素
void del(Node *head,int m,int b){
    Node *end;
    int i;
    //用循环来持续寻找目标,直到链表中只剩下一个元素为止
    while(head->next!=head && b>0){
        int n =0;//因为当m为一时,for循环不执行,为了防止出错所以用一个变量n来使程序进入if语句中
        for (i=1;inext;//这里模拟报数,到i=m-1时跳出循环
        }
        //重置i
        i=0;
        // 作用与上面的for循环相同
        if (n==0){printf("%d    ",head->next->data);end=head;head->next=head->next->next;b--;}
        else {
            // 将此次循环中符合条件的那个元素打印到控制台
        printf("%d  ",head->next->data);
        end=head->next;//用end来记录需要被删除的元素的地址
        head->next=end->next;//将链表后移一位
        free(end);//释放end所记录地址的内存
        }
        
    }
    // 将最后一个元素打印出来
    if (b!=0)printf("%d    ",head->next->data);
    
}

主程序:

//主程序
int main(){
    Node *head;
    int m;
    printf("请输入m:");
    scanf("%d",&m);
    head=start(4);
    del(head, m,4);
}
  1. 运行结果演示:

C语言循环链表练习:约瑟夫环_第2张图片

你可能感兴趣的:(c语言,链表,数据结构)