数据结构与算法基础(青岛大学-王卓)(2)

news2024/9/22 9:38:12

第二弹火爆来袭中

这波是单链表的内容整理,废话不多说,上小龙虾呀(又到了龙虾季节了,哎,口水直流了~~)


beautiful的分割线


文章目录

  • 第二弹火爆来袭中
  • 这波是单链表的内容整理,废话不多说,上小龙虾呀(又到了龙虾季节了,哎,口水直流了~~)
        • ...
        • 线性表的链式表示
          • 定义
          • 链表种类
          • 链表的表示
          • 链表的特点
          • 单链表
            • 表示方法
            • 单链表的初始化
            • 判断链表是否为空
            • 单链表的销毁(头结点也不存在了)
            • 清空单链表(头指针和头结点还在)
            • 求单链表的表长
            • 取单链表中第i个元素的内容
            • 单链表中的按值查找
            • 单链表的插入操作
            • 单链表的删除操作
            • 单链表的查找、插入、删除时间效率
            • 单链表的建立
        • ...
  • TO BE CONTINUED...

线性表的链式表示

定义

用一组物理位置任意的存储单元来存放线性表的数据元素,存储单元对连续性没要求,可零散分布,链表的每个节点由 数据+指针 组成

eg: 26个英文字母小写存储

在这里插入图片描述

链表种类

单链表,双链表,循环链表

在这里插入图片描述

链表的表示

在这里插入图片描述

  • 头指针:是指向链表中第一个结点的指针

  • 首元结点:是指链表中存储第一个数据元素a1的结点

  • 头结点:是在链表的首元结点之前附设的一个结点;

    • 链表存储的时候可以选择带和不带头节点

    • 好处:

      • 便于首元结点的处理(链表的第一个数据也能有往前的指针,处理起来和后面的正常元素就一样了)
      • 便于空表和非空表的统一处理,如下(第二种方案)

      在这里插入图片描述

    • 头结点的数据域可以为空,也可以放线性表长度等附加信息,但此节点不能计入链表长度值。

链表的特点
  • 存储上位置任意,不需要相邻
  • 访问元素时只能通过头指针进入链表,并扫描剩下每个节点直到找到目标,找到第一个节点和最后一个节点的时间不等
    • 顺序表–> 随机存取
    • 链表–> 顺序存取(找第i个元素时必须从第一个元素一直到i-1个元素再到元素i)
单链表
表示方法

单链表由表头唯一确定,可以用头指针的名字来命名,头指针为L则把链表称为表L.

存储结构

在这里插入图片描述

typedef struct Lnode{ //声明结点的类型和指向结点的指针类型
	ElemType data; //结点的数据域
	struct Lnode *next; //结点的指针域(嵌套了)
}Lnode,*LinkList; //LinkList为指向结构体Lnode的指针类型

LinkList L; //定义链表L
Lnode *p; //定义节点指针p (可以用linkList p 但是不推荐)

例子:存储学生的学号,姓名,成绩的单链表

// 通常定义法
typedef Struct {
	char num[8]; //数据域
	char name[8]; //数据域
	int score; //数据域
} ElemType;

typedef struct Lnode{
	ElemType data; //数据域
	struct Lnode *next; //指针域
}Lnode, *LinkList

Linklist L;

在这里插入图片描述

单链表的初始化
Status InitList_L(LinkList &L){
	L=new LNode; // C++ or C语言 L=(LinkList) malloc (sizeof (LNode))
	L->next=NULL;
	return OK;
}

在这里插入图片描述

判断链表是否为空
int ListEmpty(LinkList L){ //空表返回1,否则返回0
	if(L->next) //非空
		return 0;
	else
		return 1;
}
单链表的销毁(头结点也不存在了)
Status DestroyList_L(LinkList &L){
	Lnode *p;
	while(L){
		p=L;
		L=L->next;
		delete p; // C++ 用法 or C用法: free p;
	}
	return OK;
}
清空单链表(头指针和头结点还在)

依次从首元结点开始释放所有节点,最后将头结点的指针域设为空

在这里插入图片描述

Status EmptyList_L(LinkList &L){
	Lnode *p,*q;
	p=L->next;
	while (p){
		q=p->next;
		delete p;
		p=q;
	}
	L->next=NULL;
	return OK;
}
求单链表的表长
int List_Length(LinkList L){
	Lnode *p;
	p=L->next; //p指向第一个节点(首元结点)
	i=0;
	while (p){  //遍历单链表,统计节点数
		i++;
		p=p->next
	}
	return OK;
}
取单链表中第i个元素的内容

