数据结构上机题(C++语言)

说在前面的话

最近整理电脑上的文件,翻出来大二数据结构上机时写的代码。现在看来那些代码写得都挺丑的,却还有些纪念意义,挂到博客上来保存一下吧。

相关代码已经上传至码云,点击查看


特殊环形队列

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
#include<iostream>
using namespace std;
template<class T>
class Queue{
public:
void Clear();
bool EnQueue(const T item);
bool DeQueue(T & item);
bool IsEmpty();
bool IsFull();
bool GetFront(T & item);
};
template<class T>
class ArrayQueue:public Queue<T>{
private:
bool tag;
int maxSize;
int Front;
int Rear;
int *Queue;
public:
ArrayQueue(int Size){
maxSize = Size;
Queue = new T[maxSize];
Front = Rear = 0;
tag = 0;
}
~ArrayQueue(){
delete []Queue;
}
void Clear(){
Front = Rear;
tag = 0;
}
bool EnQueue(const T item){
if(Rear == Front && tag){
cout<<"队列已满,溢出"<<endl;
return false;
}
tag = 1;
Queue[Rear] = item;
Rear = (Rear +1) % maxSize;
return true;
}
bool DeQueue(T & item){
if(Front == Rear && !tag){
cout<<"队列为空"<<endl;
return false;
}
item = Queue[Front];
Front = (Front+1) % maxSize;
if(Front == Rear){
tag = 0;
}
return true;
}
bool GetFront(T & item){
if(Front == Rear && !tag){
cout<<"队列为空"<<endl;
tag = 0;
return false;
}
item = Queue[Front];
return true;
}
};
int main(){
ArrayQueue<int> q(3);
int temp;
cin>>temp;
while(temp != -1 && q.EnQueue(temp)){
cin>>temp;
}
while(q.DeQueue(temp)){
cout<<temp<<' ';
}
return 0;
}

