C语言之链表操作

概述

单链表是一种数据结构,每个节点包含数据域和指向下一节点的指针域,只能单向依次访问节点。

双链表同样是数据结构,其节点除数据域外,还有指向前驱和后继节点的两个指针域,可双向遍历访问节点。

定义节点

一个节点就是一个结构体变量

1,单链表节点

        typedef struct node

        {

                //数据域

                int num;

                char c;

                //地址域

                struct node *next;

        }Node;

2,双链表节点

       

typedef struct node

        {

                //数据域

                int num;

                char c;

                //地址域

                struct node *next;

                struct node *head;

        }Node;

创建链表

静态创建

//静态组建链表
#include<stdio.h>

typedef struct node
{
    //数据域
    int num;
    //地址域
    struct node *next;
    struct node *head;
}Node;

//链表的遍历
void printf_link(Node *head)
{
    Node *n = head;
    while(1)
    {
        printf("%d\n",n->num);
        if(n->next==NULL)
        {
            break;
        }
        n=n->next;
    }
}

int main()
{
    Node n01 = {1,NULL,NULL};
    Node n02 = {2,NULL,NULL};
    Node n03 = {3,NULL,NULL};
    n01.next=&n02;
    n02.next=&n03;
    n03.head=&n02;
    n02.head=&n01;
    
    printf_link(&n01);

    return 0;
}

动态创建

//动态创建链表
#include<stdio.h>
#include<stdlib.h>

typedef struct node
{
    //数据域
    int num;
    //地址域
    struct node *next;
    struct node *head;
}Node;

void printf_link(Node *head)
{
    Node *n = head;
    while(1)
    {
        printf("%d\n",n->num);
        if(n->next==NULL)
        {
            break;
        }
        n=n->next;
    }
}

int main()
{
    Node*n01=(Node*)calloc(1,sizeof(Node));
    Node*n02=(Node*)calloc(1,sizeof(Node));
    Node*n03=(Node*)calloc(1,sizeof(Node));
    Node*n04=(Node*)calloc(1,sizeof(Node));
    n01->head = NULL;
    n01->next = n02;
    n02->next = n03;
    n03->next = n04;
    n04->next = NULL;
    n04->head = n03;
    n03->head = n02;
    n02->head = n01;

    n01->num = 4;
    n02->num = 3;
    n03->num = 2;
    n04->num = 1;

    printf_link(n01);
    return 0;
}

链表的操作

添加

//在链表尾部添加节点

//head:链表的首节点

Node* add_node(Node *head,Node *newNode)

{

        //判断是否有首节点

        if(head == NULL)

        {

                //没有首节点,那么本次添加的节点就是首节点

                head = newNode;

                return head;

        }

        //有首节点,查找当前链表的最后一个节点

        Node *n = head;

        while(n->next !=NULL)

        {

                n=n->next;

        }

        //当循环结束后n就是最后一个节点

        n->next = newNode;

        //将新节点的上一个节点设置为原来的最后一个节点

        newNode->head = n;

        return head;

}

遍历

//遍历链表

//head:要遍历的链表的首节点

void printf_link(Node *head)

{

        Node *n = head;

        //判断当前节点是否为NULL

        while(n != NULL)

        {

                //当前节点不为空,打印其数据

                printf("%d\n",n->num)

                //移动当前节点到下一个节点

                n=n->next;

        }

}

删除

//删除指定节点

//head:头节点,delNode:要删除的节点

Node* del_node(Node *head,Node *delNode)

{

        if(head ==NULL)

        {

                printf("没有首节点\n");

                return NULL;

        }

        if(delNode == NULL)

        {

                printf("要删除的节点为NULL\n");

                return head;

        }

        if(head == delNode)

        {

                //要删除的节点为首节点,将下一个节点设为首节点

                head=head->next;

                //将当前的首节点的前驱置空

                head->head = NULL;

                //释放原来的首节点

                free(delNode);

                return head;

        }

        //要删除的节点不是首节点和尾节点时

        Node *n = head;

        while(n!=delNode && n!=NULL)

        {

                n=n->next;

        }

        if(n == NULL)

        {

                printf("没有要删除的节点\n");

                return head;

        }

        //如果要删除的节点为最后一个节点

        if(n->next == NULL)

        {

                Node *headNode = n->head;

                headNode->next = NULL;

                free(n)

                return head;

        }

        //当n为要删除的节点时

        Node*headNode = n->head;//取出n的上一个节点

        Node*nextNode = n->next;//取出n的下一个节点

        free(n);释放n

        headNode->next = nextNode;

        headNode->head = headNode;

        return head;

}

查找

按值查找

//按结构体中存储的值查找对应的节点

//head:首节点 num:查找的值

