【数据结构(邓俊辉)学习笔记】列表01——从向量到列表

embedded/2024/12/23 5:33:04/

文章目录

  • 0.概述
  • 1. 从向量到列表
    • 1.1 从静态到动态
    • 1.2 从向量到列表
    • 1.3 从秩到位置
    • 1.4 列表
  • 2. 接口
    • 2.1 列表节点
      • 2.1.1 ADT接口
      • 2.1.2 ListNode模板类
    • 2.2 列表
      • 2.2.1 ADT接口
      • 2.2.2 List模板类

0.概述

学习了向量,再介绍下列表。先介绍下列表里的概念和语义,这个对理解列表接口还是比较重要的。

1. 从向量到列表

1.1 从静态到动态

在这里插入图片描述

1.2 从向量到列表

在这里插入图片描述
注意:首末节点描述。

1.3 从秩到位置

在这里插入图片描述
在这里插入图片描述
数据结构的访问方式,应与其存储策略相一致。此时,既然继续延用循秩访问的方式已非上策,就应更多地习惯于通过位置,来指代并访问动态存储结构中的数据元素。
在这里插入图片描述

1.4 列表

与向量一样,列表也是由具有线性逻辑次序的一组元素构成的集合:
~~~~~~~~~~~~~~~~~~~~~~~~                         L = { a0, a1, …, an-1 }
列表是链表结构的一般化推广,其中的元素称作节点(node),分别由特定的位置或链接指代。与向量一样,在元素之间,也可定义前驱、直接前驱,以及后继、直接后继等关系;相对于任意元素,也有定义对应的前缀、后缀等子集。

2. 接口

2.1 列表节点

2.1.1 ADT接口

在这里插入图片描述###

2.1.2 ListNode模板类

在这里插入图片描述

using Rank = unsigned int; //秩template <typename T> struct ListNode;
template <typename T> using ListNodePosi = ListNode<T>*; //列表节点位置template <typename T> 
struct ListNode { //列表节点模板类(以双向链表形式实现)
// 成员T data; ListNodePosi<T> pred, succ; //数值、前驱、后继
// 构造函数ListNode() {} //针对header和trailer的构造ListNode ( T e, ListNodePosi<T> p = NULL, ListNodePosi<T> s = NULL ): data( e ), pred( p ), succ( s ) {} //默认构造器
// 操作接口ListNodePosi<T> insertAsPred( T const& e ); //紧靠当前节点之前插入新节点ListNodePosi<T> insertAsSucc( T const& e ); //紧随当前节点之后插入新节点
};

2.2 列表

2.2.1 ADT接口

领会下宏观接口,具体接口后面会做介绍。
在这里插入图片描述
分别针对有序和无序列表,提供了去重操作的两个版本(deduplicate()和uniquify()),以及查找操作的两
个版本(find()和search())。与向量一样,有序列表的唯一化,比无序列表效率更高。

由于只能通过位置指针以局部移动的方式访问节点,尽管有序列表中节点在逻辑上始终按照大小次序排列,其查找操作的效率并没有实质改进。

二者的效率完全一致:在最好情况下,均只需O(1)时间;在最坏情况下,均需要O(n)时间;平均而言,二者均需O(n)时间。

2.2.2 List模板类

在这里插入图片描述
头尾接口对外不可见,非常重要。


#pragma once#include "listNode.h" //引入列表节点类template <typename T> class List { //列表模板类private:Rank _size; ListNodePosi<T> header, trailer; //规模、头哨兵、尾哨兵protected:void init(); //列表创建时的初始化Rank clear(); //清除所有节点void copyNodes( ListNodePosi<T>, Rank ); //复制列表中自位置p起的n项ListNodePosi<T> merge( ListNodePosi<T>, Rank, List<T>&, ListNodePosi<T>, Rank ); //归并void mergeSort( ListNodePosi<T>&, Rank ); //对从p开始连续的n个节点归并排序void selectionSort( ListNodePosi<T>, Rank ); //对从p开始连续的n个节点选择排序void insertionSort( ListNodePosi<T>, Rank ); //对从p开始连续的n个节点插入排序void radixSort( ListNodePosi<T>, Rank ); //对从p开始连续的n个节点基数排序public:
// 构造函数List() { init(); } //默认List( List<T> const& L ); //整体复制列表LList( List<T> const& L, Rank r, Rank n ); //复制列表L中自第r项起的n项List( ListNodePosi<T> p, Rank n ); //复制列表中自位置p起的n项// 析构函数~List(); //释放(包含头、尾哨兵在内的)所有节点
// 只读访问接口Rank size() const { return _size; } //规模bool empty() const { return _size <= 0; } //判空ListNodePosi<T> operator[]( Rank r ) const; //重载,支持循秩访问(效率低)ListNodePosi<T> first() const { return header->succ; } //首节点位置ListNodePosi<T> last() const { return trailer->pred; } //末节点位置bool valid( ListNodePosi<T> p ) //判断位置p是否对外合法{ return p && ( trailer != p ) && ( header != p ); } //将头、尾节点等同于NULLListNodePosi<T> find( T const& e ) const //无序列表查找{ return find( e, _size, trailer ); }ListNodePosi<T> find( T const& e, Rank n, ListNodePosi<T> p ) const; //无序区间查找ListNodePosi<T> search( T const& e ) const //有序列表查找{ return search( e, _size, trailer ); }ListNodePosi<T> search( T const& e, Rank n, ListNodePosi<T> p ) const; //有序区间查找ListNodePosi<T> selectMax( ListNodePosi<T> p, Rank n ); //在p及其n-1个后继中选出最大者ListNodePosi<T> selectMax() { return selectMax( header->succ, _size ); } //整体最大者
// 可写访问接口ListNodePosi<T> insertAsFirst( T const& e ); //将e当作首节点插入ListNodePosi<T> insertAsLast( T const& e ); //将e当作末节点插入ListNodePosi<T> insert( ListNodePosi<T> p, T const& e ); //将e当作p的后继插入ListNodePosi<T> insert( T const& e, ListNodePosi<T> p ); //将e当作p的前驱插入T remove( ListNodePosi<T> p ); //删除合法位置p处的节点,返回被删除节点void merge( List<T>& L ) { merge( header->succ, _size, L, L.header->succ, L._size ); } //全列表归并void sort( ListNodePosi<T>, Rank ); //列表区间排序void sort() { sort( first(), _size ); } //列表整体排序Rank dedup(); //无序去重Rank uniquify(); //有序去重void reverse(); //前后倒置(习题)
// 遍历void traverse( void ( * )( T& ) ); //依次实施visit操作(函数指针)template <typename VST> void traverse( VST& ); //依次实施visit操作(函数对象)
}; //List#include "List_implementation.h"

