C++关于链表基础知识

news2024/10/7 9:14:08

单链表

// 结点的定义

template <class T>

struct Node 

{

        T data ;

        Node <T> *next;   //指向下一个node 的类型与本node相同

}

// 最后一个node指针指向Null

 生成结点:  Node <T> * p =  new Node < T>;

为结点赋值:       p-> data = 'a';

                        p- > next = (其他结点的地址);  p -> next = NULL ; (尾结点)

                        delete p; //释放结点

// 单链表的类实现

template <class T> 

class LinkList

{

public :    //此处是函数定义

        LinkList();   

        ListList(T a[ ] , int n);

        int Lenght(); 

        T Get(int);  //俺下标查找

        int Loate(T); //按值定位

        void insert(T,int);  //插入

        T delete (int) ;  //删除

        ~LinkList();  

private:

        Node <T> * first;      

}

构造函数的实现一个空链表:

template <class T>
LinkList <T> :: LinkList()
{
    first = new Node <T>;    
    first->next = NULL;           
}

头插法

初始化头节点(头节点指的是first,首结点代表链表第一个结点)

template <class T>
LinkList <T> :: LinkList (T a[ ] ,int n)
{
    //初始化头节点
    first = new Node<T>;
    first ->next =NULL;
    for (int i =0 ; i<n ;i++)
    {
        //生成新的结点
        Node <T> *s = new Node <T>;
        s ->data =a [i]; 
        
        //链接再头节点和首结点之间
        s->next = first ->next;
        first ->next = s ;
    }
}

核心代码:

        s->next = first ->next;
        first ->next = s ;

因为对于first ->next的初始化指向是NULL;此处赋值给s->next则表示了s->next指向了NULL

然后将地址s赋值给了first ->next(头节点的地址域)

尾插法

template <class T>
LinkList <T> :: LinkList (T a[ ] ,int n)
{
    //初始化头节点
    Node<T> *first = new Node<T>;
    Node<T> *r = first;    //尾结点首先指向first
    for (int i =0 ; i<n ;i++)
    {
        //生成新的结点
        Node <T> *s = new Node <T>;
        s ->data =a [i];
        s ->next =NULL;   //由于是尾插,直接指向NULL 
        
        //链接在尾结点后面:
        r->next = s;
        //尾结点后移,由于此时的新的结点s是尾结点
        r= s;
    }
    //这里也可以加一句r->next = NULL;
}

  析构函数: 

template <class T>
LinkList <T> :: ~linkList
{
    while (first != NULL)   //或者直接while(first)
    {
        Node <T> *p = first;
        first = first->next;
        delete p; 
    }
}

按照值查找: 

查找值为x的结点的位置

顺序查找:

template <class T>
int LinkList <T> :: locate (T x)  // T类型的x
{
    Node<T> *p = first->next ;//首结点后的第一个结点
    int j=1;
    while(p)   //p不为空一直循环,p为NULL的时候即循环到结尾

    {
        if(p->data ==x ) return j;
        p = p->next ;
        j++;
    }
    return 0;
}

 按照值查找返回结点 ,非模板类实现:


Node * LinkList:: local (int val )
{
    Node* p = first;
    while (p )
    {
        if (p ->data == val)
        {
            return p;
        }
        p = p -> next;
    }
    return NULL;
}

按下标查找:

template <class T>
T LinkList <T> :: Get (int i){
//初始化
    Node<T> * p = first ->next ;
    int j =1;
    while(j<i && p!=NULL)  
    {
        p= p->next
        j++;
    }
    if(p==NULL || i<1) throw"位置非法";
    return p->data ;
}

随意位置插入:

思路:

新建结点 Node<T> *s = new Node <T>;   s->data = x;   

插入 : s ->next = p->next ;         (p->next 的值是ai的地址,将其赋值给新节点地址域)

             p->next =s ;

//将值为x的结点插入到位置为i的结点,那么首先要找到i-1 号结点
template <class T>
void LinkList <T> :: Insert (T x , int i)
{
    Node <T> * p = first ; 
    int j = 0 ;
    while (p && j<i-1)
    {
        p = p->next ; 
        j++;
    }
    if (p == NULL) throw "插入位置非法"
    else {
    // 新建结点 
       Node<T> *s = new Node <T>;
       s->data = x;      
    //插入
       s ->next = p->next ; 
       p->next =s ;
    }
}

在指定结点后插入:

//在指定的p结点之后插入
template <class T>
void LinkList <T> :: insertAfter (Node<T> * p , T x )
{
    Node <T> *s =  new Node <T>;
    s -> data =x ;
    s->next = p->next; 
    p- next = s ;
}

//在指定的p结点之前插入
//需要先找到p结点的前面一个结点q ,循环来找
template <class T>
void ListList <T> ::insertBefore (Node<T>  * p ,T x )
{
    Node <T> *q = first ; //从头节点开始找
    while (q ->next != p ){   // 找到q结点的条件
       q =q->next ; 
    }
    insertAfter (q,x);  //在q后插入,等于在p前插入
}
//上述方法时间复杂度是O(n)
//下列实现时间复杂度是O(1)
template <class T>
void LinkList <T> :: insertBefore (Node <T> * p ,T x)
{
    Node <T> *s = new Node<T>;
    * s = *p ;
    p ->next = s;    //将原来的p结点当成新插入的结点,把新的结点变为p结点放在后面
    p ->data = x;    // 等同于前插
}

