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

目录

一、单循环链表的定义

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

三、单循环链表的插入

四、单循环链表的删除

五、单循环链表的遍历

六、单循环链表的修改

七、单循环链表的查找

八、测试主程序

一、单循环链表的定义

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

二、单循环链表的创建与初始化
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;
}
相关推荐
liuzhijie-06145 小时前
Codeforces 2245 D2 / E / F 题解
算法
薛定e的猫咪5 小时前
在 vibe coding开发项目过程中使用过的命令和概念整理
人工智能·学习·算法·开源
麻瓜老宋5 小时前
AI开发C语言应用按步走,我的基础开发环境
c语言·开发语言
见叶之秋5 小时前
C细节补充
c语言·开发语言
Tisfy5 小时前
LeetCode 1979.找出数组的最大公约数:模拟(附手动gcd)
java·数学·算法·leetcode·题解·最大公约数
圣光SG5 小时前
Excel 函数大全
算法·excel
Lzh编程小栈5 小时前
嵌入式深度精讲|STM32引脚全方位底层原理、配置逻辑、硬件规范、高频面试题
c语言·stm32·单片机·嵌入式硬件
To_OC6 小时前
LC 79 单词搜索:都说这是回溯入门题,我却连错三回
javascript·算法·leetcode
问商十三载7 小时前
2026大模型GEO内链优化:3个传导逻辑提权重,零成本提29%收录优先级附布局表
人工智能·算法