C语言数据结构

news2025/5/24 6:54:38

单链表

头文件:lin.h

#ifndef __LINK_H__
#define __LINK_H__

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

typedef int DataType;

/*节点数据类型*/
typedef struct node
{
    DataType data;              //数据域
    struct node *pNext;         //指针域
}LinkNode;

/* 标签数据类型 */
typedef struct list
{
    LinkNode *pHead;           //链表头节点指针
    int cLen;                  //当前链表节点个数
}LinkList;

#endif

源文件:link.c

#include "link.h"

创建一个新节点:
LinkList *createLinkList()
{
    LinkList *pList = NULL;

    pList = malloc(sizeof(LinkList));
    if (NULL == pList)
    {
        perror("fail to malloc");
        return NULL;
    }
    pList->pHead = NULL;
    pList->cLen = 0;

    return pList;
}

头插:
int insertHeadLinkList(LinkList *pList, DataType data)
{
    LinkNode * pInsertNode = malloc(sizeof(LinkNode));
    if (NULL == pInsertNode)
    {
        perror("fail to malloc");
        return -1;
    }
    pInsertNode->data = data;

    pInsertNode->pNext = pList->pHead;
    pList->pHead = pInsertNode;
    pList->cLen++;

    return 0;
}

遍历:

void showLinkList(LinkList *pList)
{
    LinkNode *pTmpNode = pList->pHead;

    while (pTmpNode != NULL)
    {
        printf("%d ", pTmpNode->data);
        pTmpNode = pTmpNode->pNext;
    }
    printf("\n");

}

判空:

int isEmptyLinkList(LinkList *pList)
{
    return pList->cLen == 0;
}

尾插:
int insertTailLinkList(LinkList *pList, DataType data)
{
    LinkNode *pInsertNode = malloc(sizeof(LinkNode));
    if (NULL == pInsertNode)
    {
        perror("fail to malloc");
        return -1;
    }
    pInsertNode->data = data;
    pInsertNode->pNext = NULL;

    if (isEmptyLinkList(pList))
    {
        pList->pHead = pInsertNode;
    }
    else
    {
        LinkNode *pTmpNode = pList->pHead;
        while (pTmpNode->pNext != NULL)
        {
            pTmpNode = pTmpNode->pNext;
        }
        pTmpNode->pNext = pInsertNode;
    }
    pList->cLen++;

    return 0;
}

头删:

int deleteHeadLinkList(LinkList *pList)
{
    if (isEmptyLinkList(pList))
    {
        return 0;
    }

    LinkNode *pFreeNode = pList->pHead;
    pList->pHead = pFreeNode->pNext;
    free(pFreeNode);
    pList->cLen--;

    return 0;
}

尾删:

int deleteTailLinkList(LinkList *pList)
{
    if (isEmptyLinkList(pList))
    {
        return 0;
    }
    else if (1 == pList->cLen)
    {
        deleteHeadLinkList(pList);
    }
    else
    {
        LinkNode *pTmpNode = pList->pHead;
        while (pTmpNode->pNext->pNext != NULL)
        {
            pTmpNode = pTmpNode->pNext;
        }
        free(pTmpNode->pNext);
        pTmpNode->pNext = NULL;
        pList->cLen--;
    }

    return 0;
}

查找单链表的某个节点:

LinkNode *findLinkList(LinkList *pList, DataType findData)
{
    LinkNode *pTmpNode = pList->pHead;

    while (pTmpNode != NULL)
    {
        if (pTmpNode->data == findData)
        {
            return pTmpNode;
        }
        pTmpNode = pTmpNode->pNext;
    }

    return NULL;
}

单链表反转:

int reverseLinkList(LinkList *pList, DataType oldData, DataType newData)
{
    LinkNode *pTmpNode = NULL;
    while ((pTmpNode = findLinkList(pList, oldData)) != NULL)
    {
        pTmpNode->data = newData;
    }
    
    return 0;
}

销毁链表:

void destroyLinkList(LinkList **ppList)
{
    while ((*ppList)->pHead != NULL)
    {
        deleteHeadLinkList(*ppList);
    }
    free(*ppList);
    *ppList = NULL;

}


LinkNode *findMidLinkNode(LinkList *pList)
{
    LinkNode *pFast = pList->pHead;
    LinkNode *pSlow = pFast;

    while (pFast != NULL)
    {
        pFast = pFast->pNext;
        if (NULL == pFast)
        {
            break;
        }
        pFast = pFast->pNext;
        pSlow = pSlow->pNext;
    }

    return pSlow;
}

