我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C++深入分析讲解链表

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C++深入分析讲解链表

链表的概述

1、数组特点

1、空间连续、元素类型相同、通过下标快速访问

2、静态数组:空间一旦确定不能更改(动态数组除外)

3、静态、动态数组 插入删除元素 需要移动大量数据

2、链表的概述

链表是一种物理存储上非连续,数据元素的逻辑连续通过链表节点中的指针变量保存下个节点的地址,实现的一种线性存储结构。

3、链表的特点

链表由一系列节点(链表中每一个元素称为节点)组成,节点在运行时动态生成(malloc,calloc),每个节点包 括两个部分:

数据域:存放节点数据(核心)

指针域:结构体指针变量 保存下一个节点的地址

静态链表

#include <stdio.h>
//设计节点类型
typedef struct stu
{
    //数据域
    int num;
    char name[32];
    float score;
    //指针域
    struct stu *next;
}STU;
int main(int argc, char const *argv[])
{
    //静态链表的节点 不是从堆区申请
    STU node1={100, "lucy", 77.7f};
    STU node2={101, "bob", 66.7f};
    STU node3={102, "tom", 55.7f};
    STU node4={103, "hehe", 74.7f};
    STU node5={104, "xixi", 73.7f};
    //构建成链表
    STU *head = NULL;
    head = &node1;
    node1.next = &node2;
    node2.next = &node3;
    node3.next = &node4;
    node4.next = &node5;
    node5.next = NULL;
    //遍历链表(从头节点  逐个节点遍历)
    STU *pb = head;
    while(pb != NULL)
    {
        printf("%d %s %f\n", pb->num, pb->name, pb->score);
        //移动到下一个节点
        pb = pb->next;
    }
    return 0;
}

链表的操作

增、删、改、查

学生管理系统 讲解链表

1、链表插入节点

帮助信息函数:

void help(void)
{
    printf("******************************\n");
    printf("* insert:插入链表节点        *\n");
    printf("* printf:遍历链表节点        *\n");
    printf("* search:查询链表节点        *\n");
    printf("* delete:删除链表节点        *\n");
    printf("* free:释放链表节点          *\n");
    printf("* quit:遍历链表节点          *\n");
    printf("******************************\n"); 
    return; 
}

头部之前插入节点

STU* insert_link(STU *head, STU tmp)
{
    //为插入的节点申请空间
    STU *pi = (STU *)calloc(1,sizeof(STU));
    //给空间赋值
    *pi = tmp;
    pi->next = NULL;
    //判断链表是否存在
    if(NULL == head)//空
    {
        head = pi;
        //return head;
    }
    else//非空
    {
        pi->next = head;
        head = pi;
        //return head;
    }
    return head;
}

尾部之后插入节点

//尾部插入节点
STU* insert_link(STU *head, STU tmp)
{
    //为插入的节点申请空间
    STU *pi = (STU *)calloc(1,sizeof(STU));
    //给空间赋值
    *pi = tmp;
    pi->next = NULL;
    //判断链表是否存在
    if(NULL == head)
    {
        head = pi;
        return head;
    }
    else
    {
        //寻找尾部节点
        STU *pb = head;
        while(pb->next != NULL)
            pb = pb->next;
        //将pi插入到 尾节点后
        pb->next = pi;
        return head;
    }
    return head;
}

有序插入节点

//有序插入节点
STU* insert_link(STU *head, STU tmp)
{
    //为插入的节点申请空间
    STU *pi = (STU *)calloc(1,sizeof(STU));
    //给空间赋值
    *pi = tmp;
    pi->next = NULL;
    //判断链表是否存在
    if(NULL == head)
    {
        head = pi;
        return head;
    }
    else
    {
        //寻找插入点
        STU *pf = NULL, *pb = NULL;
        pf = pb = head;
        //从小--->大排序
        while((pb->num < pi->num) && (pb->next != NULL))
        {
            pf = pb;
            pb = pb->next;
        }
        if(pb->num >= pi->num)//头部插入、中部插入
        {
            if(pb == head)//头部插入
            {
                pi->next = head;
                head = pi;
            }
            else//中部插入
            {
                pf->next = pi;
                pi->next = pb;
            }
        }
        else if(pb->next == NULL)//尾部插入
        {
            pb->next = pi;
        }
    }
    return head;
}

2、遍历链表节点

void printf_link(STU *head)
{
    //1、判断链表是否存在
    if(NULL == head)
    {
        printf("链表不存在\n");
        return;
    }
    else//2、链表存在,逐个节点遍历链表
    {
        STU *pb = head;
        while(pb != NULL)
        {
            printf("%d %s %f\n", pb->num, pb->name, pb->score);
            //pb指向下一个节点
            pb = pb->next;
        }
    }
    return;
}

3、查询指定节点

STU *search_link(STU *head, char *name)
{
    //判断链表是否存在
    if(NULL == head)
    {
        printf("链表不存在\n");
        return NULL;
    }
    else//链表存在
    {
        //逐个节点查询
        STU *pb = head;
        while((strcmp(pb->name, name) != 0) && (pb->next != NULL))
        {
            pb = pb->next;
        }
        if(strcmp(pb->name, name) == 0)//找到
            return pb;
        else
        {
            printf("未找到相关节点信息\n");
            return NULL;
        }
    }
    return NULL;
}