在这里插入图片描述

template <typename T> 
void List<T>::init() { //列表初始化,在创建列表对象时统一调用header = new ListNode<T>; trailer = new ListNode<T>; //创建头、尾哨兵节点header->succ = trailer; header->pred = NULL; //向前链接trailer->pred = header; trailer->succ = NULL; //向后链接_size = 0; //记录规模
}

http://www.ppmy.cn/embedded/31564.html

相关文章

服务网关GateWay原理

文章目录 自动装配核心类GatewayAutoConfigurationDispatcherHandler请求处理阶段apply方法httpHandler#handle方法WebHandler#handle方法DispatchHanlder#handle方法第一步 getHandler获取请求映射第二步 invokeHandler 请求适配第三步 handleResult请求处理总结 上一篇博文我…

【数据库原理及应用】期末复习汇总高校期末真题试卷

试卷 一、填空题 1.________是位于用户与操作系统之间的一层数据管理软件。 2.数据库系统的三级模式结构是指________、________、________。 3.数据库系统的三种数据模型是________ 、________、________。 4.若关系中的某一属性组的值能唯一地标识一个元组&#xff0c;则…

【算法】深度优先搜索岛屿数量

1、题目描述 有一个由0和1组成的二维矩阵&#xff0c;其中1代表陆地&#xff0c;0代表水&#xff0c;岛屿由水平或垂直方向上相邻的陆地连接形成。 假设矩阵的四周均被水包围&#xff0c;请计算岛屿的数量。 输入&#xff1a;matrix [[1,1,0,0],[0,0,1,0],[0,0,0,0],[0,0,1,1],…

WAAP动态安全解决方案

随着企业数字化进程不断加速&#xff0c;应用安全面临多重威胁&#xff0c;新型攻击方式层出不穷&#xff0c;常见的攻击形式包括Web应用攻击、DDoS攻击、API攻击、恶意爬虫攻击等。企业正面临严峻的安全防护挑战&#xff0c;需寻找一个可靠、全面的安全解决方案。在此情况下&a…

Apache SSI远程命令执行漏洞

什么是SSI Apache SSI&#xff08;Server Side Include)&#xff0c;通常称为"服务器端嵌入"或者叫"服务器端包含"&#xff0c;是一种类似于ASP的基于服务器的网页制作技术。默认扩展名是 .stm、.shtm 和 .shtml。 从技术层面来讲&#xff0c;SSI是一种在静…

【C++】深入剖析C++11 initializer_list 新的类功能 可变模板参数

目录 一、std::initializer_list 1、std::initializer_list是什么类型 2、std::initializer_list 的应用场景 ①给自定义容器赋值 ② 传递同类型的数据集合 二、新的类功能 1、默认成员函数 2、关键字default 3、关键字delete 三、可变参数模板 一、std::initialize…

题目:吃奶酪

问题描述&#xff1a; 解题思路&#xff1a; 枚举每种吃奶酪顺序&#xff0c;并计算其距离&#xff0c;选择最小的距离即答案。v数组&#xff1a;记录顺序。 注意点&#xff1a;1. 每次用于min的s需要重置为0。 2. 实数包括小数&#xff0c;所以结构体内x,y为double类型。 3. 第…

【QT】初始QT

目录 一.背景1.GUI开发的各种技术方案2.什么是框架3.QT支持的系统4.QT的版本5.QT的优点6.QT的应用常见 二.环境搭建1.认识QTSDK中的重要工具2.使用QT Creator创建项目3.项目解释(1)main.cpp(2)widget.h(3)widget.cpp(4)widget.ui(5)Empty.pro(6)临时文件 三.初始QT1.Hello Worl…