【C语言】 约瑟夫环,循环链表实现

1、循环链表实现约瑟夫环,每次经过特定步数删除一个元素

cs 复制代码
//looplist.h
#ifndef LOOPLIST_H
#define LOOPLIST_H
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

typedef int datatype;

typedef struct Node
{
    union 
    {
        int len;
        datatype data;
    };
    struct Node *next;
}Node,*NodePtr;

//创建循环链表
NodePtr link_create();

//判空
int link_empty(NodePtr L);

//链表申请空间封装节点
NodePtr apply_node(datatype e);


//按位置进行查找
NodePtr list_search_pos(NodePtr L, int pos);

//头插
int link_insert_tail(NodePtr L,datatype e);

//遍历链表
int link_show(NodePtr L);

//约瑟夫
int link_yue(NodePtr L,int flag);
#endif
cs 复制代码
//looplist.c
#include"looplist.h"


//创建循环链表
NodePtr link_create()
{
    NodePtr L = (NodePtr)malloc(sizeof(Node));
    if(NULL == L)
    {
        printf("链表创建失败\n");
        return NULL;
    }
    L->len = 0;
    L->next = L;
    printf("创建链表成功\n");
    return L;
}

//判空
int link_empty(NodePtr L)
{
    return L->next == L;
}

//链表申请空间封装节点
NodePtr apply_node(datatype e)
{
    //堆区申请一个节点的空间
    NodePtr p = (NodePtr)malloc(sizeof(Node));
    if(NULL == p)
    {
        printf("申请失败\n");
        return NULL;
    }

    //给节点赋值
    p->data = e;
    p->next = NULL;

    return p;
}



//按位置进行查找
NodePtr list_search_pos(NodePtr L, int pos)
{
    if(NULL == L || pos < 0 || pos > L->len)
    {
        printf("查找失败\n");
        return NULL;
    }
    NodePtr q = L;
    for (int  i = 0; i < pos; i++)
    {
        q = q->next;
    }
    return q;
}



//尾插
int link_insert_tail(NodePtr L,datatype e)
{   
    if(NULL == L)
    {
        printf("插入失败\n");
        return -1;
    }
    NodePtr q = list_search_pos(L,L->len);
    NodePtr p = apply_node(e);
    p->next = q->next;
    q->next = p;
    L->len++;
    printf("插入成功\n");
    return 0;
}


//遍历链表
int link_show(NodePtr L)
{
    if(NULL == L || link_empty(L))
    {
        printf("遍历失败\n");
        return -1;
    }
    NodePtr q = L->next;
    while(q != L)
    {
        printf("%d\t",q->data);
        q = q->next;
    }
    printf("\n");
}



//约瑟夫
int link_yue(NodePtr L, int flag) {
    if (L == NULL || flag <= 0 || link_empty(L)) {
        printf("输入的参数有误或链表为空。\n");
        return -1;
    }

    NodePtr prev = L; 
    NodePtr curr = L->next; 

    while (L->len > 1) 
    { 
        for (int count = 0; count < flag; count++) 
        {
            prev = curr; 
            curr = curr->next; 
        }
       
        printf("删除节点的值为: %d\n", curr->data); 
        prev->next = curr->next; 
        NodePtr temp = curr; 
        curr = curr->next; 
        L->len--; 
        free(temp); 
    }

    // 输出最后剩下的节点数据
    printf("最后剩下的节点数据是:%d\n", prev->data);
    return 0;
}
cs 复制代码
//main.c
#include"looplist.h"
int main(int argc, char const *argv[])
{
    NodePtr L = link_create();
    int flag = 0,n = 0,sum = 0;
    printf("请输入你想输入的个数:");
    scanf("%d",&n);

    //循环插入值
    for(int i = 0;i < n;i++)
    {
        printf("请输入第%d个值:",i+1);
        scanf("%d",&sum);
        link_insert_tail(L,sum);
    }


    printf("当前链表中的元素为:");
    link_show(L);

    printf("请输入你想走多少步移除一个数:");
    scanf("%d",&flag);
    getchar();

    //调用约瑟夫环函数
    link_yue(L,flag);
    return 0;
}

输出结果如下:

相关推荐
逝去的秋风6 分钟前
【代码随想录训练营第42期 Day57打卡 - 图论Part7 - Prim算法与Kruskal算法
算法·图论·prim算法
QXH20000015 分钟前
数据结构—双向链表
c语言·数据结构·算法·链表
bluebonnet2715 分钟前
【Rust练习】15.match 和 if let
开发语言·后端·rust
yueqingll30 分钟前
020、二级Java选择题综合知识点(持续更新版)
java·开发语言
旺小仔.33 分钟前
【数据结构篇】~排序(1)之插入排序
c语言·数据结构·算法·链表·性能优化·排序算法
一只小白菜~37 分钟前
实现实时Web应用,使用AJAX轮询、WebSocket、还是SSE呢??
前端·javascript·websocket·sse·ajax轮询
计算机学姐1 小时前
基于python+django+vue的在线学习资源推送系统
开发语言·vue.js·python·学习·django·pip·web3.py
A洛1 小时前
Cloudflare Pages 部署 Next.js 应用教程
开发语言·github·nextjs·cloudflare·cloudflarepages
lly2024061 小时前
Rust 函数
开发语言
许野平1 小时前
Rust:深入浅出说一说 Error 类型
java·开发语言·rust·error