4、删除指定节点

STU* delete_link(STU *head, char *name)
 {
     //判断链表是否存在
    if(NULL == head)
    {
        printf("链表不存在\n");
        return head;
    }
    else
    {
        STU *pf =NULL, *pb=NULL;
        pf = pb = head;
        //寻找删除点
        while((strcmp(pb->name, name) != 0) && (pb->next != NULL))
        {
            pf = pb;
            pb = pb->next;
        }
        //找到删除点
        if(strcmp(pb->name, name) == 0)
        {
            if(head == pb)//头部删除
            {
                head= head->next;
            }
            else//中尾部删除
            {
                pf->next = pb->next;
            }
            //释放pb
            if(pb != NULL)
            {
                free(pb);
                pb=NULL;
            }
        }
        else//未找到删除点
        {
            printf("未找到删除的相关节点信息\n");
        }
    }
    return head;
 }

5、释放链表

STU* free_link(STU *head)
 {
    //判断链表是否存在
    if(NULL == head)
    {
        printf("链表不存在\n");
        return head;
    }
    else//链表存在
    {
        STU *pb = head;
        while(pb != NULL)
        {
            //head纪录下一个节点的位置
            head = head->next;
            //释放pb指向的节点
            if(pb != NULL)
            {
                free(pb);
                pb = NULL;
            }
            //pb指向下一个节点
            pb=head;
        }
        printf("链表节点已经完全释放\n");
    }
    return head;
 }

6、链表的翻转

STU* reverse_link(STU *head)
 {
    //判断链表是否存在
    if(NULL == head)
    {
        printf("链表不存在\n");
        return head;
    }
    else
    {
        STU *pb = head->next;
        STU *pn = NULL;
        //将头结点指针域指向NULL
        head->next = NULL;
        //逐个节点翻转
        while(pb != NULL)
        {
            //pn纪录pb->next的节点
            pn = pb->next;
            //进行反向连接
            pb->next = head;
            //移动head到pb上
            head = pb;
            //pb指向pb的节点
            pb = pn;
        }  
    }
    return head;
 }

7、链表的排序

//选择法对链表排序
 void sort_link(STU *head)
 {
    //判断链表是否存在
    if(NULL == head)
    {
        printf("链表不存在\n");
        return;
    }
    else
    {
        STU *p_i = head, *p_j = head;//int i=0, j=0;
        while(p_i->next != NULL)//for(i=0;i<n-1; i++)
        {
            STU *p_min = p_i;//int min = i;
            p_j = p_min->next;//j=min+1
            while(p_j != NULL)//j<n
            {
                if(p_min->num > p_j->num)//if(arr[min] > arr[j])
                    p_min = p_j;//min = j;
                p_j = p_j->next;//j++
            }
            if(p_i != p_min)//if(i != min)
            {
                //整体交换
                STU tmp = *p_i;
                *p_i = *p_min;
                *p_min = tmp;
                //指针域交换
                tmp.next = p_i->next;
                p_i->next = p_min->next;
                p_min->next = tmp.next;
            }
            p_i = p_i->next;//i++
        }
    }
    return;
 }

到此这篇关于C++深入分析讲解链表的文章就介绍到这了,更多相关C++链表内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C++深入分析讲解链表

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Golangsync.Map原理深入分析讲解

go中map数据结构不是线程安全的,即多个goroutine同时操作一个map,则会报错,因此go1.9之后诞生了sync.Map,sync.Map思路来自java的ConcurrentHashMap
2022-12-17

深入浅析Java中的链表

本篇文章为大家展示了深入浅析Java中的链表,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。单链表:insertFirst:在表头插入一个新的链接点,时间复杂度为O(1)deleteFirst:删除表
2023-05-31

ReactHooks核心原理深入分析讲解

这篇文章主要介绍了reacthooks实现原理,文中给大家介绍了useStatedispatch函数如何与其使用的FunctionComponent进行绑定,节后实例代码给大家介绍的非常详细,需要的朋友可以参考下
2022-12-17

Android权限机制深入分析讲解

Android的权限管理遵循的是“最小特权原则”,即所有的Android应用程序都被赋予了最小权限。一个Android应用程序如果没有声明任何权限,就没有任何特权
2022-12-08

Python魔术方法深入分析讲解

所谓魔法函数(MagicMethods),是Python的⼀种⾼级语法,允许你在类中⾃定义函数(函数名格式⼀般为__xx__),并绑定到类的特殊⽅法中。⽐如在类A中⾃定义__str__()函数,则在调⽤str(A())时,会⾃动调⽤__str__()函数,并返回相应的结果
2023-02-08

AndroidView的事件分发机制深入分析讲解

事件分发从手指触摸屏幕开始,即产生了触摸信息,被底层系统捕获后会传递给Android的输入系统服务IMS,通过Binder把消息发送到activity,activity会通过phoneWindow、DecorView最终发送给ViewGroup。这里就直接分析ViewGroup的事件分发
2023-01-29

RocketMq深入分析讲解两种削峰方式

当上游调用下游服务速率高于下游服务接口QPS时,那么如果不对调用速率进行控制,那么会发生很多失败请求,通过消息队列的削峰方法有两种,这篇文章主要介绍了RocketMq深入分析讲解两种削峰方式
2023-01-28

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录