1. 线性表抽象类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#pragma once
template <class T>
class LinearList
{
public:
// 线性表是否为空
virtual bool empty() const = 0;
// 线性表大小
virtual int size() const = 0;
// 根据ID获取线性表元素
virtual T& get(int theIndex) const = 0;
// 根据元素获取元素对应ID
virtual int indexOf(const T& theElement) const = 0;
// 删除ID处的元素
virtual void erase(int theIndex) = 0;
// 在ID处插入元素
virtual void insert(int theIndex, const T& theElement) = 0;
// 输出线性表
virtual void output() = 0;
};

2. 线性表的数组描述

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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include"linearList.h"
#include<iostream>
using namespace std;

template<class T>
class ArrayList :public LinearList<T>
{
protected:
T* element; // 线性表元素指针
int arrayLength; // 容量
int listSize; // 元素个数
bool checkIndex(int theIndex) const; // 检查索引是否有效
void changeLength(); // 扩充数组长度

public:
// 构造函数
ArrayList(int initialCapacity = 10);
// 拷贝构造函数
ArrayList(const ArrayList<T>& theList);
// 析构函数
~ArrayList()
{
delete[] element;
}

// 线性表是否为空
bool empty() const { return listSize == 0; }

// 线性表大小
int size() const { return listSize; }

// 线性表容量
int capacity() const { return arrayLength; }

// 根据ID获取线性表元素
T& get(int theIndex) const;

// 根据元素获取元素对应ID
int indexOf(const T& theElement) const;

// 删除ID处的元素
void erase(int theIndex);

// 在ID处插入元素
void insert(int theIndex, const T& theElement);

// 输出线性表
void output();

};


// 构造函数
template<class T>
ArrayList<T>::ArrayList(int initialCapacity)
{
if (initialCapacity < 1)
{
cout << "初始化容量必须大于0" << endl;
return;
}
this->arrayLength = initialCapacity;
this->element = new T[arrayLength];
listSize = 0;
}

// 复制构造函数
template<class T>
ArrayList<T>::ArrayList(const ArrayList<T>& theList)
{
this->arrayLength = theList.arrayLength;
this->listSize = theList.listSize;
this->element = new T[arrayLength];
copy(theList.element, theList.element + listSize, element);
}

// 越界, false 表示越界, true 表示没有越界
template<class T>
bool ArrayList<T>::checkIndex(int theIndex) const
{
bool ret = !(theIndex < 0 || theIndex > listSize);
return ret;
}


// 获取元素
template<class T>
T& ArrayList<T>::get(int theIndex) const
{
if (checkIndex(theIndex))
{
return element[theIndex];
}
}

// 根据元素获取ID
template<class T>
int ArrayList<T>::indexOf(const T& theElement) const
{
int theIndex = (int)find(element, element + listSize, theElement);
return theIndex == listSize ? -1 : (theIndex-(int)element)/sizeof(T);
}

// 删除ID处元素
template<class T>
void ArrayList<T>::erase(int theIndex)
{
if (checkIndex(theIndex))
{
copy(element + theIndex + 1, element + listSize, element + theIndex);
element[--listSize].~T();
}
}

// 扩充数组长度
template<class T>
void ArrayList<T>::changeLength()
{
T* temp = new T[arrayLength * 2];
copy(element, element + arrayLength, temp);
delete[] element;
element = temp;
arrayLength = 2 * arrayLength;
}


// 在ID处插入元素
template<class T>
void ArrayList<T>::insert(int theIndex, const T& theElement)
{
if (!checkIndex(theIndex))
{
cout << "无效索引" << endl;
return;
}
if (listSize == arrayLength)
{
changeLength();
}
copy_backward(element + theIndex, element + listSize, element + listSize + 1);
element[theIndex] = theElement;
listSize++;
}

// 输出线性表
template<class T>
void ArrayList<T>::output()
{
for (int i = 0; i < listSize; i++)
{
cout << element[i] << " ";
}
cout << endl;
}

3. 线性表的链式描述

3.1 结点结构体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#pragma once
#include<iostream>
using namespace std;
template <class T>
struct ChainNode
{
// 数据成员
T element;
ChainNode<T>* next;

// 方法
ChainNode() {}
ChainNode(const T& element)
{
this->element = element;
}
ChainNode(const T& element, ChainNode<T>* next)
{
this->element = element;
this->next = next;
}
};