二叉树

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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
#include<iostream>
#include<queue>
#include<stack>
using namespace std;
enum Tags {Left,Right}; // 定义枚举类型标志位
template<class T>
class StackElement;
template<class T>
class BinaryTreeNode
{
public:
T info; // 二叉树结点数据域
BinaryTreeNode<T> * left;
BinaryTreeNode<T> * right;
BinaryTreeNode() {} // 缺省构造函数
BinaryTreeNode(const T& ele) // 给定数据的构造函数
{
info = ele;
left = NULL;
right = NULL;
}
BinaryTreeNode(const T& ele,BinaryTreeNode<T> *l, BinaryTreeNode<T> *r) // 子树构造结点
{
info = ele;
left = l;
right = r;
}
};
template <class T>
class BinaryTree
{
public:
BinaryTreeNode<T> * root; // 二叉树根结点
BinaryTree() // 构造函数
{
root = NULL;
}
~BinaryTree() // 析构函数
{
deleteBinaryTree(root);
}
//创建二叉树
void create(BinaryTreeNode<T>* &temp)
{
T data;
int flag1,flag2;
cout<<"请按格式输入:数据,是否有左节点(1/0),是否有右节点(1/0)"<<endl;
cin>>data>>flag1>>flag2;
temp = new BinaryTreeNode<T>(data);
if(flag1 && flag2)
{
create(temp->left);
create(temp->right);
}
else if(flag1)
{
create(temp->left);
}
else if(flag2)
{
create(temp->right);
}
else
{
}
}
//按照水平顺序打印二叉树
void levelOrderPrint(BinaryTreeNode<T> *root)
{
queue<BinaryTreeNode<T>*> aQueue;
BinaryTreeNode<T> *pointer = root;
if (pointer)
{
aQueue.push(pointer); // 根结点入队列
}
while (!aQueue.empty()) // 队列非空
{
pointer = aQueue.front(); // 获得队列首结点
cout<<pointer->info<<' ';
aQueue.pop(); // 当前结点出队列
if (pointer->left != NULL)
aQueue.push(pointer->left); // 左子树进队列
if (pointer->right != NULL)
aQueue.push(pointer->right); // 右子树进队列
}
}
//计算度为2、1、0的节点的个数
void levelOrderCounter(BinaryTreeNode<T> *root)
{
int counter0 = 0,counter1 = 0,counter2 = 0;
char Max = root->info;
queue<BinaryTreeNode<T>*> aQueue;
BinaryTreeNode<T> *pointer = root;
if (pointer)
{
aQueue.push(pointer); // 根结点入队列
}
while (!aQueue.empty()) // 队列非空
{
pointer = aQueue.front(); // 获得队列首结点
if(pointer->info > Max)
Max = pointer->info;
if(pointer->left && pointer->right)
counter0++;
else if(pointer->left || pointer->right)
counter1++;
else
counter2++;
aQueue.pop(); // 当前结点出队列
if (pointer->left != NULL)
aQueue.push(pointer->left); // 左子树进队列
if (pointer->right != NULL)
aQueue.push(pointer->right); // 右子树进队列
}
cout<<"度为2的节点:"<<counter0<<" 度为1的节点:"<<counter1<<" 度为0的节点:"<<counter2<<endl;
cout<<"最大值为:"<<Max<<endl;
}
//递归删除二叉树
void deleteBinaryTree(BinaryTreeNode<T> *temp)
{
if(temp->left)
deleteBinaryTree(temp->left);
if(temp->right)
deleteBinaryTree(temp->right);
delete(temp);
}
//获取根节点
BinaryTreeNode<T>* Root()
{
return root;
}
//计算树的最大深度
void BiTreeDepth(BinaryTreeNode<T> * p, int level, int &depth) // T指向二叉树的根,level 为 T 所指结点所在层次,其初值为1
{
//depth 为当前求得的最大层次,其初值为1
if (p)
{
if (level>depth) depth = level;
BiTreeDepth(p->left, level+1, depth);
BiTreeDepth(p->right, level+1, depth);
}
}
//旋转树
void ChangePos(BinaryTreeNode<T> * root)
{
BinaryTreeNode<T> * temp;
if (root != NULL) //非空
{
//交换当前结点左右孩子的位置
temp = root->left;
root->left = root->right;
root->right = temp;
//递归交换
ChangePos(root->left);
ChangePos(root->right);
}
}
void BiTreeLevelCounter(BinaryTreeNode<T> * p, int level, int arr[], int n) // T指向二叉树的根,level 为 T 所指结点所在层次,其初值为1
{
//depth 为当前求得的最大层次,其初值为1
if (p)
{
arr[level-1]++;
BiTreeLevelCounter(p->left, level+1, arr, n);
BiTreeLevelCounter(p->right, level+1, arr, n);
}
}
bool levelOrderComplete(BinaryTreeNode<T> *root)
{
queue<BinaryTreeNode<T>*> aQueue;
BinaryTreeNode<T> *pointer = root;
int flag = 0;
if (pointer)
{
aQueue.push(pointer); // 根结点入队列
}
while (!aQueue.empty()) // 队列非空
{
pointer = aQueue.front(); // 获得队列首结点
/*
if(pointer->left != NULL && flag)
return false;
if(pointer->left == NULL){
flag = 1;
}
if(pointer->right != NULL && flag)
return false;
if(pointer->right == NULL)
flag = 1;
*/
aQueue.pop(); // 当前结点出队列
if (pointer->left != NULL)
{
if(flag)
return false;
else
aQueue.push(pointer->left); // 左子树进队列
}
else
flag = 1;
if (pointer->right != NULL)
{
if(flag)
return false;
else
aQueue.push(pointer->right); // 右子树进队列
}
else
flag = 1;
}
return true;
}
void PreOrder (BinaryTreeNode<T> *root)
{
// 前序遍历二叉树或其子树
if (root != NULL)
{
cout<<root->info<<' ';
PreOrder(root->left); // 前序遍历左子树
PreOrder(root->right); // 前序遍历右子树
}
}
//前序非递归遍历
void PreOrderWithoutRecursion(BinaryTreeNode<T> *root)
{
stack<BinaryTreeNode<T>*> aStack;
BinaryTreeNode<T> *pointer = root;
while (!aStack.empty() || pointer)
{
if(pointer)
{
cout<<pointer->info<<' '; // 访问当前结点
if (pointer->right != NULL) // 非空右孩子入栈
aStack.push(pointer->right);
pointer = pointer->left;
}
else
{
pointer = aStack.top(); // 获得栈顶元素
aStack.pop(); // 栈顶元素退栈
}
}
}
//中序遍历
void InOrder (BinaryTreeNode<T> *root)
{
// 中序遍历二叉树或其子树
if (root != NULL)
{
InOrder (root->left); // 中序周游左子树
cout<<root->info<<' '; // 访问当前结点
InOrder(root->right); // 中序周游右子树
}
}
//中续费递归遍历
void InOrderWithoutRecursion(BinaryTreeNode<T> *root)
{
// 使用STL中的栈
stack<BinaryTreeNode<T>* > aStack;
BinaryTreeNode<T> *pointer = root;
while (!aStack.empty() || pointer)
{
if (pointer)
{
aStack.push(pointer); // 当前指针入栈
pointer = pointer->left; // 左路下降
}
else // 左子树访问完毕,转向访问右子树
{
pointer = aStack.top(); // 获得栈顶元素
aStack.pop(); // 栈顶元素退栈
cout<<pointer->info<<' '; // 访问当前结点
pointer = pointer->right; // 指针指向右孩子
}
}
}
//后序遍历
void PostOrder(BinaryTreeNode<T> *root)
{
// 后序遍历二叉树或其子树
if (root != NULL)
{
PostOrder(root->left); // 后序遍历左子树
PostOrder (root->right); // 后序遍历右子树
cout<<root->info<<' '; // 访问当前结点
}
}
//后续非递归遍历
void PostOrderWithoutRecursion(BinaryTreeNode<T>* root)
{
StackElement<T> element;
stack<StackElement<T > > aStack;
BinaryTreeNode<T>* pointer;
if (root == NULL) // 如果是空树则返回
return;
else pointer = root;
while (!aStack.empty() || pointer)
{
//如果当前指针非空则压栈并下降到最左子结点
while (pointer != NULL)
{
element.pointer = pointer;
element.tag = Left; // 置标志位为Left, 表示进入左子树
aStack.push(element);
pointer = pointer->left;
}
element = aStack.top(); // 获得栈顶元素
aStack.pop(); // 栈顶元素退栈
pointer = element.pointer;
if (element.tag == Left) // 如果从左子树回来
{
element.tag = Right; // 置标志位为Right, 表示进入右子树
aStack.push(element);
pointer = pointer->right;
}
else // 如果从右子树回来
{
cout<<pointer->info<<' '; // 访问当前结点
pointer = NULL; // 置point指针为空,以继续弹栈
}
}
}
//删除叶子
void deleteLeave(BinaryTreeNode<T>* temp)
{
if(temp == NULL)
return ;
if(temp->left == NULL && temp->right == NULL)
{
cout<<temp->info<<' ';
delete temp;
temp = NULL;
return ;
}
if(temp->left)
if(temp->left->left == NULL && temp->left->right == NULL){
cout<<temp->left->info<<' ';
delete temp->left;
temp->left = NULL;
}
if(temp->right)
if(temp->right->left == NULL && temp->right->right == NULL){
cout<<temp->right->info<<' ';
delete temp->right;
temp->right = NULL;
}
deleteLeave(temp->left); // 前序遍历左子树
deleteLeave(temp->right); // 前序遍历右子树
}
};
template <class T>
class StackElement // 栈元素的定义
{
public:
BinaryTreeNode<T>* pointer; // 指向二叉树结点的指针
Tags tag; // 标志位
};
int main()
{
BinaryTree<char> b1;
b1.create(b1.root); //建立二叉树
cout<<"广度优先遍历:";
b1.levelOrderPrint(b1.root); //广度优先遍历
cout<<endl;
cout<<"前序遍历:";
b1.PreOrder(b1.root); //前序遍历
cout<<endl;
cout<<"非递归前序遍历:";
b1.PreOrderWithoutRecursion(b1.root);
cout<<endl;
cout<<"中序遍历:";
b1.InOrder(b1.root); //中序遍历
cout<<endl;
cout<<"非递归前序遍历:";
b1.InOrderWithoutRecursion(b1.root);
cout<<endl;
cout<<"后序遍历:";
b1.PostOrder(b1.root); //后序遍历
cout<<endl;
cout<<"非递归后序遍历:";
b1.PostOrderWithoutRecursion(b1.root);
cout<<endl;
b1.levelOrderCounter(b1.root); //广度节点计数、最大值
cout<<"是否是完全二叉树?"<<b1.levelOrderComplete(b1.root)<<endl; //完全二叉树判断
int Max = 0;
int arr[10] = {0};
b1.BiTreeLevelCounter(b1.root, 1, arr, 10); //结点数最多一层的结点计数:
for(int i = 0; i < 10; i++)
{
if(arr[i]>Max)
Max = arr[i];
}
cout<<"结点数最多一层的结点个数:"<<Max<<endl;
int depth = 1;
b1.BiTreeDepth(b1.root, 1, depth); //统计深度
cout<<"深度:"<<depth<<endl;
b1.ChangePos(b1.root); //交换孩子结点
b1.levelOrderPrint(b1.root);
cout<<"删除所有叶子节点:";
b1.deleteLeave(b1.root);
cout<<endl;
//cout<<b1.root->left->info<<endl;
//cout<<b1.root->right->info<<endl;
//cout<<"B呢?"<<b1.root->left;
b1.PreOrder(b1.root);
return 0;
}