思路:从头指针触发,顺着链域next逐个往下搜索,直到搜索到第i个节点为止,因此链表不是随机存取结构,需判断找不到的情况和i的正确取值情况。

Status GetElem_L(LinkList L, int i, ElemType &e){
	p=L->next;j=1; //初始化,p指向首元结点,j来累计遍历过的位置
	while (!p && j<i){ //向后扫描直到p指向第i个元素或者p为空时
		p=p->next;
		++j; //注意这里是前加加,返回的是自增后的j, j++ 后加加是返回自增前的j
	}
	if (!p || j > i) return ERROR; //p指向空节点或者i各元素不存在时,返回ERROR
	e=p->data;
	return OK;
}//GetElem_L
单链表中的按值查找
  • 返回该数据所在位置(改数据地址)

    Lnode *LocateElem_L(LinkList L, ElemType e){
    //在单链表中查找元素为e的数据元素,找到后返回e的地址,未找到返回NULL
    	p=L->next;
    	while (p && p->data!=e){
    		p=p->next;
    	}
    	return p;
    }
    
  • 返回该数据所在的位置序号(第几个元素)

    int LocateElem_L(LinkList L, ElemType e){
    // 使用计数器i返回查找到的位置
    	p=L->next;j=1;
    	while (p && p->data!=e){
    		p=p->next;j++;
    	}
    	if (p) return j; //p非空情况下的i才有意义
    	else return 0;
    }
    
单链表的插入操作

在第i个节点前插入值为e的新节点 - 找前趋

在这里插入图片描述

//单链表的插入操作,在第i个位置插入元素数据域为e的元素
Status ListInset_L(LinkList &L, int i, ElemType e){
	p=L;j=0 //初始化p指向头结点,计数器为0
	while (p && j<i-1) {p=p->next; ++j;} //寻找i-1节点
	if (!p || j>i-1) return ERROR; //当p为空时,p已经指向了表长+1的节点位置,此时插入位置变为表长+2,这种情况不允许,所以这里排除掉了插入位置大于表长+1位置和i小于1的不合理情况。
	s=new Lnode;s->data=e; // 创建即将插入的新节点s
	s->next=p->next; // s指向原来的i节点
	p->next=s; //i-1节点指向新节点s
	return OK;
}//ListInset_L
单链表的删除操作

删除第i各元素 - 找前趋

在这里插入图片描述

Status List_Delete_L(LinkList &L, int i, ElemType &e){
	p=L;j=0; Lnode *q; //初始化,p指向头结点,计数器清零
	while(p->next && j<i-1) {p=p->next; ++j;} //寻找i-1元素,注意此处判定改为了p->next, 当p->next为NULL时,说明i-1个元素已经是表的最后一个元素,那么要删除的i元素就是表长+1的元素,而它是不存在的
	if(!p->next || j>i-1) return ERROR; // 排除不合理的i元素
	q=p->next; e=q->data; //将待删除元素信息做保留
	p->next=q->next; // i-1元素指向i+1元素
	delete q; //删除指针
	return OK;
}//ListDelete_L
单链表的查找、插入、删除时间效率
  • 查找 - 时间效率为O(n)

  • 插入/删除:

    • 单个操作并不会移动元素,只是动指针,时间效率为O(1)

    • 查找并操作时,时间效率为O(n)

单链表的建立
  • 头插法 - 元素倒序依次插入链表头结点后面

    • 从一个空表开始,重复读入数据

    • 生成新节点,将读入数据放入新节点的数据域中

    • 从最后一个节点开始,依次将各节点插入到链表的前端

    • 算法时间复杂度O(n)

      在这里插入图片描述

      在这里插入图片描述

     //头插法创建单链表
     Void CreateList_H(LinkList &L, int n){
         L=new Lnode; L->next=NULL; //建立一个带头结点的单链表
         for (i=n;i>0;--i){ //循环倒序插入所有元素
             p=new Lnode; //生成(C)新节点p=(Lnode*)malloc(sizeof(Lnode));
             cin>>p->data; //输入(C)元素值scanf(&p->data)
             p->next=L->next;
             L->next=p;
         }
     }//CreateList_H
    
  • 尾插法 - 新元素正序依次插入末尾

    • 从一个空链表L开始,新节点依次插入链表尾部,尾指针r指向链表尾结点

    • 初始时,r/L都指向头结点。每读取一个数据元素则申请一个新节点并插入尾结点后,r指向新的尾结点。

    • 算法时间复杂度O(n)

      在这里插入图片描述

     //尾插法创建单链表
     Void CreateList_R(LinkList &L, int n){
         L=new Lnode; L->next=NULL; //创建空单链表
         r=L; // 尾指针初始化等于头结点
         for (i=0;i<n;++i){ //依次正序添加节点
             p=new Lnode; 
             cin>>p->data;
             p->next=NULL; //新节点的指针域置空作为新的尾结点 
             r->next=p; //新节点链接前一个节点
             r=p; //尾指针移动到新尾结点
         }
     }//CreateList_R
    

