数据结构-线性表-链表

news2024/12/23 9:08:05

目录

    • 线性表的链式存储结构:
    • 一、单向链表的ADT定义
    • 二、链表的优缺点

线性表的链式存储结构:

为了表示数据元素ai和其后继元素ai+1之间的逻辑关系,对ai来说需存储其本身信息和后继元素的信息(存储位置)。这两部分组成ai的存储映像,称为结点(Node),它包含两个域:数据域和指针域。n个结点链结在一起,就组成线性表的链式存储结构。
在这里插入图片描述
1)单向链表

using namespace std;
struct Node
{
	int value;
	Node *next;
}*LinkedList,LNode;

2)双向链表

struct DNode
{
    int value;       /* Data field */
    struct DNode *prior;  /* Pointer field */
    struct DNode *next;   /* Pointer field */
}DNode;

一、单向链表的ADT定义

1.1 创建链表
使用尾插法创建单链表

 //尾插法创建单链表、链表长度为n;
void CreatLinkedList(LinkedList &L,int n)  
{
    L = (LinkedList)malloc(sizeof(LNode));  //初始化;
    L->next = NULL;
    L->data = 0;
    LinkedList Tail = L;    //尾指针;
    cout<<"Enter "<<n<<" number(s)"<<endl;
    for(int i = 0 ; i < n; i++)
    {
        LinkedList Temp = (LinkedList)malloc(sizeof(LNode));
        cin>>Temp->data;
        Tail->next = Temp;
        Tail = Temp;
        Temp = NULL;
        L->data++;  //计数;
    }
    Tail->next = NULL;
}

1.2 查找
从头结点开始,逐个查找(后移)并计数,直到第i个为止。
算法的平均时间复杂度为T(n) = O(n)

//查找链表中第一个数据为data的节点,如果找到就返回节点指针,否则返回空指针NULL
Node findInList(LinkedList lst, int data) {
    Node tmp = lst;
    while (tmp->next != NULL) {
        if (tmp->data == data) {
            return tmp;
        }
        tmp = tmp->next;
    }
    return NULL;
}

在这里插入图片描述
1.3 插入
在指定位置插入节点

	// 在链表最前面插入一个节点,插入完成后,新插入的节点为链表的新的头结点
    void addHead(LinkedList* head, int val) {
        LinkedList* newNode = new Node();
        newNode->value = val;
        newNode->next = head->next;
    }

    // 在链表最后面添加一个节点
    void addTail(LinkedList* head, int val) {
        LinkedList* newNode = new Node();
        newNode->value = val;
        newNode->next = nullptr;
        LinkedList* cur = head;
        while(cur->next != nullptr){
            cur = cur->next;
        }
        cur->next = newNode;
    }

    // 在链表的某个位置插入一个节点
    void addIndex(LinkedList* head, int index, int val) {
        LinkedNode* newNode = new Node();
        LinkedNode* cur = _dummyHead;
        while(index--) {
            cur = cur->next;
        }
        newNode->next = cur->next;
        cur->next = newNode;
    }

1.4 删除
删除结点

LinkedList* removeElements(LinkedList* head, int val) {
        //删除头节点
        while((head != NULL)&&(head->value == val)){ 
            Node* temp = head;
            head = head->next;
            delete temp;
        }
        //删除非头节点
        Node*  cur = head;  //头节点不动
        //不是空链表且不是尾部节点
        while((cur != NULL)&&(cur->next != NULL)){
        	//如果下一个节点的值等于目标值,删除
            if(cur->next->val == val){ 
                Node*  temp = cur->next; //
                cur->next = cur->next->next;
                delete temp; 
            }
            else{
                cur = cur->next;
            }
        }
        return head;

1.5 反转链表

    Node* reverseList(ListNode* head) {
    	//初始化一个空指针的节点
        Node* pre = new Node();  
        pre = nullptr;
        ListNode* cur = new Node();
        cur = head;
        Node* temp;
        while(cur != nullptr){
            temp = cur->next; 
            cur->next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
    }

1.6 链表的合并

有序表的合并,用链表实现:
在这里插入图片描述

在这里插入图片描述

Node* mergeList(Node* head1, Node* head2)
	Node* p = head1; // 指向第一个链表的指针
	Node* q = head2; // 指向第二个链表的指针
	Node* dummy = new Node(); // 创建一个虚拟节点
	Node* r = dummy; // 指向新链表的指针
	while (p != nullptr && q != nullptr) {
	    if (p->val < q->val) {
	        r->next = p; // 将第一个链表中的节点插入到新链表中
	        p = p->next; // 移动指针到下一个节点
	    } else {
	        r->next = q; // 将第二个链表中的节点插入到新链表中
	        q = q->next; // 移动指针到下一个节点
	    }
	    r = r->next; // 移动指针到新链表的最后一个节点
	}
	if (p != nullptr) {
	    r->next = p; // 将第一个链表中剩余的节点插入到新链表中
	} else {
	    r->next = q; // 将第二个链表中剩余的节点插入到新链表中
	}
	head = dummy->next; // 将新链表头指针指向第一个节点
	return head;

1.7 链表的长度

int getListSize(LinkedList* head){
	Node* p = head; // 指向链表头节点的指针
	int len = 0; // 链表长度
	while (p != nullptr) {
	    len++;
	    p = p->next; // 移动指针到下一个节点
	}
	cout << "链表的长度为:" << len << endl;
	return len;
}

二、链表的优缺点

链表的优点:
1)进行插入和删除元素的操作不需要移动其余元素,效率高,复杂度为O(1);
2)链表不要求连续空间,空间利用效率高
链表的缺点:
1)查找元素和搜索元素的效率低,最快情况为O(1),平均情况为O(N)