二叉搜索树

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
184
185
186
187
188
189
190
191
192
193
194
#include<iostream>
#include<queue>
#include<stack>
using namespace std;
enum Tags {Left,Right}; // 定义枚举类型标志位
template<class T>
class StackElement;
template<class T>
class BinaryTreeNode
{
public:
T info; // 二叉树结点数据域
BinaryTreeNode<T> * left;
BinaryTreeNode<T> * right;
BinaryTreeNode() {} // 缺省构造函数
BinaryTreeNode(const T& ele){ // 给定数据的构造函数
info = ele;
left = NULL;
right = NULL;
}
BinaryTreeNode(const T& ele,BinaryTreeNode<T> *l, BinaryTreeNode<T> *r){ // 子树构造结点
info = ele;
left = l;
right = r;
}
};
template<class T>
class BinaryTree
{
public:
BinaryTreeNode<T> * root; // 二叉树根结点
BinaryTree(){ // 构造函数
root = NULL;
}
~BinaryTree(){ // 析构函数
deleteBinaryTree(root);
}
void create(BinaryTreeNode<T>* &temp){
T data;
int flag1,flag2;
cout<<"请按格式输入:数据,是否有左节点(1/0),是否有右节点(1/0)"<<endl;
cin>>data>>flag1>>flag2;
temp = new BinaryTreeNode<T>(data);
if(flag1 && flag2){
create(temp->left);
create(temp->right);
}else if(flag1){
create(temp->left);
}else if(flag2){
create(temp->right);
}else{
}
}
void deleteBinaryTree(BinaryTreeNode<T> *temp){
if(temp->left)
deleteBinaryTree(temp->left);
if(temp->right)
deleteBinaryTree(temp->right);
delete(temp);
}
void PreOrder (BinaryTreeNode<T> *temp)
{
// 前序遍历二叉树或其子树
if (temp != NULL)
{
cout<<temp->info<<' ';
PreOrder(temp->left); // 前序遍历左子树
PreOrder(temp->right); // 前序遍历右子树
}
}
//二叉搜索树函数
BinaryTreeNode<T>* Search(BinaryTreeNode<T>* temp ,T key){
BinaryTreeNode<T>* current = temp;
while((temp != NULL) && (key != current->info)){
current = (key < current->info ? Search(current->left, key) : Search(current->right, key));
}
return current;
}
void insertNode(const T value){
BinaryTreeNode<T> *p = root, *prev = NULL;
while(p != NULL){
prev = p;
if(p -> info < value){
p = p->right;
}else{
p = p->left;
}
}
if(!root){
root = new BinaryTreeNode<T>(value);
}else if(prev->info < value){
prev->right = new BinaryTreeNode<T>(value);
}else{
prev->left = new BinaryTreeNode<T>(value);
}
}
void deleteByCopying(T value){
BinaryTreeNode<T>* node = Search(root, value);
BinaryTreeNode<T>* previous;
BinaryTreeNode<T>* temp = node;
BinaryTreeNode<T>* temp1 = node->left;
if(node->right == NULL){
*node = *(node->left);
delete temp1;
}else if(node->left == NULL){
*node = *(node->right);
delete temp1;
}else{
previous = node;
temp = node->left;
while(temp->right != NULL){
previous = temp;
temp = temp->right;
}
node->info = temp->info;
if(previous == node){
node->left = NULL;
delete temp;
}else if(temp->left != NULL){
previous->right = temp->left;
}else{
previous->right = NULL;
}
delete temp;
}
}
};
/*
template<class T>
class BinarySearchTree:public BinaryTree<T>{
public:
BinaryTreeNode<T>* Search(BinaryTreeNode<T>* root, T key){
BinaryTreeNode<T>* current = root;
while((root != NULL) && (key != current->info)){
current = (key < current->info ? Search(current->left, key) : Search(current->right, key));
}
return current;
}
void insertNode(BinaryTreeNode<T>* root, const T& value){
BinaryTreeNode<T> *p = root, *prev = NULL;
while(p != 0){
prev = p;
if(p -> info < value){
p = p->right;
}else{
p = p->left;
}
}
if(root = NULL){
root = new BinaryTreeNode<T>(value);
}else if(prev->info < value){
prev->right = new BinaryTreeNode<T>(value);
}else{
prev->left = new BinaryTreeNode<T>(value);
}
}
void deleteByCopying(T value){
BinaryTreeNode<T> temp = Search(root, value);
}*/
int main(){
BinaryTree<int> b1;
int x;
b1.create(b1.root);
//b1.PreOrder(b1.root);
for(int i = 1; i < 10; i++){
//cout<<"请输入要插入的数:"<<endl;
//cin>>x;
b1.insertNode(i);
}
b1.PreOrder(b1.root);
cout<<"请输入要删除的数:"<<endl;
cin>>x;
b1.deleteByCopying(x);
b1.PreOrder(b1.root);
return 0;
}