Node *find_v(Node *head,int num)

{

        Node *n =head;

        while(n !=NULL)

        {

                if(n->num == num)

                {

                        return n;

                }

                 n=n->next;

        }

        return NULL;

}

按位查找

//按结构体在链表中的位置查找对应的节点

//head:首节点 index:下标

//注意:链表本身没有下标的概念

Node* find-i(Node *head,int index)

{

        Node *n = head;

        int i=0;

        while(n!=NULL)

        {

                if(i == index)

                {

                        return n;

                }

                n = n->next;

                i++;

        }

        return NULL;

}

修改

按值修改

//根据值修改指定节点的值

//head:首节点,num:查找的值,newNum:修改后的值

void updata_v(Node *head,int num,int newNum)

{

        Node *n = find_v(head,num);

        if(n == NULL)

                return;

        n->num = newNum;

}

按位查找

//根据位置修改指定节点的值

//head:首节点,index:修改后的位置,newNum:修改后的值

void updata_i(Node *head,int index,int newNum)

{

        Node *n = find_i(head,index);

        if(n ==NULL)

                return;

        n->num = newNum;

}

插入

//按位插入新节点

//head:首节点,index:位置,newNode:新节点

Node* insert(Node *head,int index,Node *newNode)

{

        if(index == 0)

        {

                newNode->next = head;

                head->head = newNode;

                head = newNode;

                //将链表的头指针 head 指向新插入的节点 newNode

                return head;

        }

       

        Node *n = find_i(head,index);

        //当插入节点是尾节点

        if(n == NULL)

        {

                add_node(head,newNode);

                return head;

        }

        Node *headNode = n->head;

        headNode->next = newNode;

        newNode->head = headNode;

        

        newNode->next = n;

        n->head = newNode;

        return head;

}

获取链表长度

//获取链表长度

int get_len(len *head)

{

        int i = 0;

        Node *n = head;

        while(n !=NULL)

        {

                i++;

                n=n->next;

        }

        return i;

}

逆序排序

void printf_link(Node *head)

{

        int len = get_len(head);

        int index = len -1;

        Node *n = (head,index);

                while(n !=NULL)
                {

                        printf("%d\n",n->num);

                        n = n->head;

                }

}

释放链表

void free_link(Node *head)

{

        Node *n = head;

        while(n != NULL)
        {

                Node *nextNode = n->next;

                free(n);

                n=nextNode;

        }

}

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

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

相关文章

python 编程 在 Matplotlib 中 默认预定的所有颜色,可以使用多种方法来指定颜色,包括预定义的颜色名称、十六进制颜色代码、

在 Matplotlib 中&#xff0c;可以使用多种方法来指定颜色&#xff0c;包括预定义的颜色名称、十六进制颜色代码、RGB 元组等。如果你想要一个比较深的颜色&#xff0c;你可以选择一些预定义的深色名称&#xff0c;或者使用较低的亮度值来定义自己的颜色。 以下是一些预定义的…

【基于Java Springboot敬老院管理系统

一、作品包含 源码数据库设计文档万字全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据库…

JRebel插件,全教程

JRebel是一套JavaEE开发工具。相信大家都用过&#xff0c;但是频繁的需要激活&#xff0c;已经让java开发者烦不胜烦。 本篇文章来给大家解决这个烦恼。当然没有用过的同行&#xff0c;我也跟大家介绍一下: 简单来说&#xff0c;Jrebel 可快速实现热部署&#xff0c;在本地开发…

PPPoE技术详解

一 &#xff0c; 背景 随着运营商对宽带接入技术要求的不断提高&#xff0c;以xDSL&#xff0c;CableModem和以太网为主的几种宽带接入技术在用户管理和计费等方面的不足开始显露&#xff0c;已无法满足运营商的需求。 在众多的技术中&#xff0c;以太网接入方式经济实惠&…

[JAVA]MyBatis环境配置介绍

什么是MyBatis环境配置&#xff1f; MyBatis是基于JDBC对数据库进行操作&#xff0c;在我们进行数据操作时&#xff0c;我们需要告诉MyBatis我们连接哪个数据库&#xff0c;ip地址&#xff0c;数据库名称&#xff0c;用户名密码等。以此来进行环境配置。 首先&#xff0c;MyB…

Javascirpt时区——脱坑指南

最近业务反馈了一个约课功能的问题&#xff0c;澳大利亚的用户反馈&#xff0c;无法进行选课。排查之后发现是时区不对引起的&#xff0c;由于时区的偏差已经超过时间&#xff0c;导致无法选课。 这里对js中处理时区的问题做一些总结。 时区 时区&#xff08;Time Zone&#xf…

不用来回切换,一个界面管理多个微信