结点删除:

首先需要把ai代表的结点摘除,使用s 表示:
        s = p->next ;

        p->next = s -> next ;

然后删除结点:

        delete s ;

template <class T>
T LinkList <T> ::  detele (int i)
{
    Node <T> * p = first ;
    int j = 0;
    while(p  && j <i )
    {
        p = p->next ;
        j++ ;
    }
    if (p->next ==NULL)
        throw "删除位置非法"
    else {
        s = p->next ;   //让中间结点(待删除)赋值给s
        p->next = s ->next ;  // 然后第三结点赋值给第一个结点的地址域
        delete s; //删除中间结点
    }
}
// 上述操作时间复杂度O(n)
//改成O(1):
template <class T>  //返回T因为一般删除都会返回结点的x值
T LinkList <T> ::delete (Node <T> *p )
{
    if(p->next){// p非最后一个结点 ,使用删除后面的一个结点代替删除自己
        T x =p ->data ;
        p -> data = p ->next ->data ;
        Node <T>  *q = p ->next ;  //表示出来后一个结点
        q ->next = p ->next  ; //准备将q出链
        delete q;
        return x ;//一般删除结点都返回其值
    else{...正常循环}
}
}

求取链表长度:

template <class T>
int LinkList <T> :: Length(){
    Node <T> * p = first ;
    int i =0;
    while ( p ){
        p = p ->next;
        i++;
    }
    return i;
}
//上述时间复杂度 O(N)

循环链表:

尾指针地址域指向头节点,上述代码循环条件改为p!= r

双链表:

每个结点有两个指针域,指向前驱和后继

template <class T> 
struct DulNode 
{
    T data;
    DulNode <T> * prior, *next ;
}

插入操作:

首先更改新结点的指针域

然后动链表

删除操作:

顺序表和链表的对比:

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

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

相关文章

LLM+知识图谱新工具! iText2KG:使用大型语言模型构建增量知识图谱

iText2KG是一个基于大型语言模型的增量知识图谱构建工具&#xff0c;通过从文本文档中提取实体和关系来逐步构建知识图谱。该工具具有零样本学习能力&#xff0c;能够在无需特定训练的情况下&#xff0c;在多个领域中进行知识提取。它包括文档提炼、实体提取和关系提取模块&…

BM1 反转链表

