【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;
}

输出结果如下:

相关推荐
一棵开花的树,枝芽无限靠近你3 分钟前
【PPTist】添加PPT模版
前端·学习·编辑器·html
凡人的AI工具箱3 分钟前
15分钟学 Go 第 60 天 :综合项目展示 - 构建微服务电商平台(完整示例25000字)
开发语言·后端·微服务·架构·golang
陈王卜6 分钟前
django+boostrap实现发布博客权限控制
java·前端·django
景天科技苑14 分钟前
【vue3+vite】新一代vue脚手架工具vite,助力前端开发更快捷更高效
前端·javascript·vue.js·vite·vue项目·脚手架工具
SameX15 分钟前
HarmonyOS Next 安全生态构建与展望
前端·harmonyos
chnming198719 分钟前
STL关联式容器之map
开发语言·c++
进击的六角龙21 分钟前
深入浅出:使用Python调用API实现智能天气预报
开发语言·python
檀越剑指大厂21 分钟前
【Python系列】浅析 Python 中的字典更新与应用场景
开发语言·python
VertexGeek22 分钟前
Rust学习(八):异常处理和宏编程:
学习·算法·rust
石小石Orz23 分钟前
Three.js + AI:AI 算法生成 3D 萤火虫飞舞效果~
javascript·人工智能·算法