【二】数据结构之List
数据结构中,线性表无独有偶,除了Vector还有另外一种ADT,就是我们要讨论的List,与向量Vector有所不同,列表List不在是系统连续的内存空间,也就是说不是基于数组来实现的了,尽管在物理上不是线性的,但是抽象层次上,List在逻辑上依旧是现行表,因此List优化了Vector插入,删除操作的劣势,但是在查找方面却不如Vector的二分查找来的快。
List有哪些接口呢?
恩,接下来,给出具体的实现,注释都很详细,很容易理解。
节点的实现如下:
#ifndef LISTNODE_H
#define LISTNODE_H
typedef int Rank;//秩
#define ListNodePosi(T) ListNode<T>* //列表节点位置
template <typename T> struct ListNode{
//列表节点模板类(以双向链表形式实现)
//成员
T data; ListNodePosi(T) pred; ListNodePosi(T) 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);//紧靠当前节点之后插入新节点
};
//类函数定义
template <typename T>//将e紧靠当前节点之前插入于当前节点所属列表(设有哨兵头节点header)
ListNodePosi(T) ListNode<T>::insertAsPred(T const& e){
ListNodePosi(T) x = new ListNode(e, pred, this);//创建新节点
pred->succ = x; pred = x;//设置正向链接
return x;//返回新节点的位置
}
template <typename T>//将e紧靠当前节点之后插入于当前节点所属列表(设有哨兵头节点trailer)
ListNodePosi(T) ListNode<T>::insertAsSucc(T const& e){
ListNodePosi(T) x = new ListNode(e, this, succ);//创建新节点
succ->pred = x; succ = x;//设置反向链接
return x;//返回新节点的位置
}
#endif // !LISTNODE_H
列表的实现如下:
#ifndef LIST_H
#define LIST_H
#include "listNode.h"
template<typename T> class List{
//列表模板类
private:
int _size; ListNodePosi(T) header; ListNodePosi(T) trailer;//规模、头尾哨兵
protected:
void init();//初始化
int clear();//清楚所有节点至表空
void copyNodes(ListNodePosi(T), int);//复制列表中自p起的n项
void merge(ListNodePosi(T)&, int, List<T>&, ListNodePosi(T), int);//归并
void mergeSort(ListNodePosi(T)&, int);//归并排序
void selectionSort(ListNodePosi(T), int);//选择排序
void insertionSort(ListNodePosi(T), int);//插入排序
public: