本文贴出邓俊辉教授所编写教材《数据结构C++版》的列表一部分的全部实现代码,供大家参考,交流学习。
#include<iostream>
#include<algorithm>
#include<functional>
#include<cstdlib>
#include<ctime>
using namespace std;
typedef int Rank;
#define ListNodePosi(T) 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) p, int n);
void merge(ListNodePosi(T)& p, int n, List<T>& L, ListNodePosi(T) q, int m);
void mergeSort(ListNodePosi(T)& p, int n);
void selectionSort(ListNodePosi(T) p, int n);
void insertionSort(ListNodePosi(T) p, int n);
public:
List()
{
init();
}
List(List<T> const& L);
List(List<T> const& L, int 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) insertA(ListNodePosi(T) p, T const& e);
ListNodePosi(T) insertB(ListNodePosi(T) p, T const& e);
T remove(ListNodePosi(T) p);
void merge(List<T>& L)
{
merge(first(), size, L, L.first(), L._size);
}
void sort(ListNodePosi(T) p, int n);
void sort()
{
sort(first(), _size);
}
int deduplicate();
int uniquify();
void reverse();
void traverse(void (*visit) (T&));
template <typename VST>
void traverse(VST&);
};
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>
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>
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>
int List<T>::clear()
{
int oldSize = _size;
while (0 < _size)
{
remove(header->succ);
}
return oldSize;
}
template <typename T>
void List<T>::copyNodes(ListNodePosi(T) p, int n)
{
init();
while (n--)
{
insertAsLast(p->data);
p = p->succ;
}
}
template <typename T>
void List<T>::merge(ListNodePosi(T)& p, int n, List<T>& L, ListNodePosi(T) q, int m)
{
ListNodePosi(T) pp = p->pred;
while (0 < m)
{
if ((0 < n) && (p->data <= q->data))
{
if (q == (p = p->succ)) break; n--;
}
else
{
insertB(p, L.remove((q = q->succ)->pred)); m--;
}
}
p = pp->succ;
}
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);
merge(p, m, *this, q, n - m);
}
template <typename T>
void List<T>::selectionSort(ListNodePosi(T) p, int n)
{
ListNodePosi(T) head = p->pred;
ListNodePosi(T) tail = p;
for (int i = 0; i < n; i++)
{
tail = tail->succ;
}
while (1 < n)
{
ListNodePosi(T) max = selectMax(head->succ, n);
insertB(tail, remove(max));
tail = tail->pred;
n--;
}
}
template <typename T>
void List<T>::insertionSort(ListNodePosi(T) p, int n)
{
for (int r = 0; r < n; r++)
{
insertA(search(p->data, r, p), p->data);
p = p->succ;
remove(p->pred);
}
}
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, int r, int n)
{
ListNodePosi(T) p = L.first();
while (0 < r--)
{
p = p->succ;
}
copyNodes(p, n);
}
template <typename T> List<T>::~List()
{
clear();
delete header;
delete trailer;
}
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>
static bool lt(T* a, T* b)
{
return lt(*a, *b);
}
template <typename T>
static bool lt(T& a, T& b)
{
return a < b;
}
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));
printf("\n");
return p;
}
template <typename T>
ListNodePosi(T) List<T>::selectMax(ListNodePosi(T) p, int n)
{
ListNodePosi(T) max = p;
for (ListNodePosi(T) cur = p; 1 < n; n--)
{
if (!lt((cur = cur->succ)->data, max->data))
{
max = cur;
}
}
return max;
}
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>::insertA(ListNodePosi(T) p, T const& e)
{
_size++;
return p->insertAsSucc(e);
}
template <typename T>
ListNodePosi(T) List<T>::insertB(ListNodePosi(T) p, T const& e)
{
_size++;
return p->insertAsPred(e);
}
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>
void List<T>::sort(ListNodePosi(T) p, int n)
{
switch (rand() % 3)
{
case 1:
{
insertionSort(p, n);
break;
}
case 2:
{
selectionSort(p, n);
break;
}
default:
{
mergeSort(p, n);
break;
}
}
}
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>::reverse()
{
ListNodePosi(T) p = header;
ListNodePosi(T) q = trailer;
for (int i = 1; i < _size; i += 2)
{
swap((p = p->succ)->data, (q = q->pred)->data);
}
}
template <typename T>
void List<T>::traverse(void (*visit) (T&))
{
int i = 0;
for (ListNodePosi(T) p = header->succ; p != trailer; p = p->succ)
{
visit(p->data);
i++;
if (i % 10 == 0)
{
cout << endl;
}
}
}
template<typename T>
void visit(T& elem)
{
cout << elem << '\t';
}
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);
}
}
int main()
{
List<int>obj;
cout << "------------------01.Initial list:-----------------" << endl;
srand((unsigned)time(NULL));
for (int i = 0; i < 10; i++)
{
obj.insertAsFirst(rand() % 1000);
obj.insertAsLast(rand() % 2000);
}
cout << "Insert successed!" << endl;
cout << endl;
cout << "------------------02.Traverse list:-----------------" << endl;
obj.traverse(visit);
cout << endl;
cout << "------------------03.Insert values at head:-----------------" << endl;
obj.insertAsFirst(1);
obj.traverse(visit);
cout << endl;
cout << "------------------04.Insert values at end:-----------------" << endl;
obj.insertAsLast(2);
obj.traverse(visit);
cout << endl;
cout << "------------------05.find a element with a concret value:-----------------" << endl;
ListNode<int>* aNode = obj.find(1);
if (aNode != NULL)
{
cout << "An element with a value 1 was founded!" << endl;
}
else
{
cout << "An element with a value 1 was not founded!" << endl;
}
cout << endl;
cout << "------------------06.report the size of this list:-----------------" << endl;
int x = obj.size();
cout << "the size of this list is:" << x << endl;
cout << endl;
cout << "------------------07.get the position of head of this list:-----------------" << endl;
ListNode<int>* h = obj.first();
cout << "the address of the first node of this list on my computer is:" << h << endl;
cout << endl;
cout << "------------------08.get the position of tail of this list:-----------------" << endl;
ListNode<int>* t = obj.last();
cout << "the address of the last node of this list on my computer is:" << t << endl;
cout << endl;
cout << "------------------09.test insert a node at left of aother node:-----------------" << endl;
obj.insertA(t, 250);
obj.traverse(visit);
cout << endl;
cout << "------------------10.test insert a node at right of aother node:-----------------" << endl;
obj.insertB(t, 250);
obj.traverse(visit);
cout << endl;
cout << "------------------11.remove a node:-----------------" << endl;
obj.remove(t);
obj.traverse(visit);
cout << endl;
cout << "------------------13.sort list:-----------------" << endl;
obj.sort();
obj.traverse(visit);
cout << endl;
cout << "------------------14.search a node in this list:-----------------" << endl;
ListNode<int>* res = obj.search(20);
cout << "the result of searching:" << (res->data == 20 ? "success" : "failed") << endl;
cout << endl;
cout << "------------------15.uniquify this list:-----------------" << endl;
obj.uniquify();
obj.traverse(visit);
cout << endl;
cout << "------------------16.dedupliacate this list:-----------------" << endl;
obj.insertAsFirst(10);
obj.insertAsFirst(10);
obj.insertAsFirst(10);
cout << endl;
cout << "before deduplicated:" << endl;
obj.traverse(visit);
obj.deduplicate();
cout << endl;
cout << "after deduplicated:" << endl;
obj.traverse(visit);
system("pause");
return 0;
}
在这里值得注意的是,你可能会对,这样一段代码
#define ListNodePosi(T) ListNode<T>
产生怀疑或者误解,不过这样做这样未免显得有些多余,在C++早期的版本之中这样的语法格式的确是合法的。