3.2 线性表实现

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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include"linearList.h"
#include"chianNode.h"
#include<iostream>
using namespace std;
template<class T>
class Chain :public LinearList<T>
{
protected:
ChainNode<T>* firstNode;
int listSize;
bool checkIndex(int theIndex) const;

public:
Chain(int initialCapacity = 10);
Chain(const Chain<T>&);
~Chain();

bool empty() const { return listSize == 0; };
// 线性表大小
int size() const { return listSize; }
// 根据ID获取线性表元素
T& get(int theIndex) const;
// 根据元素获取元素对应ID
int indexOf(const T& theElement) const;
// 删除ID处的元素
void erase(int theIndex);
// 在ID处插入元素
void insert(int theIndex, const T& theElement);
// 输出线性表
void output();
};

// 普通的构造函数
template<class T>
Chain<T>::Chain(int initialCapacity)
{
if (initialCapacity < 1)
{
cout << "初始容量设置必须大于0" << endl;
}
firstNode = NULL;
listSize = 0;
}

// 拷贝构造函数
template<class T>
Chain<T>::Chain(const Chain<T>& theList)
{
listSize = theList.listSize;
if (listSize == 0)
{
firstNode = NULL;
return;
}
ChainNode<T>* sourceNode = theList.firstNode;
firstNode = new ChainNode<T>(sourceNode->element);
sourceNode = sourceNode->next;
ChainNode<T>* targetNode = firstNode;
while (sourceNode != NULL)
{
targetNode->next = new ChainNode<T>(sourceNode->element);
targetNode = targetNode->next;
sourceNode = sourceNode->next;
}
targetNode->next = NULL;
}

// 析构函数
template<class T>
Chain<T>::~Chain()
{
while (firstNode != NULL)
{
ChainNode<T>* nextNode = firstNode->next;
delete firstNode;
firstNode = nextNode;
}
}

template<class T>
T& Chain<T>::get(int theIndex) const
{
if (checkIndex(theIndex))
{
ChainNode<T>* currentNode = firstNode;
for (int i = 0; i < theIndex; i++)
{
currentNode = currentNode->next;
}
return currentNode->element;
}
}

template<class T>
int Chain<T>::indexOf(const T& theElement) const
{
ChainNode<T>* currentNode = firstNode;
int index = 0;
while (currentNode->element != theElement && currentNode != NULL)
{
currentNode = currentNode->next;
index++;
}
return currentNode == NULL ? -1 : index;
}

template<class T>
void Chain<T>::erase(int theIndex)
{
if (checkIndex(theIndex))
{
ChainNode<T>* deleteNode;
if (theIndex == 0)
{
deleteNode = firstNode;
firstNode = firstNode->next;
}
else if (theIndex < listSize - 1)
{
ChainNode<T>* p = firstNode;
for (int i = 0; i < theIndex - 1; i++)
{
p = p->next;
}
deleteNode = p->next;
p->next = p->next->next;
}
else
{
ChainNode<T>* p = firstNode;
for (int i = 0; i < theIndex; i++)
{
p = p->next;
}
deleteNode = p;
p->next = NULL;
}
listSize--;
delete deleteNode;
}
}

template<class T>
void Chain<T>::insert(int theIndex, const T& theElement)
{
if (checkIndex(theIndex))
{
if (theIndex == 0)
{
firstNode = new ChainNode<T>(theElement, firstNode);
}
else
{
ChainNode<T>* p = firstNode;
for (int i = 0; i < theIndex - 1; i++)
{
p = p->next;
}
p->next = new ChainNode<T>(theElement, p->next);
}
listSize++;
}
}


template<class T>
void Chain<T>::output()
{
ChainNode<T>* currentNode = firstNode;
while (currentNode != NULL)
{
cout << currentNode->element << " ";
currentNode = currentNode->next;
}
cout << endl;
}

template<class T>
bool Chain<T>::checkIndex(int theIndex) const
{
bool ret = !(theIndex < 0 || theIndex > listSize);
return ret;
}