1.概念与定义

空或者只有一个结点。或者
1、存在唯一的一个被称之为“第一个”的结点。
2、存在唯一的一个被称之为“最后一个”的结点。
3、除第一个结点之外,每个结点均只有一个前驱结点。
4、除最后一个结点之外,每个结点均只有一个后继结点。

2.抽象类

1
2
3
4
5
6
7
8
9
10
11
12
13
template <class elemType>
class list
{
public:
virtual void clear() = 0; //纯虚函数
virtual int length() const = 0;
virtual void insert(int i, const elemType &x) = 0;
virtual void remove(int i) = 0;
virtual int search(const elemType &x) const = 0 ;
virtual elemType visit(int i) const = 0;
virtual void traverse() const = 0;
virtual ~list() {};
};

3.顺序表类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//抽象类的子类
template <class elemType>
class seqList: public list<elemType>
{
private:
elemType *data;
int currentLength;
int maxSize;
void doubleSpace();//扩容
public:
seqList(int initSize = 10);
~seqList() {delete [] data;}
void clear() {currentLength = 0;}
int length() const {return currentLength;}
void insert(int i, const elemType &x);
void remove(int i);
int search(const elemType &x) const ;
elemType visit(int i) const;
void traverse() const ;
};

//构造函数
template <class elemType>
seqList<elemType>::seqList(int initSize)
{
data = new elemType[initSize]; //可增加考虑健壮性
maxSize = initSize;
currentLength = 0;
}

//查找
template <class elemType>
int seqList<elemType>::search(const elemType &x) const
{
for (int i = 0; i < currentLength; i++)
if (i == currentLength) {
return -1;
else return i;
}
}

//遍历
template <class elemType>
int seqList<elemType>::traverse() comst
{
for (int i = 0; i < currentLength; i++)
cout << data[i] << " ";
cout << endl;
}

//插入
//时间复杂度:最好O(1),最坏O(n),平均O(n)
template <class elemType>
void seqList<elemType>::insert(int i, const elemType &x)
{
if (i < 0 || i > currentLength) throw OutOfBound();
if (currentLength == maxSize) doubleSpace();
for (int j = currentLength; j > i; j--) data[j] = data[j-1];
data[i] = x;
++currentLength;
}

//扩充空间
template <class elemType>
void seqList<elemType>::doubleSpace()
{
elemType *tmp = data;
data = new elemType[2 * maxSize];
for (int i = 0; i < currentLength; i++) data[i] = tmp[i];
maxSize *= 2;
delete [] tmp;
}

//删除
template <class elemType>
void seqList<elemType>::remove(int i)
{
if (i < 0 || i > currentLength) throw OutOfBound();
for (int j = i; j < currentLength - 1; j++) data[j] = data[j + 1];
--currentLength;
}

4.链式表类

单链表类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
template <class elemType>
class sLinkList: public list<elemType>
{
private:
struct node
{ //单链表中的结点类
elemType data;
node *next;
node(const elemType &x, node *n = NULL) { data = x; next = n; }
node( ): next(NULL) {}
~node() {}
};
node *head; //头指针
int currentLength; //表长
node *move(int i) const; //返回第i个元素的地址
public:
sLinkList() ;
~sLinkList() {clear(); delete head; }
void clear() ;
int length() const {return currentLength;}
void insert(int i, const elemType &x);
void remove(int i);
int search(const elemType &x) const ;
elemType visit(int i) const;
void traverse() const ;
};

//构造函数
template <class elemType>
sLinkList<elemType>::sLinkList()
{
head = new node; //创建头结点
currentLength = 0;
}

//清空
template <class elemType>
void sLinkList<elemType>::clear()
{
node *p = head->next, *q;
while (p != NULL) {
q = p->next;
delete p;
p = q;
}
head->next = NULL; //重置头结点
currentLength = 0;
}

//返回第i个元素的指针
template <class elemType>
sLinkList<elemType>::node *sLinkList<elemType>::move(int i) const
{
node* p = head;
while (i-- >= 0) p = p->next;
return p;
}

//查找
template <class elemType>
int sLinkList<elemType>::search(const elemType &x) const
{
node *p = head->next;
int i = 0;
while (p != NULL && p->data != x) { p = p->next; ++i; }
if (p == NULL) return -1;
else return i;
}

//遍历
template <class elemType>
void sLinkList<elemType>::traverse() const
{
node *p = head->next;
while (p != NULL) {
cout << p->data << " ";
p = p->next;
}
cout << endl;
}

双链表类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
template <class elemType>
class dLinkList: public list<elemType>
{
private:
struct node { //双链表中的结点类
elemType data;
node *prev, *next;
node(const elemType &x, node *p = NULL, node *n = NULL) { data = x; next = n; prev = p; }
node( ):next(NULL), prev(NULL) {}
~node() {}
};
node *head, *tail; //头尾指针
int currentLength; //表长
node *move(int i) const; //返回第i个元素的地址
public:
dLinkList() ;
~dLinkList() {clear(); delete head; delete tail;}
void clear() ;
int length() const {return currentLength;}
void insert(int i, const elemType &x);
void remove(int i);
int search(const elemType &x) const ;
elemType visit(int i) const;
void traverse() const ;
};

//构造函数
template <class elemType>
dLinkList<elemType>::dLinkList()
{
head = new node; //创建头结点
tail = new node; //创建尾结点
head->next = tail; //头结点指向尾结点
tail->prev = head; //尾结点指向头结点
currentLength = 0;
}

//插入
template <class elemType>
void dLinkList<elemType>::insert(int i, const elemType &x)
{
node *pos, *tmp;
pos = move(i); //注意,move需要自行实现
tmp = new node(x, pos->prev, pos); //结点构造函数
pos->prev->next = tmp;
pos->prev = tmp;
++currentLength;
}

//删除
template <class elemType>
void dLinkList<elemType>::remove(int i)
{
node *pos;
pos = move(i); //注意,move需要自行实现
pos->prev->next = pos->next;
pos->next->prev = pos->prev;
delete pos;
--currentLength;
}

双向链表中查找、访问、遍历等操作与单链表类似,只是需要注意前驱和后继指针的使用,此处不再实现。

单循环链表类

  • 一般单循环链表不带头结点。
  • Head为头指针。(头指针和头结点有区别)
  • 插入操作时间复杂度为O(1),删除操作时间复杂度为O(n),查找操作时间复杂度为O(n)。

双循环链表类

  • 首元素中prior字段给出尾元素的地址,尾元素中next字段给出首元素的地址。
  • 一般也不设头尾结点(注意头/尾结点;头/尾指针;首/尾元素的区分)
  • 插入操作时间复杂度为O(1),删除操作时间复杂度为O(n),查找操作时间复杂度为O(n)。