因此对于经常插入和删除的操作,数据结构采用 链表或者使用二叉搜索树。
在这里插入图片描述

参考资料:数据结构与算法基础课程-王卓老师

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

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

相关文章

Android系统(AOSP)--编译指令篇

目录 一、编译Android系统 二、普通编译指令 三、快速编译指令 四、新建lunch项和编译类型说明 五、Android编译系统的整体架构 六、编译后的输出目录和生成文件 七、Android常用编译命令总结 一、编译Android系统 1.Android系统全编译(Android5.1以后mtk都是这种方式…

裸辞3个月没工作,害怕面试,害怕HR问我的问题,怎么办?

其实裸辞最大的伤害就是很容易导致自己的不自信。 现在可能就是你的低谷期&#xff0c;你需要做的是什么呢&#xff0c;丰富自己。 你要相信&#xff0c;你只是太久没有面试过&#xff0c;生疏了而已。 今天小月带你回到面试场&#xff0c;找回面试最纯正的感觉&#xff01; 面…

火龙果MM32F3273G8P开发板MindSDK开发教程1 - 点亮LED

火龙果MM32F3273G8P-MindSDK开发教程1-点亮LED 1、登录官网下载对应的MindSDK固件 https://mindsdk.mindmotion.com.cn/&#xff0c;然后注册下载mm32F3270的固件即可。 下载完的文件为 plus-f3270_mdk.zip 解压后的文件路径如图&#xff1a; 2、新建LED工程 将下载的plu…

基于张量补全的交通数据复原文献汇总(最新)

由于传感器故障和通信故障等因素导致的交通数据缺失严重制约了ITS的发展与应用。如何准确、高效地恢复缺失数据已成为ITS的一个关键问题。近年来&#xff0c;LRTC&#xff08;低秩张量补全&#xff09;的方法已被广泛应用于交通数据补全。本文将介绍几篇最新的关于交通数据补全…

python3 爬虫相关学习7:初步摸索使用 BeautifulSoup

1 一个爬图片pic的代码的例子 下面这段是爬一些图片pic的代码学写了一段bs的代码&#xff0c;但是马上报错 #E:\work\FangCloudV2\personal_space\2learn\python3\py0001.txtimport requests from bs4 import BeautifulSoupurl"https://movie.douban.com/celebrity/10115…

搭建个人博客

个人网站用处有很多&#xff0c;可以写博客来记录学习过程中的各种事&#xff0c;不管是新知识还是踩坑记录&#xff0c;写完就丢在网站上&#xff0c;方便日后复习&#xff0c;也可以共享给他人&#xff0c;让其他人避免踩雷。 当然也不仅限于技术性的文章&#xff0c;生活中有…

隐马尔可夫模型在数学建模中的应用及MATLAB实现

2023年9月数学建模国赛期间提供ABCDE题思路加Matlab代码,专栏链接(赛前一个月恢复源码199,欢迎大家订阅):http://t.csdn.cn/Um9Zd 目录 2023年9月数学建模国赛期间提供ABCDE题思路加Matlab代码,专栏链接(赛前一个月恢复源码199,欢迎大家订阅):http://t.csdn.cn/Um9Zd 隐马尔可…

(二)CSharp-数据类型

一、数据类型 1、C#程序是一组类型声明 C 程序是一组函数和数据类型C 程序是一组函数和类C# 程序是一组类型声明 2、类型是一种模板 类型由下面的元素定义&#xff1a; 名称用于保存数据成员的数据结构一些行为及约束条件 3、实例化类型 从某个类型模板创建实际的对象&am…

完败!资深码农 VS 新手+AI;阿里云AI黑客松千万奖金池;手把手教你用AI写小说;微软AI入门课 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; 阿里云首届AI黑客马拉松&#xff0c;共享 1000 万美元风投资金池 阿里云官方宣布&#xff0c;将以国内最大AI模型社区「Model Scope 魔…

基于双视角图表示算法的双向人职匹配偏好建模推荐系统构建

基于双视角图表示算法的双向人职匹配偏好建模推荐系统构建 文章目录 基于双视角图表示算法的双向人职匹配偏好建模推荐系统构建1. 传统推荐系统模型2. 协同过滤算法3. 基于双视角图表示学习算法的模型构建3.1 数据输入3.2 双视角交互图的构建3.3 混合偏好传播策略3.4 对于双向意…

H5项目怎么打包成APP

文章目录 前言一、新建5APP项目二、删除不需要的文件三、将H5打包的文件拷贝到当前目录下四、配置APP五、发行-云打包六、安装apk总结 前言 开发uni-app的编辑器HBuilderX可以将H5项目打包成APP&#xff0c;相信很多小伙伴还不知道这个功能&#xff0c;下面将介绍下如何将H5打…

linux MMU内存管理单元

本篇文章简要阐述MMU的概念&#xff0c;以及以段地址的转换过程为例&#xff0c;简单说明MMU将虚拟地址转换成物理地址的过程。更多详细内容请查看《ARM-MMU(中文手册).pdf》。 1、MMU概述 在ARM存储系统中&#xff0c;使用MMU实现虚拟地址到实际物理地址的映射。为何要实现这…

人工智能学习07--pytorch21--目标检测:YOLO系列理论合集(YOLOv1~v3)

如果直接看yolov3论文的话&#xff0c;会发现有好多知识点没见过&#xff0c;所以跟着视频从头学一下。 学习up主霹雳吧啦Wz大佬的学习方法&#xff1a; 想学某个网络的代码时&#xff1a;到网上搜这个网络的讲解 → 对这个网络大概有了印象 → 读论文原文&#xff08; 很多细…

Django实现接口自动化平台(五)httprunner(4.x)介绍【持续更新中】

上一章&#xff1a; Django实现接口自动化平台&#xff08;四&#xff09;解决跨域问题【持续更新中】_做测试的喵酱的博客-CSDN博客 下一章&#xff1a; 一、httpruner介绍 1.1 背景&#xff1a; 之所以学习httpruner的用法&#xff0c;是要把httpruner嵌入我们的自动化平…

全网最全、最新MyBatis框架核心知识

MyBatis框架 1. 软件开发常用结构 MyBatis是操作数据库的&#xff0c;相当于是一个增强的JDBC 1.1 三层架构 三层架构包括&#xff1a; 界面层&#xff08;User Interface layer&#xff09;业务逻辑层&#xff08;Business Logic Layer&#xff09;数据访问层&#xff08;Dat…

Window搭建IOS App自动化测试环境

平台搭建&#xff1a;tidevice&#xff08;Windows逆向通信iOS工具&#xff09;WebDriverAgent&#xff08;iOS通信服务&#xff09;facebook-wda&#xff08;iOS测试框架&#xff09; macOSXcode&#xff1a;在手机上安装WebDriverAgent的时候需要用到&#xff0c;必须要Xcod…

HDFS概述及其优缺点

什么是HDFS&#xff1f; HDFS的全称是hadoop distributed file system&#xff0c;即hadoop的分布式文件系统。 见名知意&#xff0c;它就是用来进行文件存储的。毕竟它是大数据的一个组件&#xff0c;用来存储这种海量的数据。 它是基于03年10月份&#xff0c;谷歌发表的GFS…

Hadoop 怎么委任和解除节点?

前言 本文隶属于专栏《大数据技术体系》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见大数据技术体系 正文 Hadoop 集群的管理员经常需要向集群中添加节点…

Android Studio引用第三方库的方式

title: 大小端详解 date: 2023-06-06 21:01:24 comments: true #是否可评论 toc: true #是否显示文章目录 categories: #分类 - gradle - android studio tags: #标签 - gradle - android studio summary: android stduio 导入第三方库方式 Android Studio引用第三方库的方式 …

NCUTer 我的创作纪念日(2023-06-06)

前言 大家好&#xff0c;我是NCUTer&#xff0c;今天收到私信&#xff0c;突然发现&#xff0c;我来到CSDN已经2年多了&#xff0c;距离发布第一篇博客已经2年整了。正式规划性的写博客&#xff0c;是在2021年6月底开始的&#xff0c;当时啥也不懂&#xff0c;不知道该怎么去做…