TO BE CONTINUED…

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

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

相关文章

【致敬未来的攻城狮计划】— 连续打卡第二十七天:瑞萨RA RA2E1 的 BTN触摸按键

文章目录 由于一些特殊原因&#xff1a; 系列文章链接&#xff1a;&#xff08;其他系列文章&#xff0c;请点击链接&#xff0c;可以跳转到其他系列文章&#xff09;或者参考我的专栏“ 瑞萨MCU ”&#xff0c;里面是 瑞萨RA2E1 系列文章。 24.RA2E1的 DMAC——数据传输 25.R…

DB2_sql_问题

db2新增字段指定顺序 这个是不能做到的&#xff0c;除非把表删除重新创建的&#xff01; 原理是这样子的&#xff1a;当你创建表时系统会记录下你的SEQ-ID,就是字段的顺序号&#xff0c;这个是根据字段先后顺序来生成的&#xff0c;系统默认显示的时候也是根据这个来的&#x…

linux:工具(命令)vi、vim文本编辑器详解。

linux:工具(命令)vi/vim文本编辑器详解。 因此&#xff0c;本质上vi和vim是同种东西&#xff0c;后面也会合起来说&#xff0c;但是使用上会使用vim&#xff0c;因为vim是加强版。 使用形式&#xff1a; 无论退出还是进入都需要去到 “命令模式”。 当使用vi/vim时就会进入“命…

「高性能MySQL」读书笔记(1)- MySQL架构

一、前言 本系列主要是记录阅读「高性能MySQL」期间笔记&#xff0c;记录在日常使用中忽略的知识、模糊的点&#xff0c;主要面对有一定MySQL使用经验的开发者。 本文是针对于MySQL一些基础定义的解释说明&#xff0c;会非常浅显通俗易懂。 二、MySQL的逻辑架构 简单梳理My…

PCL学习九:Registration-配准

参考引用 Point Cloud Library黑马机器人 | PCL-3D点云 1. 点云中的数学 函数求导 对于函数 f ( x ) x 2 f(x)x^2 f(x)x2 其一阶导数也是 x x x 的函数&#xff1a; d f d x 2 x \frac{df}{dx}2x dxdf​2x其二阶导为常数&#xff0c;与 x x x 无关&#xff1a; d 2 f d x…

【漏洞分析】CVE-2021-0920 Linux内核垃圾回收机制中的竞争UAF漏洞

漏洞发现&#xff1a;该漏洞早在2016年被 RedHat 内核开发人员发现并披露&#xff0c;但 Linux 内核社区直到 2021 年重新报告后才对该漏洞进行修补&#xff08;patch&#xff09;。Google的威胁分析小组&#xff08;Threat Analysis Group&#xff09;发现该漏洞在野外被使用&…

shell脚本----基础命令

文章目录 一、sort命令二、uniq命令三、 tr命令四、cut命令 一、sort命令 sort命令以行为单位对文件内容进行排序&#xff0c;也可以根据不同的数据类型来排序&#xff0c;比较的原则是从首字符向后&#xff0c;一次按ASCII码的值进行比较&#xff0c;最后按序输出。 ASCII码…

【P17】JMeter 边界提取器(Boundary Extractor)

文章目录 一、准备工作二、测试计划设计 一、准备工作 慕慕生鲜&#xff1a; http://111.231.103.117/#/login 进入网页后&#xff0c;登录&#xff0c;页面提供了账户和密码 搜索框输入“虾” 右键检查或按F12&#xff0c;打开调试工具&#xff0c;点击搜索 二、测试计划设…

详细版易学版TypeScript - 元组 枚举

一、元组(Tuple) 数组:合并了相同类型的对象 const myArr: Array<number> [1, 2, 3]; 元组(Tuple):合并了不同类型的对象 // 定义元组时就要确定好数据的类型&#xff0c;并一一对应 const tuple: [number, string] [12, "hi"]; // 添加内容时&#xff0c;不…

SQLIST数据库编程