最大堆

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
#include<iostream>
#include<queue>
#include<stack>
#include<stdlib.h>
#include<ctime>
using namespace std;
template <class T>
class MaxHeap // 最大堆类定义
{
private:
T *heapArray; // 存放堆数据的数组
int CurrentSize; // 当前堆中元素数目
int MaxSize; // 堆所能容纳的最大元素数目
//void swap(int pos_x, int pos_y); // 交换位置x和y的元素
void BuildHeap(); // 建堆
public:
MaxHeap(const int n); // 构造函数,n表示 堆的最大元素数目
virtual ~MaxHeap()
{
delete []heapArray;
}; // 析构函数
bool isEmpty( ); // 如果堆空,则返回真
bool isLeaf(int pos) const; // 如果是叶结点,返回TRUE
int leftchild(int pos) const; // 返回左孩子位置
int rightchild(int pos) const; // 返回右孩子位置
int parent(int pos) const; // 返回父结点位置
bool Insert(const T& newNode); // 向堆中插入新元素newNode
T& RemoveMax(); // 从堆顶删除最大值
bool Remove(int pos, T& node); // 删除给定下标的元素
void SiftUp(int position); // 从position向上开始调整,使序列成为堆
void SiftDown(int left); // 向下筛选,参数left表示开始处理的数组下标
void Print();
};
template<class T>
MaxHeap<T>::MaxHeap(const int n)
{
if (n <= 0)
return;
CurrentSize = 0;
MaxSize = n; // 初始化堆容量为n
heapArray = new T[MaxSize]; // 创建堆空间
srand(unsigned(time(0)));
for(int i = 0; i < 5; i++){
heapArray[i] = (rand()%100);
}
CurrentSize = 5;
BuildHeap(); // 此处进行堆元素的赋值工作
}
template<class T>
bool MaxHeap<T>::isLeaf(int pos) const
{
return (pos >= CurrentSize/2) && (pos < CurrentSize);
}
template<class T>
int MaxHeap<T>::leftchild(int pos) const
{
return 2*pos + 1; // 返回左孩子位置
}
template<class T>
int MaxHeap<T>::rightchild(int pos) const
{
return 2*pos + 2; // 返回右孩子位置
}
template<class T>
int MaxHeap<T>::parent(int pos) const
{
return (pos-1)/2; // 返回父结点位置
}
template<class T>
void MaxHeap<T>::SiftUp(int position)
{
// 从position向上开始调整
int temppos = position;
T temp = heapArray[temppos];
while ((temppos>0) && (heapArray[parent(temppos)]<temp))
{
heapArray[temppos] = heapArray[parent(temppos)];
temppos = parent(temppos);
}
heapArray[temppos] = temp;
}
template<class T>
void MaxHeap<T>::Print()
{
// 从position向上开始调整
cout<<"堆的排列:";
for(int i = 0; i < CurrentSize; i++){
cout<<heapArray[i]<<' ';
}
cout<<endl;
}
template <class T>
void MaxHeap<T>::SiftDown(int left)
{
int i = left; // 标识父结点
int j = leftchild(i); // 标识关键值较小的子结点
T temp = heapArray[i]; // 保存父结点
while (j < CurrentSize) // 过筛
{
if ((j < CurrentSize-1) && (heapArray[j]<heapArray[j + 1]))
//若有右子结点,且大于左子结点
j++; // j指向右子结点
if (temp<heapArray[j]) //若父结点小于子结点的值则交换位置
{
heapArray[i] = heapArray[j];
i = j;
j = leftchild(j);
}
else
break; //堆序满足,跳出
}
heapArray[i] = temp;
}
template<class T> // 建堆
void MaxHeap<T>::BuildHeap()
{
for (int i = CurrentSize/2-1; i >= 0; i--) // 反复调用筛选函数
SiftDown(i);
}
template <class T>
bool MaxHeap<T>::Insert(const T& newNode) // 向堆中插入新元素newNode
{
if (CurrentSize == MaxSize)
return false; // 堆空间已经满
heapArray[CurrentSize] = newNode;
SiftUp(CurrentSize); // 向上调整
CurrentSize++;
return true;
}
template<class T>
T& MaxHeap<T>::RemoveMax() // 从堆顶删除最大值
{
if (CurrentSize == 0)
{
cout<< "Can't Delete"; // 调用RemoveMax之前,需要判断堆非空
exit(1);
}
else
{
T temp;
temp = heapArray[0];
heapArray[0] = heapArray[--CurrentSize];
heapArray[CurrentSize] = temp;
// 交换堆顶和最后一个元素
if (CurrentSize>1)
SiftDown(0); // 从堆顶开始筛选
return heapArray[CurrentSize];
}
}
template<class T>
bool MaxHeap<T>::Remove(int pos, T& node) // 删除给定下标的元素
{
if ((pos < 0) || (pos >= CurrentSize))
return false;
node = heapArray[pos];
heapArray[pos] = heapArray[- -CurrentSize]; // 用最后的元素值替代删除位置的元素
if (heapArray[parent(pos)] < heapArray[pos])
SiftUp(pos); // 当前元素大于父结点,需要上升调整
else SiftDown(pos); // 当前元素小于父结点,向下筛
return true;
}
int main()
{
MaxHeap<int> heap(10);
heap.Print();
heap.Insert(50);
heap.Print();
cout<<heap.RemoveMax();
heap.Print();
return 0;
}