你是不是也有多个微信号需要管理&#xff1f; 是不是也觉得频繁切换账号很麻烦&#xff1f; 是不是也想提升多账号管理的效率&#xff1f; 在工作中&#xff0c;好的辅助工具&#xff0c;能让我们的效率加倍增长&#xff01; 今天&#xff0c; 就给大家分享一个多微管理工具…

每日OJ题_牛客_AB32【模板】哈夫曼编码_C++_Java

目录 牛客_AB32【模板】哈夫曼编码 题目解析 C代码 Java代码 牛客_AB32【模板】哈夫曼编码 【模板】哈夫曼编码_牛客题霸_牛客网 描述&#xff1a; 给出一个有n种字符组成的字符串&#xff0c;其中第ii种字符出现的次数为ai​。请你对该字符串应用哈夫曼编码&#xff0c;…

UDP协议

​ UDP协议 前置知识一、应用层的进程为什么要bind端口号二、如何确定网络中的一个进程三、进程 服务 协议 端口之间的关系四、常见的协议对应的端口五、一些命令六、一个进程能不能绑定多个端口号&#xff0c;一个端口号能不能被多个进程绑定七、对任何一个协议报文的认识 UD…

KkFileView4.1.0部署文档--linux

先看下官方文档&#xff1a;kkFileView - 在线文件预览 环境要求中的JDK8如果没有的&#xff0c;需先安装JDK8&#xff0c;这里不做展示。 第二个office相关环境要求在linux中会自动下载安装&#xff0c;不用管。 1、下载地址 Linux 或 MacOS 版&#xff1a; https://kkfil…

[论文笔记]An LLM Compiler for Parallel Function Calling

引言 今天带来一篇优化函数调用的论文笔记——An LLM Compiler for Parallel Function Calling。 为了简单&#xff0c;下文中以翻译的口吻记录&#xff0c;比如替换"作者"为"我们"。 当前的函数(工具)调用方法通常需要对每个函数进行顺序推理和操作&…

基于JAVA的资源检索系统(源码+定制+开发)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

展望:多模态融合与marker推断

技术进步使得利用高维、高通量、多尺度的生物医学数据从多个角度研究患者和疾病成为可能。在肿瘤学中&#xff0c;正在生成大量数据&#xff0c;从分子、组织病理学到临床记录。深度学习的引入极大地促进了生物医学数据的分析。然而&#xff0c;大多数方法都侧重于单一模态&…

AI在电商平台中的创新应用:提升销售效率与用户体验的数字化转型

1. 引言 AI技术在电商平台的应用已不仅仅停留在基础的数据分析和自动化推荐上。随着人工智能的迅速发展&#xff0c;越来越多的电商平台开始将AI技术深度融合到用户体验、定价策略、供应链优化、客户服务等核心业务中&#xff0c;从而显著提升运营效率和用户满意度。在这篇文章…

基于Java Springboot餐厅点餐系统(加入商家版)

一、作品包含 源码数据库设计文档万字全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA 数据库&#xff1a;MySQL5.7…

NeRF在农业领域的应用-------------(1)

一、Exploring Accurate 3D Phenotyping in Greenhouse through Neural Radiance Fields&#xff08;通过神经辐射场探索温室中精确的三维表型分析&#xff09; 1.摘要 在精准农业中&#xff0c;准确收集植物表型对于优化可持续农业实践至关重要。 在受控实验室环境中进行的传…

pico-sdk(零)

pico-sdk&#xff08;零&#xff09; 项目概述license相关文档 依赖三方库链接 项目概述 Raspberry Pi Pico SDK&#xff08;以下简称 SDK&#xff09;提供了为 RP 系列微控制器设备&#xff08;如 Raspberry Pi Pico 或 Raspberry Pi Pico 2&#xff09;编写 C、C 或汇编语言…

基于java+SpringBoot+Vue的视频网站系统设计与实现

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis Maven mysql5.7或8.0等等组成&#x…

vue注册全局组件,其他地方可以直接方便的调用

文章目录 问题注册全局组件完结 问题 本来我们想使用某个组件&#xff0c;需要在各个地方引入对应的参数&#xff0c;并配置好components内容&#xff0c;才可以使用 但是随着用的越来越多&#xff0c;这种方法变得重复且易出错 注册全局组件 修改main.js文件&#xff0c;放…

javaScript交互补充(元素的三大系列)

1、元素的三大系列 1.1、offset系列 1.1.1、offset初相识 使用offset系列相关属性可以动态的得到该元素的位置&#xff08;偏移&#xff09;、大小等 获得元素距离带有定位祖先元素的位置获得元素自身的大小&#xff08;宽度高度&#xff09;注意&#xff1a;返回的数值都不…