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

文章目录

  • 0.概述
  • [1. 从向量到列表](#1. 从向量到列表)
    • [1.1 从静态到动态](#1.1 从静态到动态)
    • [1.2 从向量到列表](#1.2 从向量到列表)
    • [1.3 从秩到位置](#1.3 从秩到位置)
    • [1.4 列表](#1.4 列表)
  • [2. 接口](#2. 接口)
    • [2.1 列表节点](#2.1 列表节点)
      • [2.1.1 ADT接口](#2.1.1 ADT接口)
      • [2.1.2 ListNode模板类](#2.1.2 ListNode模板类)
    • [2.2 列表](#2.2 列表)
      • [2.2.1 ADT接口](#2.2.1 ADT接口)
      • [2.2.2 List模板类](#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模板类

cpp 复制代码
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模板类

头尾接口对外不可见,非常重要。

cpp 复制代码
#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 ); //整体复制列表L
   List( 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 ); } //将头、尾节点等同于NULL
   ListNodePosi<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"
cpp 复制代码
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; //记录规模
}
相关推荐
hsling松子4 小时前
使用PaddleHub智能生成,献上浓情国庆福
人工智能·算法·机器学习·语言模型·paddlepaddle
dengqingrui1234 小时前
【树形DP】AT_dp_p Independent Set 题解
c++·学习·算法·深度优先·图论·dp
C++忠实粉丝4 小时前
前缀和(8)_矩阵区域和
数据结构·c++·线性代数·算法·矩阵
我的心永远是冰冰哒5 小时前
ad.concat()学习
学习
ZZZ_O^O5 小时前
二分查找算法——寻找旋转排序数组中的最小值&点名
数据结构·c++·学习·算法·二叉树
CV-King5 小时前
opencv实战项目(三十):使用傅里叶变换进行图像边缘检测
人工智能·opencv·算法·计算机视觉
代码雕刻家6 小时前
数据结构-3.9.栈在递归中的应用
c语言·数据结构·算法
雨中rain6 小时前
算法 | 位运算(哈希思想)
算法
slomay6 小时前
关于对比学习(简单整理
经验分享·深度学习·学习·机器学习
hengzhepa7 小时前
ElasticSearch备考 -- Async search
大数据·学习·elasticsearch·搜索引擎·es