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

输出结果如下:

相关推荐
sbjdhjd7 小时前
Redis 主从复制、哨兵高可用与 Cluster 集群部署实验手册
运维·前端·redis·云原生·开源·bootstrap·html
z落落7 小时前
C# 泛型方法(原理、类型推断、多泛型参数)+泛型效率(普通类型 VS Object装箱 VS 泛型)
开发语言·c#
L_09077 小时前
【C++】异常
开发语言·c++
Frostnova丶7 小时前
【算法笔记】数学知识
笔记·算法
乐兮创想 小林7 小时前
企业官网移动端性能优化实战:从 Core Web Vitals 到图片/CDN/响应式的工程清单
前端·性能优化·网站建设·北京网站建设公司
吴可可1237 小时前
AutoCAD 2016与2014二次开发关键差异
算法
前端一小卒8 小时前
不手写代码的第 30 天,我才明白前端这个岗位还剩什么
前端·javascript·ai编程
Ajie'Blog8 小时前
Copilot Agent Tasks API 开放:AI 编程开始进入后台任务时代
服务器·前端·javascript·人工智能·copilot·ai编程
世辰辰辰8 小时前
批量修改图片/文本名子
开发语言·python·批量修改文件名
老毛肚8 小时前
jeecgboot vue TS & 模板化 04
前端·javascript·vue.js