LinkNode *findLastKNode(LinkList *pList, int K)
{
    LinkNode *pFast = pList->pHead;
    LinkNode *pSlow = pFast;
    int i = 0;
    for (; i < K; i++)
    {
        pFast = pFast->pNext;
    }
    while (pFast != NULL)
    {
        pFast = pFast->pNext;
        pSlow = pSlow->pNext;
    }

    return pSlow;
}

int deletePointNode(LinkList *pList, DataType deleteData)
{
    LinkNode *pPreNode = pList->pHead;
    LinkNode *pFreeNode = pList->pHead;

    while (pFreeNode != NULL)
    {
        if (pFreeNode->data == deleteData)
        {
            if (pPreNode == pFreeNode)
            {
                pList->pHead = pFreeNode->pNext;
                free(pFreeNode);
                pPreNode = pList->pHead;
                pFreeNode = pList->pHead;
            }
            else
            {
                pPreNode->pNext = pFreeNode->pNext;
                free(pFreeNode);
                pFreeNode = pPreNode->pNext;
            }
            pList->cLen--;
        }
        else
        {
            pPreNode = pFreeNode;
            pFreeNode = pFreeNode->pNext;
        }
    }

    return 1;
}

void invertLinkList(LinkList *pList)
{
    LinkNode *pTmpNode = pList->pHead;
    LinkNode *pInsertNode = NULL;
    
    pList->pHead = NULL;
    while (pTmpNode != NULL)
    {
        pInsertNode = pTmpNode;
        pTmpNode = pTmpNode->pNext;
        
        pInsertNode->pNext = pList->pHead;
        pList->pHead = pInsertNode;
    }
    
    return ;
}

链表排序:

void sortLinkList(LinkList *pList)
{
    //链表为空或只有一个节点不需要排序
    if (isEmptyLinkList(pList) || 1 == pList->cLen)
    {
        return ;
    }
    //保存第二个节点并且从第一个节点后断开
    LinkNode *pInsertNode = NULL;
    LinkNode *pTmpNode = pList->pHead->pNext;
    pList->pHead->pNext = NULL;

    while (pTmpNode != NULL)
    {
        //找到要插入的节点
        pInsertNode = pTmpNode;
        pTmpNode = pTmpNode->pNext;

        //判断是否需要头插
        if (pInsertNode->data < pList->pHead->data)
        {
            //头插
            pInsertNode->pNext = pList->pHead;
            pList->pHead = pInsertNode;
        }
        else
        {
            //寻找插入位置
            LinkNode *p = pList->pHead;
            while (p->pNext != NULL && p->pNext->data < pInsertNode->data)
            {
                p = p->pNext;
            }
            //节点插入
            pInsertNode->pNext = p->pNext;
            p->pNext = pInsertNode;
        }
    }
}

int isLoopLinkList(LinkList *pList)
{
    LinkNode *pFast = pList->pHead;
    LinkNode *pSlow = pList->pHead;

    while (pFast != NULL)
    {
        pFast = pFast->pNext;
        if (NULL == pFast)
        {
            return 0;
        }
        if (pSlow == pFast)
        {
            return 1;
        }
        pFast = pFast->pNext;
        pSlow = pSlow->pNext;
        if (pFast == pSlow)
        {
            return 1;
        }
    }
}
int main(int argc, const char *argv[])
{
    LinkList *pList = NULL;
    LinkNode *pTmpNode = NULL;

    pList = createLinkList();

//    insertHeadLinkList(pList, 1);
    insertHeadLinkList(pList, 2);
    insertHeadLinkList(pList, 3);
    insertHeadLinkList(pList, 4);

    insertTailLinkList(pList, 5);
    insertTailLinkList(pList, 3);
    insertTailLinkList(pList, 3);
    insertTailLinkList(pList, 3);
    insertTailLinkList(pList, 3);
    insertTailLinkList(pList, 3);
    insertTailLinkList(pList, 3);


    showLinkList(pList);
#if 0
    deleteHeadLinkList(pList);

    deleteTailLinkList(pList);

    showLinkList(pList);

    pTmpNode = findLinkList(pList, 3);
    if (pTmpNode != NULL)
    {
        printf("find %d\n", pTmpNode->data);
    }
    else
    {
        printf("not find\n");
    }

    reverseLinkList(pList, 3, 10);
    showLinkList(pList);
#endif
    
    pTmpNode = findMidLinkNode(pList);
    printf("mid node = %d\n", pTmpNode->data);

    pTmpNode = findLastKNode(pList, 3);
    printf("last K node = %d\n", pTmpNode->data);
#if 0    
    deletePointNode(pList, 3);
    showLinkList(pList);
    
    invertLinkList(pList);
    showLinkList(pList);

    sortLinkList(pList);
    showLinkList(pList);

//    destroyLinkList(&pList);
#endif

    //构造环形链表
    pTmpNode = pList->pHead;
    while (pTmpNode->pNext != NULL)
    {
        pTmpNode = pTmpNode->pNext;
    }
    pTmpNode->pNext = pList->pHead->pNext->pNext->pNext->pNext;

    if (isLoopLinkList(pList))
    {
        printf("is loop link.\n");
    }
    else
    {
        printf("is not loop link.\n");
    }

    return 0;
}
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2384426.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

