List(C++模版实现的带哨兵的双向链表)
# ifndef C11LEARN_LIST_H
# define C11LEARN_LIST_H
template < typename T >
class List
{
protected : class Node { public : Node * pre; Node * next; T key; Node ( ) { } Node ( const T key) : key ( key) { } } ; private : Node* Nil; int size;
public : List ( ) ; virtual ~ List ( ) ; List ( const List< T> & list) ; const List< T> & operator = ( const List< T> & list) ; const List< T> & operator + ( const List< T> & list) ; const List< T> & operator - ( const List< T> & list) ; List< T> merge ( const List< T> & list) ; List< T> except ( const List< T> & list) ; List< T> intersect ( const List< T> & list) ; void add ( const T key) ; void insert ( const T key, int position) ; bool remove ( const T key) ; bool remove_all ( const T key) ; bool remove_at ( int index) ; bool contain ( const T & key) ; T operator [ ] ( int index) const ; T & operator [ ] ( int index) ; bool empty ( ) ; void clear ( ) ; int length ( ) const ; int length ( ) ; void sort ( bool ascending = true ) ; void sort ( void ( * f) ( T * array, int length) ) ; const List< T> & distinct ( ) ;
private : Node* search ( const T & key) ;
Node* get ( int index) const ; void add ( Node* node) ; bool remove ( Node* node) ; void quick_sort ( T* array, int start, int end, bool ascending = true ) ; int partition ( T* array, int start, int end, bool ascending) ;
} ; template < typename T >
List < T> :: List ( )
{ Nil = new Node ( ) ; Nil-> next = Nil; Nil-> pre = Nil; size = 0 ;
}
template < typename T >
List< T> :: ~ List ( ) { clear ( ) ; delete Nil;
}
template < typename T >
List < T> :: List ( const List< T> & list)
{ Nil = new Node ( ) ; Nil-> next = Nil; Nil-> pre = Nil; size = 0 ; Node * current = list. Nil-> next; while ( current != list. Nil) { add ( current-> key) ; current = current-> next; }
}
template < typename T >
const List< T> & List< T> :: operator = ( const List< T> & list) { if ( & list == this ) return * this ; clear ( ) ; Node * current = list. Nil-> next; while ( current != list. Nil) { add ( current-> key) ; current = current-> next; } return * this ;
}
template < typename T >
List< T> List < T> :: merge ( const List< T> & list)
{ List< T> temp ( * this ) ; temp. distinct ( ) ; Node* current = list. Nil-> next; while ( current!= list. Nil) { if ( ! temp. contain ( current-> key) ) { temp. add ( current-> key) ; } current = current-> next; } return temp;
}
template < typename T >
List< T> List < T> :: except ( const List< T> & list) { List< T> temp ( * this ) ; temp. distinct ( ) ; Node* current = list. Nil-> next; while ( current!= list. Nil) { if ( temp. contain ( current-> key) ) { temp. remove ( current-> key) ; } current = current-> next; } return temp;
}
template < typename T >
List< T> List < T> :: intersect ( const List< T> & list) { List< T> temp; Node* current = list. Nil-> next; while ( current!= list. Nil) { if ( contain ( current-> key) ) { temp. add ( current-> key) ; } current = current-> next; } temp. distinct ( ) ; return temp;
}
template < typename T >
const List< T> & List < T> :: distinct ( ) { if ( size == 0 ) return * this ; T* array = new T[ size] ; int index = 0 ; Node* current = Nil-> next; while ( current!= Nil) { array[ index] = current-> key; current = current-> next; index++ ; } quick_sort ( array, 0 , size- 1 ) ; T current_key = array[ 0 ] ; for ( int i = 1 ; i < size; ++ i) { if ( current_key == array[ i] ) { remove ( current_key) ; } else { current_key = array[ i] ; } } delete [ ] array; return * this ;
}
template < typename T >
void List < T> :: add ( const T key)
{ Node* node = new Node ( key) ; size++ ; add ( node) ;
}
template < typename T >
void List < T> :: add ( Node* node) { if ( Nil-> next == Nil) { Nil-> pre = node; Nil-> next = node; node-> pre = Nil; node-> next = Nil; } else { Nil-> pre-> next = node; node-> pre = Nil-> pre; node-> next = Nil; Nil-> pre = node; }
}
template < typename T >
void List < T> :: insert ( const T key, int position)
{ if ( position< 0 || position> size) throw "out of bound" ; if ( position == size || size == 0 ) { add ( key) ; } else { Node* node = new Node ( key) ; Node* current = get ( position) ; current-> pre-> next = node; node-> pre = current-> pre; node-> next = current; current-> pre = node; size++ ; if ( position == 0 ) { Nil-> next = node; } }
}
template < typename T >
bool List < T> :: remove ( const T key) { Node * result = search ( key) ; if ( result!= Nil) { remove ( result) ; return true ; } return false ;
}
template < typename T >
bool List < T> :: contain ( const T& key) { return search ( key) != Nil;
}
template < typename T >
bool List < T> :: empty ( ) { return Nil-> next == Nil;
}
template < typename T >
typename List < T> :: Node* List < T> :: search ( const T & key) { Node * current = Nil-> next; while ( current != Nil && current-> key!= key) { current = current-> next; } return current;
}
template < typename T >
bool List < T> :: remove ( Node* node) { if ( empty ( ) ) return false ; node-> pre-> next = node-> next; node-> next-> pre = node-> pre; size -- ; delete node; return true ;
}
template < typename T >
void List < T> :: clear ( ) { Node* current = Nil-> next; while ( current!= Nil) { Node * temp = current; current = current-> next; delete temp; } Nil-> next = Nil; Nil-> pre = Nil; size = 0 ;
}
template < typename T >
int List < T> :: length ( ) const { return size;
}
template < typename T >
int List < T> :: length ( ) { return size;
}
template < typename T >
T List< T> :: operator [ ] ( int index) const { return get ( index) -> key;
}
template < typename T >
T & List< T> :: operator [ ] ( int index) { return get ( index) -> key;
}
template < typename T >
typename List < T> :: Node* List < T> :: get ( int index) const { if ( index>= size || index < 0 ) throw "Index out of bounds" ; Node * current; if ( index>= size/ 2 ) { index = size - index - 1 ; current = Nil-> pre; while ( index-- > 0 ) { current = current-> pre; } } else { current = Nil-> next; while ( index-- > 0 ) { current = current-> next; } } return current;
}
template < typename T >
bool List < T> :: remove_at ( int index) { if ( index>= size) return false ; return remove ( get ( index) ) ;
}
template < typename T >
void List < T> :: quick_sort ( T* array, int start, int end, bool ascending) { if ( start< end) { int k = partition ( array, start, end, ascending) ; quick_sort ( array, start, k- 1 , ascending) ; quick_sort ( array, k+ 1 , end, ascending) ; }
}
template < typename T >
int List < T> :: partition ( T* array, int start, int end, bool ascending) { T key = array[ end] ; int p = start - 1 ; T temp; for ( int i = start; i < end; ++ i) { if ( ( array[ i] <= key && ascending) || ( array[ i] >= key && ! ascending) ) { p++ ; temp = array[ p] ; array[ p] = array[ i] ; array[ i] = temp; } } array[ end] = array[ p+ 1 ] ; array[ p+ 1 ] = key; return p+ 1 ;
}
template < typename T >
void List < T> :: sort ( bool ascending) { if ( size == 0 ) return ; T* array = new T[ size] ; Node* current = Nil-> next; int index = 0 ; while ( current!= Nil) { array[ index] = current-> key; current = current-> next; index++ ; } quick_sort ( array, 0 , size - 1 , ascending) ; int length = size; clear ( ) ; for ( int i = 0 ; i < length; ++ i) { add ( array[ i] ) ; } delete [ ] array;
}
template < typename T >
void List < T> :: sort ( void ( * f) ( T * array, int length) ) { if ( size == 0 ) return ; T* array = new T[ size] ; Node* current = Nil-> next; int index = 0 ; while ( current!= Nil) { array[ index] = current-> key; current = current-> next; index++ ; } f ( array, size) ; int length = size; clear ( ) ; for ( int i = 0 ; i < length; ++ i) { add ( array[ i] ) ; } delete [ ] array;
}
template < typename T >
const List< T> & List< T> :: operator + ( const List< T> & list) { Node* current = list. Nil-> next; while ( current!= list. Nil) { add ( current-> key) ; current = current-> next; } return * this ;
}
template < typename T >
const List< T> & List< T> :: operator - ( const List< T> & list) { Node* current = list. Nil-> next; while ( current!= list. Nil) { remove_all ( current-> key) ; current = current-> next; } return * this ;
}
template < typename T >
bool List < T> :: remove_all ( const T key) { Node* current = Nil-> next; bool success = false ; while ( current!= Nil) { if ( current-> key == key) { success = true ; Node* node = current; current = current-> next; node-> pre-> next = node-> next; node-> next-> pre = node-> pre; size -- ; delete node; } else { current = current-> next; } } return success;
}
# endif