List
1.元素在逻辑上具有线性次序物理地址不做限制。
2.哨兵节点header和trailer封装后外部不可见。
3.重载操作符[]实现下标和位置转换。
4.有序查找无序查找
5.前插入算法首先创建新节点
然后使new成为this节点的前驱和this节点前驱节点的后继。
6.后插入算法
7.基于复制的构造方法从源列表中取出n个相邻节点作为末节点插入新列表
8.删除p节点的前驱与p节点的后继相连然后释放p节点。
9.析构删除列表节点直到列表为空然后释放列表头尾哨兵节点。
10.去重算法有序、无序去重
11.排序算法插入、选择、归并
using Rank = int;
template <typename T> struct ListNode;
template <typename T> using ListNodePosi = ListNode<T>*;
template <typename T> struct ListNode {
T data; ListNodePosi<T> pred; ListNodePosi<T> succ;
ListNode() {}
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> class List {
private:
int _size; ListNodePosi<T> header; ListNodePosi<T> trailer;
protected:
void init();
int clear();
void copyNodes ( ListNodePosi<T>, int );
ListNodePosi<T> merge ( ListNodePosi<T>, int, List<T> &, ListNodePosi<T>, int );
void mergeSort ( ListNodePosi<T> &, int );
void selectionSort ( ListNodePosi<T>, int );
void insertionSort ( ListNodePosi<T>, int );
void radixSort(ListNodePosi<T>, int);
public:
List() { init(); }
List ( List<T> const& L );
List ( List<T> const& L, Rank r, int n );
List ( ListNodePosi<T> p, int n );
~List();
Rank size() const { return _size; }
bool empty() const { return _size <= 0; }
T& operator[] ( Rank r ) const;
ListNodePosi<T> first() const { return header->succ; }
ListNodePosi<T> last() const { return trailer->pred; }
bool valid ( ListNodePosi<T> p )
{ return p && ( trailer != p ) && ( header != p ); }
ListNodePosi<T> find ( T const& e ) const
{ return find ( e, _size, trailer ); }
ListNodePosi<T> find ( T const& e, int n, ListNodePosi<T> p ) const;
ListNodePosi<T> search ( T const& e ) const
{ return search ( e, _size, trailer ); }
ListNodePosi<T> search ( T const& e, int n, ListNodePosi<T> p ) const;
ListNodePosi<T> selectMax ( ListNodePosi<T> p, int n );
ListNodePosi<T> selectMax() { return selectMax ( header->succ, _size ); }
ListNodePosi<T> insertAsFirst ( T const& e );
ListNodePosi<T> insertAsLast ( T const& e );
ListNodePosi<T> insert ( ListNodePosi<T> p, T const& e );
ListNodePosi<T> insert ( T const& e, ListNodePosi<T> p );
T remove ( ListNodePosi<T> p );
void merge ( List<T> & L ) { merge ( header->succ, _size, L, L.header->succ, L._size ); }
void sort ( ListNodePosi<T> p, int n );
void sort() { sort ( first(), _size ); }
int deduplicate();
int uniquify();
void reverse();
void traverse ( void (* ) ( T& ) );
template <typename VST>
void traverse ( VST& );
};
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;
}
template <typename T>
T& List<T>::operator[] ( Rank r ) const {
ListNodePosi<T> p = first();
while ( 0 < r-- ) p = p->succ;
return p->data;
}
template <typename T>
ListNodePosi<T> List<T>::find ( T const& e, int n, ListNodePosi<T> p ) const {
while ( 0 < n-- )
if ( e == ( p = p->pred )->data ) return p;
return NULL;
}
template <typename T>
ListNodePosi<T> List<T>::search ( T const& e, int n, ListNodePosi<T> p ) const {
do {
p = p->pred; n--;
} while ( ( -1 < n ) && ( e < p->data ) );
return p;
}
template <typename T> ListNodePosi<T> List<T>::insertAsFirst ( T const& e )
{ _size++; return header->insertAsSucc ( e ); }
template <typename T> ListNodePosi<T> List<T>::insertAsLast ( T const& e )
{ _size++; return trailer->insertAsPred ( e ); }
template <typename T> ListNodePosi<T> List<T>::insert ( ListNodePosi<T> p, T const& e )
{ _size++; return p->insertAsSucc ( e ); }
template <typename T> ListNodePosi<T> List<T>::insert ( T const& e, ListNodePosi<T> p )
{ _size++; return p->insertAsPred ( e ); }
template <typename T>
ListNodePosi<T> ListNode<T>::insertAsSucc ( T const& e ) {
ListNodePosi<T> x = new ListNode ( e, this, succ );
succ->pred = x; succ = x;
return x;
}
template <typename T>
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>
void List<T>::copyNodes ( ListNodePosi<T> p, int n ) {
init();
while ( n-- ) { insertAsLast ( p->data ); p = p->succ; }
}
template <typename T>
List<T>::List ( ListNodePosi<T> p, int n ) { copyNodes ( p, n ); }
template <typename T>
List<T>::List ( List<T> const& L ) { copyNodes ( L.first(), L._size ); }
template <typename T>
List<T>::List ( List<T> const& L, Rank r, int n ) {
ListNodePosi<T> p = L.first();
while ( 0 < r-- ) p = p->succ;
copyNodes ( p, n );
}
template <typename T> T List<T>::remove ( ListNodePosi<T> p ) {
T e = p->data;
p->pred->succ = p->succ; p->succ->pred = p->pred;
delete p; _size--;
return e;
}
template <typename T> List<T>::~List()
{ clear(); delete header; delete trailer; }
template <typename T> int List<T>::clear() {
int oldSize = _size;
while ( 0 < _size ) remove ( header->succ );
return oldSize;
}
template <typename T> int List<T>::deduplicate() {
int oldSize = _size; ListNodePosi<T> p = first();
for ( Rank r = 0; p != trailer; p = p->succ )
if ( ListNodePosi<T> q = find(p->data, r, p) )
remove(q);
else r++;
return oldSize - _size;
}
template <typename T> int List<T>::uniquify() {
if ( _size < 2 ) return 0;
int oldSize = _size;
ListNodePosi<T> p = first(); ListNodePosi<T> q;
while ( trailer != ( q = p->succ ) )
if ( p->data != q->data ) p = q;
else remove ( q );
return oldSize - _size;
}
template <typename T> void List<T>::traverse ( void ( *visit ) ( T& ) )
{ for ( ListNodePosi<T> p = header->succ; p != trailer; p = p->succ ) visit ( p->data ); }
template <typename T> template <typename VST>
void List<T>::traverse ( VST& visit )
{ for ( ListNodePosi<T> p = header->succ; p != trailer; p = p->succ ) visit ( p->data ); }
template <typename T> void List<T>::sort ( ListNodePosi<T> p, int n ) {
switch ( rand() % 4 ) {
case 1: insertionSort ( p, n ); break;
case 2: selectionSort ( p, n ); break;
case 3: mergeSort ( p, n ); break;
default: radixSort ( p, n ); break;
}
}
template <typename T>
void List<T>::insertionSort ( ListNodePosi<T> p, int n ) {
for ( int r = 0; r < n; r++ ) {
insert ( search ( p->data, r, p ), p->data );
p = p->succ; remove ( p->pred );
}
}
template <typename T>
void List<T>::selectionSort ( ListNodePosi<T> p, int n ) {
ListNodePosi<T> head = p->pred, tail = p;
for ( int i = 0; i < n; i++ ) tail = tail->succ;
while ( 1 < n ) {
ListNodePosi<T> max = selectMax ( head->succ, n );
insert ( remove ( max ), tail );
tail = tail->pred; n--;
}
}
template <typename T>
void List<T>::mergeSort ( ListNodePosi<T> & p, int n ) {
if ( n < 2 ) return;
int m = n >> 1;
ListNodePosi<T> q = p; for (int i = 0; i < m; i++) q = q->succ;
mergeSort(p, m); mergeSort(q, n - m);
p = merge ( p, m, *this, q, n - m );
}
typedef unsigned int U;
template <typename T>
void List<T>::radixSort ( ListNodePosi<T> p, int n ) {
ListNodePosi<T> head = p->pred; ListNodePosi<T> tail = p;
for ( int i = 0; i < n; i++ ) tail = tail->succ;
for ( U radixBit = 0x1; radixBit && (p = head); radixBit <<= 1 )
for ( int i = 0; i < n; i++ )
radixBit & U (p->succ->data) ?
insert( remove( p->succ ), tail ) : p = p->succ;
}