链表——环形链表

头文件cList.h

#ifndef _CLIST_H_
#define _CLIST_H_

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

struct Node;
typedef struct Node *pNode;

struct Head;
typedef struct Head *pHead;

struct Node
{
    int data;
    pNode next;
};

struct Head
{
    int length;
    pNode next;
};

pHead Create (void);                            // 创建循环链表
int GetLength (pHead pH);                       // 获取来年表长度
bool IsEmpty (pHead pH);                        // 判断是否为空
void Insert (pHead pH, int pos, int val);       // 在链表中插入元素
pNode Delete (pHead pH, int val);               // 删除链表中元素
pNode Search (pHead pH, int val);               // 查找链表中元素
void Print (pHead pH);                          // 打印链表

pHead
Create (void)
{
    pHead pH = (pHead)malloc (sizeof (struct Head));

    if (pH == NULL)
    {
        printf ("Error Memory!");
    }

    pH -> next = NULL;
    pH -> length = 0;

    return pH;
}

bool
IsEmpty (pHead pH)
{
    if (pH == NULL)
    {
        printf ("Error Head!");
    }

    if (pH -> length == 0)
    {
        return true;
    }

    return false;
}

void
Insert (pHead pH, int pos, int val)
{
    if (pH == NULL || pos < 0 || pos > pH -> length)
    {
        printf ("Error Input!");
    }

    pNode p = (pNode)malloc (sizeof (struct Node));
    p -> data = val;

    if (IsEmpty (pH))
    {
        pH -> next = p;
        p -> next = p;
    }
    else
    {
        pNode pRear = pH -> next;

        if (pos == 0)
        {
            while (pRear -> next != pH -> next)
            {
                pRear = pRear -> next;
            }

            p -> next = pH -> next;
            pH -> next = p;

            pRear -> next = p;
        }
        else
        {
            pNode pCur = pH -> next;

            for (int i = 1; i < pos; i ++)
            {
                pCur = pCur -> next;
            }

            p -> next = pCur -> next;
            pCur -> next = p;
        }
    }

    pH -> length ++;
}

pNode
Delete (pHead pH, int val)
{
    if (pH == NULL)
    {
        printf ("Error Head!");
    }

    pNode pRear = pH -> next;

    while (pRear ->next != pH -> next)
    {
        pRear = pRear -> next;
    }

    pNode p = Search (pH, val);

    if (p == NULL)
    {
        return NULL;
    }
    else
    {
        pNode pCur = pH -> next;

        for (int i = 0; i < pH -> length; i ++)
        {
            if (pCur -> next == p)
            {
                pCur -> next = p -> next;

                return p;
            }

            pCur = pCur -> next;

        }
    }

    return NULL;
}

pNode
Search (pHead pH, int val)
{
    if (pH == NULL)
    {
        printf ("Error Head!");
    }

    pNode p = pH -> next;

    do
    {
        if(p -> data == val)
        {
            return p;
        }

        p = p -> next;
    }
    while (p -> next != NULL);

    printf ("Not Found!");

    return NULL;
}

void
Print (pHead pH)
{
    if (pH == NULL)
    {
        printf ("Error Head!");
    }

    pNode p = pH -> next;

    for (int i = 0; i < pH -> length; i ++)
    {
        printf ("%d ", p -> data);

        p = p -> next;
    }

    printf ("\n");
}
#endif // _CLIST_H_

测试文件main.c

约瑟夫环问题

m个人围成一圈,从第一个开始报数,第n个将出局,最后剩下一个,其余人都将被出局。

#include "cList.h"

int main (void)
{
    int m, n;
    printf ("请输入约瑟夫环的总人数: \n");
    scanf ("%d", &m);

    if (m <= 0)
    {
        printf ("请输入正确的数字! \n");

        return 0;
    }

    printf ("请输入被踢人的报数: \n");
    scanf ("%d", &n);

    if (n <= 0)
    {
        printf ("请输入正确的数字! \n");

        return 0;
    }

    pHead pH = Create ();

    for (int i = m; i > 0; i --)                    // 根据输入的 m 创建链表
    {
        Insert (pH, 0, i);
    }

    Print (pH);
    printf ("被踢出顺序: \n");

    pNode p = pH -> next;                           // p 指向第一个节点

    while (p -> next != p)                          // while 循环结束后指向自身,此时剩下最后一个节点
    {
        for (int i = 1; i < n - 1; i ++)            // for 循环结束后 p 指向出局节点的上一个节点
        {
            p = p -> next;
        }

        pNode pCur = p -> next;                     // pCur 指向要出局的节点

        if (pCur == pH -> next)                     // 如果出局节点位于0位置,即头节点后一个
        {
            pH -> next = pCur -> next;              // 类似于 Delete 断开原先链接,与下一个节点相连接
            p -> next = pCur -> next;

            printf ("%d ", pCur -> data);

            free (pCur);

            pH -> length --;
        }
        else                                        // 非头节点同理
        {
            p -> next = pCur -> next;

            printf ("%d ", pCur -> data);

            free (pCur);

            pH -> length --;
        }

        p = p -> next;
    }

    p -> next = p;
    printf ("\n");

    printf ("链表中还留下的是: ");
    Print (pH);

    system ("pause");
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神秘的企鹅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值