精度再升级,可到微米!单位自动换算平米和米

CAD图纸单位怎么看&#xff1f;精度怎么调&#xff1f; 长度测出来是什么单位&#xff1f; 面积一大串怎么回事&#xff1f; 坐标小数点位置不对怎么办&#xff1f; 点击直接获取CAD快速看图 首先说原理 CAD图纸在绘制时&#xff0c;一般情况下单位是&#xff1a; 长度---…

常见算法题目2 - 给定一个字符串,找出其中最长的不重复子串

算法题目2 - 给定一个字符串&#xff0c;找出其中最长的不重复子串 1. 问题描述 给定一个字符串&#xff0c;输出其最长的不重复子串&#xff0c;例如&#xff1a; String str "ababc"; 输出&#xff1a; abc以下根据两种搜索算法。 2. 算法解决 2.1 暴力循环法…

如何配置jmeter做分布式压测

问&#xff1a;为何需要做分布式 答&#xff1a;当我们本地机器jmeter进行压测时&#xff0c;单台JMeter机器通常无法稳定生成2000 QPS&#xff08;受限于CPU、内存、网络带宽&#xff09;&#xff0c;本地端口耗尽&#xff1a;操作系统可用的临时端口&#xff08;Ephemeral P…

Django 中的 ORM 基础语法

深入剖析 Django 中的 ORM 语法&#xff1a;从基础到实战进阶 在 Django 开发领域&#xff0c;ORM&#xff08;对象关系映射&#xff09;是开发者高效操作数据库的得力工具。它以简洁直观的 Python 代码&#xff0c;替代繁琐的 SQL 语句&#xff0c;极大提升了开发效率。本文将…

【计算机网络】TCP如何保障传输可靠性_笔记

文章目录 一、传输可靠性的6方面保障二、分段机制三、超时重传机制四、流量控制五、拥塞控制 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 源网站 按TCP/IP 4层体系&#xff0c;TCP位于传输层&#xff0c;为应用层提供服务 一、传输可靠性的6方面保障…

html主题切换小demo

主题切换功能为网页和应用程序提供了多样化的视觉风格与使用体验。实现多主题切换的技术方案丰富多样&#xff0c;其中 CSS 变量和 JavaScript 样式控制是较为常见的实现方式。 以下是一个简洁的多主题切换示例&#xff0c;愿它能为您的编程之旅增添一份趣味。 代码展示 <…

AI架构职责分配——支持AI模块的职责边界设计

职责分配——支持AI模块的职责边界设计 在传统系统中&#xff0c;职责分配通常围绕“控制层处理逻辑、服务层执行业务、数据层持久化”进行划分。这种分工逻辑在纯业务系统中足以支撑高效协作与系统演进。然而&#xff0c;随着AI模块的引入&#xff0c;系统中新增了如模型推理…

CARIS HIPS and SIPS 12.1是专业的多波束水深数据和声呐图像处理软件

CARIS HIPS 和 SIPS 是一套综合水文处理软件&#xff0c;主要用于海洋水道处理和测量领域‌。该软件集成了测深、水柱和海底图像处理功能&#xff0c;能够提高业务处理的精确度和效率‌。 主要功能和应用场景 ‌测深数据处理‌&#xff1a;HIPS主要用于处理大型测深数据。 ‌…

在 Ubuntu 24.04 LTS 上 Docker 部署 DB-GPT

一、DB-GPT 简介 DB-GPT 是一个开源的AI原生数据应用开发框架(AI Native Data App Development framework with AWEL(Agentic Workflow Expression Language) and Agents)。目的是构建大模型领域的基础设施&#xff0c;通过开发多模型管理(SMMF)、Text2SQL效果优化、RAG框架以及…

