数据结构<三>单循环链表

目录

一、单循环链表的定义

二、单循环链表的创建与初始化

三、单循环链表的插入

四、单循环链表的删除

五、单循环链表的遍历

六、单循环链表的修改

七、单循环链表的查找

八、测试主程序

一、单循环链表的定义

单循环链表是一种数据结构,它类似于单向链表,不同之处在于它的最后一个节点连接回第一个节点,形成了一个循环。这意味着在单循环链表中,每个节点都有一个指针指向下一个节点,并且最后一个节点指向第一个节点。这样,这个链表就可以无限制地循环下去。

二、单循环链表的创建与初始化
cpp 复制代码
//单循环链表的定义
typedef struct node
{
    int data;          // 数据域
    struct node *next; // 指针域
} cyclist_t;           // crcle list
​
//单循环链表的初始化
cyclist_t *cyclist_init(void)
{
    cyclist_t *h = malloc(sizeof(cyclist_t));
    h->data = 0; // 头节点的数据域为0
    h->next = h; // 头节点的指针域指向自己
    return h;
}
三、单循环链表的插入
cpp 复制代码
//单循环链表的插入
int cyclist_insert(cyclist_t *h, int val)
{
    cyclist_t *p = malloc(sizeof(cyclist_t));
    p->data = val;     // 赋值
    p->next = h->next; // 接链表步骤1
    h->next = p;       // 接链表步骤2
    return 0;
}
四、单循环链表的删除
cpp 复制代码
//单循环链表的删除
// 正常删除1个节点, 要定位要要删除节点的前一个节点
// 如果要删除的节点是头结点 , 必须要更新一个新的头结点。
cyclist_t *cyclist_delete(cyclist_t *h, int val)
{
    cyclist_t *p = h; // p 指向头节点 , 必须定位的头节点
    cyclist_t *q;
    // 判断p->next 节点的地址 是不是和头节点重合了
    // 如果重合了, p定位到了h 的前一个节点
    while (p->next != h)
    {
        if (p->next->data == val)
        {
            q = p->next;       // 要删除的节点
            p->next = q->next; // 步骤1
            free(q);           // 步骤2
            return h;          // 返回头节点
        }
        p = p->next; // 往后移动1个节点
    }
    if (p->next == h)
    {
        if (p->next->data == val) // 要删除的节点是头节点
        {
            q = p->next;       // 要删除的节点
            p->next = q->next; // 步骤1
            free(q);           // 步骤2
            return p;          // 返回新头节点
        }
    }
    return h;
}
五、单循环链表的遍历
cpp 复制代码
//遍历单循环链表
int cyclist_print(cyclist_t *h)
{
    cyclist_t *p = h->next; // p 指向第一个节点
    printf("链表的内容:");
    // p != h
    // p == h   链表已经循环一遍
    while (p != h)
    {
        printf("%d ", p->data);
        p = p->next; // 移动节点
    }
    if (p == h) // 表示链表循环正好一周
    {
        printf("%d ", p->data);
    }
    printf("\n");
}
六、单循环链表的修改
cpp 复制代码
//修改单循环链表
int cyclist_modify(cyclist_t *h, int oldval, int newval)
{
    cyclist_t *p = h->next; // p 指向第一个节点
    while (p != h)          // 遍历链表
    {
        if (p->data == oldval) // 找到要修改的节点
        {
            p->data = newval;
            return 0; // 函数返回
        }
        p = p->next; // 移动节点
    }
    return 0; // 没有找到要修改的节点
}
七、单循环链表的查找
cpp 复制代码
//查找单循环链表
int cyclist_search(cyclist_t *h, int val)
{
    cyclist_t *p = h->next; // p 指向第一个节点
    while (p != h)          // 遍历链表
    {
        if (p->data == val) // 找到要查找的节点
        {
            return 1; // 查找成功
        }
        p = p->next; // 移动节点
    }
    return 0; // 查找失败
}
八、测试主程序
cpp 复制代码
int main(int argc, char const *argv[])
{
    cyclist_t *L = cyclist_init();
    for (int i = 1; i < 11; i++)
    {
        cyclist_insert(L, i);
    }
    cyclist_print(L);
    L = cyclist_delete(L, 10);
    L = cyclist_delete(L, 0);
    L = cyclist_delete(L, 5);
    cyclist_print(L);
    cyclist_modify(L, 9, 99);
    cyclist_modify(L, 4, 44);
    cyclist_modify(L, 2, 22);
    cyclist_print(L);
    if(cyclist_search(L, 99))
    {
        printf("99 found\n");
    }
    else
    {
        printf("99 not found\n");
    }
    if(cyclist_search(L, 10))
    {
        printf("10 found\n");
    }
    else
    {
        printf("10 not found\n");
    }
    return 0;
}
相关推荐
数模竞赛Paid answer9 小时前
2023年五一杯数学建模A题无人机定点投放问题求解全过程完整文档及程序
算法·数学建模·无人机·五一杯
科学实验家9 小时前
dp子序列问题,好难呀
算法
wabs66618 小时前
关于图论【卡码网117.软件构建的思考】
数据结构·算法·软件构建·图论·卡码网
mifengxing18 小时前
LeetCode 41.缺失的第一个正数|Hard题O(n)+O(1)最优解法深度解析
java·算法·leetcode·排序算法
Tongzhi202619 小时前
从部署到运维:通芝科技无感考勤一体机的全流程效率解析
运维·数据结构·科技·算法·贪心算法
Wang's Blog19 小时前
AI Agent白手起家30: 动态示例选择器之根据长度选择 Few Shot 示例
算法
oyguyteggytrrwwwrt21 小时前
自制交叉线路识别算法
算法
手写码匠21 小时前
华为云Flexus+DeepSeek征文|Dify 多智能体协同编排实战:R1 规划 + V3 执行,构建企业 Agent 团队
人工智能·深度学习·算法·aigc
晓天衡宇•评测社区1 天前
FSR-Bench 前沿科学推理榜单发布:GPT-5.5 居首,“会推理”未必“能答对”
算法
程序喵大人1 天前
【C++进阶】STL算法与函数对象 - 02 sort为什么需要随机访问迭代器
开发语言·c++·算法