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

输出结果如下:

相关推荐
云泽8081 分钟前
C++ list容器模拟实现:迭代器、构造与STL风格编程
开发语言·c++·list
LFly_ice2 分钟前
Next-1-启动!
开发语言·前端·javascript
regon4 分钟前
第九章 述职11 交叉面试
面试·职场和发展·《打造卓越团队》
小时前端4 分钟前
谁说 AI 历史会话必须存后端?IndexedDB方案完美翻盘
前端·agent·indexeddb
2201_757830877 分钟前
条件分页查询
java·开发语言
wordbaby9 分钟前
TanStack Router 基于文件的路由
前端
LYFlied9 分钟前
【每日算法】LeetCode 105. 从前序与中序遍历序列构造二叉树
数据结构·算法·leetcode·面试·职场和发展
重生之我是Java开发战士11 分钟前
【数据结构】Java对象的比较
java·jvm·数据结构
wordbaby14 分钟前
TanStack Router 路由概念
前端
努力学习的小廉15 分钟前
【QT(六)】—— 常用控件(三)
开发语言·qt