在讨论完了列表的节点类之后,下面就可以考虑列表的接口和实现了。
列表的抽象数据类型的接口如下:
1.报告规模:size()
2.返回首/末节点:first()、last()
3.作为头/尾节点插入:insertAsFirst()、insertAsLast()
4.作为前驱/后继节点插入:insertAsBefore()、insertAsAfter()
5.删除元素:remove()
6.判断有序:disorded()
7.排序操作:sort()
8.无序查找:find()
9.有序查找:search()
10.无序去重:deduplicate()
11.有序去重:uniquify()
12.遍历操作:traverse()
列表类型的具体实现如下:
#include "ListNode.h" //引入列表节点类
template <typename T>
class List //列表类模板
{
private: //私有成员变量
int _size; //定义列表规模
ListNodePosi(T) header, tailer; //头尾哨兵
protected: //保护成员函数
void init(); //初始化
int clear(); //清空
void copyNodes(ListNodePosi(T) p, int n); //复制自节点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:
/*--构造函数--*/
List() { init(); } //默认初始化
List(List<T> const &); //复制初始化
List(ListNodePosi(T) p, int n); //复制自节点p开始的n项
List(List<T>, Rank lo, Rank hi); //复制区间[lo, hi)间的项
/*--析构函数--*/
~List();
/*--只读接口--*/
Rank size() { return _size };
bool empty() { return (_size <= 0) };
T& operator[](Rank r) const;
ListNodePosi(T) & fisrt() const { return header.succ };
ListNodePosi(T) & last() const { return tailer.pred };
bool disorded() const;
ListNodePosi(T) find(T const &);
ListNodePosi(T) find(T const &, ListNodePosi(T), int);
ListNodePosi(T) search(T const &);
ListNodePosi(T) search(T const &, ListNodePosi(T), int);
/*--可写接口--*/
ListNodePosi(T) insertAsFirst(T const &);
ListNodePosi(T) insertAsLast(T const &);
ListNodePosi(T) insertAsBefore(ListNodePosi(T), T const &);
ListNodePosi(T) insertAsAfter(ListNodePosi(T), T const &);
T remove(ListNodePosi(T));
void merge(List<T> &);
void sort();
void sort(ListNodePosi(T), int);
int deduplicate();
int uniquify();
/*--遍历接口--*/
void traverse(void (* )(T &));
template <typename VST>
void traverse(VST &);
};