Axure高保真CRM客户关系管理系统原型

一套出色的CRM&#xff08;客户关系管理&#xff09;系统&#xff0c;无疑是企业管理者掌控客户动态、提升销售业绩的得力助手。今天&#xff0c;就为大家介绍一款精心打造的Axure高保真CRM客户关系管理系统原型模板&#xff0c;助你轻松开启高效客户管理之旅。 这款CRM原型模…

自学嵌入式 day 23 - 数据结构 树状结构 哈希表

一、树状结构 1.特征&#xff1a;在任意一个非空树中&#xff0c; &#xff08;1&#xff09;&#xff0c;有且仅有一个特定的根结点 &#xff08;2&#xff09;&#xff0c;当n>1 时&#xff0c;其余结点可分为m个互不相交的有限集合T1,T2,T3.。。。。Tm&…

JavaScript进阶(十二)

第三部分:JavaScript进阶 目录 第三部分:JavaScript进阶 十二、深浅拷贝 12.1 浅拷贝 12.2 深拷贝 1. 通过递归实现深拷贝 2. js库lodash里面cloneDeep内部实现了深拷贝 3. 通过JSON.stringify()实现 十三、异常处理 13.1 throw抛异常 13.2 try /catch捕获异常 1…

中文域名25周年,取得哪些里程碑式的进展?

二十五载中文域名路 第八届中文域名创新应用论坛在北京举办。与会领导专家回顾了中文域名发展历史&#xff0c;深入探讨了当下面临的机遇与挑战&#xff0c;并展望了未来的发展。 自2000年中国推出全球首个中文域名试验系统以来&#xff0c;中文域名已走过25年历程&#xff0c…

应对进行性核上性麻痹,健康护理铸就温暖防线

进行性核上性麻痹&#xff08;PSP&#xff09;是一种罕见的神经退行性疾病&#xff0c;主要影响患者的运动、平衡及吞咽等功能。针对这类患者&#xff0c;有效的健康护理对提升其生活质量、延缓病情发展至关重要。 在日常生活护理方面&#xff0c;由于患者存在平衡障碍和肌肉僵…

python邮件地址检验 2024年信息素养大赛复赛/决赛真题 小学组/初中组 python编程挑战赛 真题详细解析

python邮件地址检验 2024全国青少年信息素养大赛Python编程挑战赛复赛真题解析 博主推荐 所有考级比赛学习相关资料合集【推荐收藏】 1、Python比赛 信息素养大赛Python编程挑战赛 蓝桥杯python选拔赛真题详解 蓝桥杯python省赛真题详解 蓝桥杯python国赛真题详解 2、…

CAD球体功能梯度材料3D插件

插件介绍 CAD球体功能梯度材料3D插件可在AutoCAD内建立大小呈现梯度分布的球体及长方体孔隙三维模型。 功能梯度材料&#xff08;FGM&#xff09;模型包含大小梯度变化的球体及与之适配的长方体部件&#xff0c;可用于球体材料的梯度分布或梯度多孔结构材料建模。 插件支持…

自制操作系统day9内存管理(cache、位图、列表管理、内存的释放)(ai辅助整理)

day9内存管理 整理源文件&#xff08;harib06a&#xff09; 残留问题&#xff1a;鼠标指针的叠加处理不太顺利&#xff0c;以后处理 先介绍cache&#xff08;高速缓存&#xff09; 每次访问内存&#xff0c;都将所访问的地址和内容存入高速缓存&#xff0c; 往内存里写入数据…

JavaWebsocket-demo

Websocket客户端 pom依赖 <dependency><groupId>org.java-websocket</groupId><artifactId>Java-WebSocket</artifactId><version>1.4.0</version></dependency>客户端代码片段 Component Slf4j public class PositionAlarmL…

特征学习:赋予机器学习 “慧眼” 的核心技术

一、特征学习&#xff1a;从人工设计到智能发现的范式革新 1.1 核心定义与价值 特征学习的本质是让机器模仿人类大脑的认知过程 —— 例如&#xff0c;人类视觉系统通过视网膜→视神经→大脑皮层的层级处理&#xff0c;从像素中识别物体&#xff1b;特征学习则通过神经网络的卷…

3D个人简历网站 7.联系我

3D个人简历网站 7.联系我 修改Contact.jsx // 从 react 库导入 useRef 和 useState hooks import { useRef, useState } from "react";/*** Contact 组件&#xff0c;用于展示联系表单&#xff0c;处理用户表单输入和提交。* returns {JSX.Element} 包含联系表单的 …