双向链表的构造,以及约瑟夫问题

本文介绍了如何在C语言中使用双向链表结构,包括创建、遍历、节点插入和删除等操作,并利用约瑟夫环问题的示例展示了链表的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

函数主体:

#include <stdio.h>
#include <stdlib.h>
#include "./03_Mutlinklist.h"

/*n:    创建双向链表
 * @param [ in] 
 * @param [out] 
 * @return      
 */

Mutlinklist* create_Mutlink(void)
{
    Mutlinklist* head = (Mutlinklist*)malloc(sizeof(Mutlinklist));
    if(NULL == head){
        printf("链表为空,创建失败\n");
        return NULL;
    }
    //头结点链表长度初始化为0
    head->data.len = 0;
    //头结点中的指针域初始化为空
    head->next = NULL;
    head->prev = NULL;

    return head;
}

/*
 * function:    遍历链表
 * @param [ in] 
 * @param [out] 
 * @return      
 */

void show_Mutlink(Mutlinklist* head)
{

    Mutlinklist* p = head->next;
    while(p != NULL){
        printf("%d\t",p->data.text);
        p = p->next;
    }
    putchar(10);
    return;
}
/*
 * function:    将创建的新节点封装为函数
 * @param [ in] 
 * @param [out] 
 * @return      
 */

/*
 * function:    头插法插入数据
 * @param [ in] 
 * @param [out] 
 * @return      
 */

void head_Mutlinklist(Mutlinklist* head,datatype num)
{
    Mutlinklist* temp = (Mutlinklist*)malloc(sizeof(Mutlinklist));
    if(NULL == temp){
        printf("结点申请失败\n");
        return;
    }
    temp->data.text = num;
    temp->next = NULL;
    temp->prev = NULL;

    temp->next = head->next;
    head->next = temp;
        
    temp->prev = head;    
     if(temp->next != NULL){
        temp->next->prev = temp;
    }
    head->data.len++;
    return;    
}

void end_insertMutlink(Mutlinklist* head,datatype num)
{
    Mutlinklist* temp = (Mutlinklist*)malloc(sizeof(Mutlinklist));
    if(NULL == temp){
        printf("结点申请失败\n");
        return;
    }
    temp->data.text = num;
    temp->next = NULL;
    temp->prev = NULL;

    Mutlinklist* p = head;
    while(p->next != NULL){
        p=p->next;
    }
    temp->next = p->next;
    p->next = temp;
    
    temp->prev = p;
    head->data.len++;
    return;
}

/*
 * function:    判断链表是否为空
 * @param [ in] 
 * @param [out] 
 * @return      
 */

int isEmpty_Mutlink(Mutlinklist* head)
{
    return head->next == head ? 1:0;  //为1则返回空
}

/*
 * function:    头删法删除
 * @param [ in] 
 * @param [out] 
 * @return      
 */

datatype del_headMutlink(Mutlinklist* head)
{
    if(isEmpty_Mutlink(head)){
        printf("链表为空\n");
        return (datatype)-1;
    }
    
    Mutlinklist* p = head->next;    
    head->next = p->next;

    datatype num = p->data.text    ;
    free(p);
    p = NULL;
    head->data.len--;
    return num;

}

/*
 * function:    尾删法
 * @param [ in] 
 * @param [out] 
 * @return      
 */

datatype del_endMutlink(Mutlinklist* head)
{
    if(isEmpty_Mutlink(head) == 1){
        printf("链表为空,删除失败\n");
        return (datatype)-1;
    }
    Mutlinklist* p = head;
    while(p->next != NULL){
        p = p->next;
    }
    p->prev->next = p->next;
    datatype num = p->data.text;
    free(p);
    head->data.len--;
    return num;

}

/*
 * function:    按位置插入
 * @param [ in] 
 * @param [out] 
 * @return      
 */

void insert_poslMutlink(Mutlinklist* head,datatype pos,datatype num)
{
    Mutlinklist* temp = (Mutlinklist*)malloc(sizeof(Mutlinklist));
    if( NULL== temp){
        printf("创建结点失败\n");
        return;
    }
    temp->data.text = num;
    temp->next = NULL;
    temp->prev = NULL;

    if(pos < 0 || pos > head->data.len+1){
        printf("位置不合法\n");
        return;
    }
    Mutlinklist* p = head;
    for(int i = 0;i < pos-1;i++){
        p = p->next;
    }
    temp->next = p->next;
    p->next = temp;

    temp->prev = p;
    if(p->next != NULL){
        p->next->prev = temp;
    }
    head->data.len++;
     return;
}

/*
 * function:    按位置删除
 * @param [ in] 
 * @param [out] 
 * @return      
 */

void del_posMutlink(Mutlinklist* head,datatype pos)
{
    if(isEmpty_Mutlink(head) == 1){
        printf("链表为空,删除失败\n");
        return;
    }
    if(pos<0 || pos>head->data.len+1){
        printf("位置非法\n");
        return;
    }

    Mutlinklist* p = head;
    for(int i=0;i<pos;i++){
        p=p->next;
    }
    p->prev->next = p->next;
    if(p->next!=NULL){
        p->next->prev=p->prev;
    }
    free(p);
    p=NULL;
    return;
}


 函数声明:

#ifndef __MUTLINKLIST__
#define __MUTLINKLIST__
typedef int datatype;
typedef struct node{
    union{
        datatype text;
        int len;
    }data;
    struct node* next;
    struct node* prev;
}Mutlinklist;    


Mutlinklist* create_Mutlink(void);
void show_Mutlink(Mutlinklist* head);
void head_Mutlinklist(Mutlinklist* head,datatype num);
void end_insertMutlink(Mutlinklist* head,datatype num);
int isEmpty_Mutlink(Mutlinklist* head);
datatype del_headMutlink(Mutlinklist* head);
datatype del_endMutlink(Mutlinklist* head);
void insert_poslMutlink(Mutlinklist* head,datatype pos,datatype num);
void del_posMutlink(Mutlinklist* head,datatype pos);


#endif

框架:

约瑟夫问题8个人围坐一圈,约定从第3个人开始编号为1,数到第4个人出列。出列后原来第5个人计算为1. n=8,k=3,m=4,最终出队的结果是6 2 7 4 3 5 1 8

代码实现:

#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
    int data;
    struct Node *next;
} Node;

Node* createCircularLinkedList(int n) {
    Node *head = NULL;
    Node *prev = NULL;

    for (int i = 1; i <= n; i++) {
        Node *newNode = (Node *)malloc(sizeof(Node));
        newNode->data = i;
        newNode->next = NULL;

        if (head == NULL) {
            head = newNode;
        } else {
            prev->next = newNode;
        }
        prev = newNode;
    }

    prev->next = head; // 将最后一个节点指向头节点,形成循环

    return head;
}

void josephus(int n, int k, int m) {
    Node *head = createCircularLinkedList(n);

    Node *current = head;
    Node *prev = NULL;

    for (int i = 0; i < k - 1; i++) {
        prev = current;
        current = current->next;
    }

    while (n > 0) {
        for (int i = 0; i < m - 1; i++) {
            prev = current;
            current = current->next;
        }

        Node *next = current->next;
        printf("%d ", current->data);

        prev->next = next;
        free(current);

        current = next;
        n--;
    }
}

int main() {
    int n = 8;
    int k = 3;
    int m = 4;

    josephus(n, k, m);

    return 0;
}

效果:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值