目录 数据库简介 1.常用数据库 2. SQLite基础 3.创建SQLite数据库 虚拟中sqlite3安装 基础SQL语句使用 sqlite3编程 数据库简介 1.常用数据库 大型数据库 &#xff1a;Oracle 中型数据库 &#xff1a;Server是微软开发的数据库产品&#xff0c;主要支持windows平台 小型数据库…

( 位运算 ) 190. 颠倒二进制位 ——【Leetcode每日一题】

❓190. 颠倒二进制位 难度&#xff1a;简单 颠倒给定的 32 位无符号整数的二进制位。 提示&#xff1a; 请注意&#xff0c;在某些语言&#xff08;如 Java&#xff09;中&#xff0c;没有无符号整数类型。在这种情况下&#xff0c;输入和输出都将被指定为有符号整数类型&a…

Vue.js自定义指令及用Vue实现简单的学生信息管理系统

目录 一、自定义指令v-mycolor 自定义指令生命周期&#xff1a; 二、使用钩子函数的自定义指令 三、Vue实现简单的学生信息管理系统 除了核心功能默认内置的指令&#xff0c;Vue.js允许注册自定义指令。添加一个自定义指令&#xff0c;有两种方式&#xff1a; &#xff08;1…

Redis 常见命令

一、redis中的常见数据结构 Redis共有5种常见数据结构&#xff0c;分别字符串&#xff08;STRING)、列表&#xff08;LIST&#xff09;、集合&#xff08;SET)、散列&#xff08;HASH&#xff09;、有序集合&#xff08;ZSET)。 二、redis中字符串(String)介绍 String 类型是…

PS网页版设计工具有哪些?

Photoshop是平面设计领域的老熟人&#xff0c;也是许多设计师的启蒙设计软件。然而&#xff0c;Photoshop的功能繁多&#xff0c;需要设计师具备较强的软件操作能力。在我们以为会和Photoshop一直相爱相杀的时候&#xff0c;一款专注于用户界面的矢量设计软件——即时设计&…

荔枝派Zero(全志V3S)驱动开发之RGB LCD屏幕显示jpg图片

文章目录 前言一、jpeglib 库移植1、jpeglib 库下载2、安装 jpeglib 库 二、jpeg 图片解压缩过程和压缩过程1、jpeg 解压缩过程2、jpeg 压缩过程 三、编译 C 源码1、源码展示2、拷贝需要用到的头文件3、编译 C 代码 四、验证测试1、拷贝相关文件到开发板2、显示图片 前言 由于…

深入了解Dubbo SPI 工作机制——@Adaptive(6)

Adaptive这个注解就是适配策略&#xff0c;我都是称呼为最佳适配子类&#xff0c;或者最佳适配类。就是找到最佳的子实现类的&#xff0c;其实就是默认的类。这个注解可以打在类上方&#xff0c;那么dubbo SPI机制通过接口获取实例类&#xff0c;就是获取到有Adaptive注解的实现…

WooCommerce商城开发:高性能订单存储数据库模式

这是一系列深入探讨的第一部分&#xff0c;专门用于解释高性能订单存储数据库模式的实施。 与1 月份提出的版本相比&#xff0c;数据库模式的变化很小。我们在不同的地方添加和删除了几列&#xff0c;但整体表结构与第一个提案中描述的相同&#xff1a; 我们在此项目中添加了4…

51单片机(九)LED点阵屏

❤️ 专栏简介&#xff1a;本专栏记录了从零学习单片机的过程&#xff0c;其中包括51单片机和STM32单片机两部分&#xff1b;建议先学习51单片机&#xff0c;其是STM32等高级单片机的基础&#xff1b;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 &#xff1a;适用于想要…

创维E900-S-Hi3798MV100-当贝纯净桌面-卡刷固件包

创维E900-S-Hi3798MV100-当贝纯净桌面-卡刷固件包-内有教程 特点&#xff1a; 1、适用于对应型号的电视盒子刷机&#xff1b; 2、开放原厂固件屏蔽的市场安装和u盘安装apk&#xff1b; 3、修改dns&#xff0c;三网通用&#xff1b; 4、大量精简内置的没用的软件&#xff0…

RabbitMQ消息队列实战(5)—— 发后即忘和远程RPC数据传输模型

本文我们学习下使用RabbitMQ实现的几种数据发送的模型——发后即忘模型和远程RPC调用。二者实际上是从业务的角度定义的一个RabbitMQ的使用模型。发后即忘模型&#xff0c;强调发送时不太关心消息接收者的执行结果&#xff0c;仅仅是为了发送信息。而远程RPC调用模型强调&#…