要求 代码 /*** struct ListNode {* int val;* struct ListNode *next;* };*/ /*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可*** param head ListNode类* return ListNode类*/ struct ListNode* ReverseList(struct …

【LeetCode-热题100-128题】官方题解好像有误

最长连续序列 题目链接&#xff1a;https://leetcode.cn/problems/longest-consecutive-sequence/?envTypestudy-plan-v2&envIdtop-100-liked 给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的…

Linux高阶——0928—Github本地仓库与云端仓库关联

1、安装代理软件 steam 选择Github和系统代理模式&#xff0c;一键加速即可 2、 安装Git 3、访问Github网站&#xff0c;创建新用户 4、Github探索 &#xff08;1&#xff09;Explore探索标签 &#xff08;2&#xff09;工程结构 用户名/仓库名 自述文件&#xff0c;用markdo…

【Llamaindex RAG实践】

基础任务 (完成此任务即完成闯关) 任务要求&#xff1a;基于 LlamaIndex 构建自己的 RAG 知识库&#xff0c;寻找一个问题 A 在使用 LlamaIndex 之前InternLM2-Chat-1.8B模型不会回答&#xff0c;借助 LlamaIndex 后 InternLM2-Chat-1.8B 模型具备回答 A 的能力&#xff0c;截…

每日OJ题_牛客_重排字符串_贪心_C++_Java

目录 牛客_重排字符串_贪心 题目解析 C代码 Java代码 牛客_重排字符串_贪心 重排字符串 (nowcoder.com) 描述&#xff1a; 小红拿到了一个只由小写字母组成的字符串。她准备把这个字符串重排&#xff08;只改变字母的顺序&#xff0c;不改变数量&#xff09; …

滑动窗口--(中篇)

将X减到0的最小操作数 给你一个整数数组 nums 和一个整数 x 。每一次操作时&#xff0c;你应当移除数组 nums 最左边或最右边的元素&#xff0c;然后从 x 中减去该元素的值。请注意&#xff0c;需要 修改 数组以供接下来的操作使用。 如果可以将 x 恰好 减到 0 &#xff0c;返…

Tomcat 项目配置指南

在实际工作中&#xff0c;我们所维护的项目可能与我们平时做的项目不一样。其中一种情况就是需要自己配置Tomcat服务。 下面笔者为大家介绍Tomcat基础的配置以及可能遇到的问题。 文章目录 一、Tomcat 配置二、常见报错及解决方案参考 一、Tomcat 配置 1. 下载 Tomcat 从 Apa…

一款完全开源并免费的监测与分析系统,支持监测,预警,分析,报告,支持本地化部署(附源码)

前言 在当今这个信息爆炸的时代&#xff0c;企业和个人都需要时刻了解网络上的动态&#xff0c;以便及时了解自身品牌形象和社会舆论的变化。然而&#xff0c;现有的舆情监测工具往往价格昂贵&#xff0c;且cao作复杂&#xff0c;难以满足普通用户的需求。 在这种背景下&…

基于SSM实现的求职招聘系统 设计与实现

一、项目简介 求职招聘系统&#xff0c;基于SSM实现的求职招聘系统 二、技术实现 后台框架&#xff1a;Spring、SpringMVC、MyBatis UI界面&#xff1a;JSP、jQuery 、H-ui 数据库&#xff1a;MySQL 下载地址 基于SSM实现的求职招聘系统源码数据库资源-CSDN文库 三、系…

音频文件重采样 - python 实现

在处理音频文件的时候&#xff0c;经常会将原音频进行统一的重采样处理&#xff0c;设置为相同的采样率&#xff0c;本示例&#xff0c;就是将44100采样率的音频&#xff0c;重采样为16000. 安装对应的python 库&#xff1a;librosa 和 soundfile. pip install soundfile pip i…

Vue前端框架的基础配置

登录界面添加背景图 通过在登录界面的vue文件中&#xff0c;设置div标签的background-image属性&#xff0c;加载背景图 <style scoped> .myvue{width:100%;height: 750px; //添加背景图的地址background-image: url(../assets/oa.jpeg);background-size: cover;backgr…

Linux更改固定IP地址

1.VMware里更改虚拟网络 一: 二: 三:确定就好了 2.修改Linux系统的固定IP 一:进入此文件 效果如下: 执行以下命令: 此时IP已更改 3.远程连接 这个是前提!!! 更改网络编辑器后网络适配器可能会修改,我就是遇着这个,困住我了一会 一:可以以主机IP对应连接 连接成功 二:主机名连…

[OS] 2.Wait for signal (do_wait),task_struct

Wait for signal (do_wait) Linux 内核中 do_wait() 函数的实现&#xff0c;该函数是父进程等待子进程结束的系统调用的一部分。它通过在内核模式下等待信号&#xff0c;处理进程终止以及与父子进程相关的机制。让我们详细解读您提供的信息&#xff0c;涉及 do_wait() 的执行过…

微软推出针对个人的 “AI伴侣” Copilot 会根据用户的行为模式、习惯自动进化

微软推出了为每个人提供的“AI伴侣”Copilot&#xff0c;它不仅能够理解用户的需求&#xff0c;还能根据用户的日常习惯和偏好进行适应和进化。帮助处理各种任务和复杂的日常生活场景。 它能够根据用户的生活背景提供帮助和建议&#xff0c;保护用户的隐私和数据安全。Copilot…

Crypto虐狗记---”你“和小鱼(八)

前言&#xff1a;剧情八 提示&#xff1a; 下载&#xff1a; 只给了公钥 那么可以用RsaCtfTool去分离公钥---》 得到(e&#xff0c;n)&#xff1a; 如何安装参考&#xff1a; kail下安装RsaCtfTool - 九皋777 - 博客园 (cnblogs.com) 已知n&#xff0c;那么去得到p q 或者使…

智能制造领域的系统都有啥,MES、APS、PLC、SCADA等

提及制造业&#xff0c;大家都能想到工业4.0.那么与工业4.0紧密相连的B端系统都有哪些类型的&#xff0c;本文为大家详细解读下。 在智能制造领域&#xff0c;常见的系统包括MES&#xff08;制造执行系统&#xff09;、APS&#xff08;高级计划与排程系统&#xff09;、PLC&am…

Oracle 数据库安装和配置详解

Oracle 数据库安装和配置详解 Oracle 数据库是一款功能强大、广泛使用的企业级关系数据库管理系统 (RDBMS)&#xff0c;适用于处理大型数据库和复杂事务。本文将介绍如何在 Linux 和 Windows 环境下安装 Oracle 数据库&#xff0c;并对其进行基本配置&#xff0c;帮助开发者快…

maven指定模块快速打包idea插件Quick Maven Package

问题背景描述 在实际开发项目中&#xff0c;我们的maven项目结构可能不是单一maven项目结构&#xff0c;项目一般会用parent方式将各个项目进行规范&#xff1b; 随着组件的数量增加&#xff0c;就会引入一个问题&#xff1a;我们只想打包某一个修改后的组件A时就变得很不方便…

8位单片机与32位单片机

8位单片机与32位单片机 8位与32位指的是什么 单片机的8位或32位说的是什么呢&#xff1f;要搞懂这个问题&#xff0c;首先要搞明白8位或32位说的是单片机上的哪一个部件。 这是单片机的内部框图。单片机内部由这么多部件构成&#xff0c;并不单单是一个CPU&#xff0c;它内部…