二叉树的构造与一些常见操作(C++描述)
2020-10-04 二叉树的构建与销毁&遍历&具体操作
这是《王道数据结构》中要求读者必须掌握的一些操作,我花了一上午实现了一下,其中大部分操作都是用的递归方法。为了测试,我额外写了诸如构建树和销毁树等函数。
过程中我仅用了几个用例来测试函数,可能有没考虑到的边界情况,如果存在问题,请各位大佬务必在评论区指正。
先直接上代码,等以后有时间再把这些操作整理、完善和扩充。
2020-10-04 二叉树的构建与销毁&遍历&具体操作
#include<iostream>
#include<vector>
using namespace std
;
typedef char elem
;
typedef struct BNode
{
elem val
;
BNode
* left
, *right
;
BNode(elem v
):left(NULL),right(NULL){
val
= v
;
}
}BTree
;
typedef struct Queue
{
static const int MaxSize
= 50;
BNode
* queue
[MaxSize
];
int front
, rear
;
Queue():front(0),rear(0){}
void EnQueue(BNode
* node
){
if((rear
+1)%MaxSize
!= front
){
queue
[rear
] = node
;
rear
= (rear
+1) % MaxSize
;
}
}
void DeQueue(BNode
*& e
){
if(front
!= rear
){
e
= queue
[front
];
front
= (front
+1)%MaxSize
;
}
}
bool isEmpty(){
return front
== rear
;
}
}Queue
;
void createBTree(BTree
*& root
, const vector
<elem
>& v
);
void destroyBTree(BTree
*& root
);
void bfs(BTree
* root
, vector
<BNode
*>& nodes
);
void preorder(BTree
* root
, vector
<BNode
*>& nodes
);
void inorder(BTree
* root
, vector
<BNode
*>& nodes
);
void postorder(BTree
* root
, vector
<BNode
*>& nodes
);
void bfsPrint(BTree
* root
);
void preOrderPrint(BTree
* root
, int level
=1);
int calcDegreeNodeCount(BTree
* root
, int degree
);
int getBTreeHeight(BTree
* root
);
int getBTreeWidth(BTree
* root
);
void delBTreeLeaves(BTree
*& root
);
int getNodeLayer(BTree
* root
, BNode
* p
, int level
=1);
elem
getBTreeMaxVal(BTree
* root
);
void swapNodes(BNode
* root
);
void revertBTree(BTree
* root
);
void createBTree(BTree
*& root
, const vector
<elem
>& v
){
int n
= v
.size();
if(!n
|| v
[0] == '#')
return;
root
= NULL;
Queue que
;
root
= new BNode(v
[0]);
que
.EnQueue(root
);
int i
=1;
while (i
<n
){
BNode
* p
= NULL;
if(!que
.isEmpty())
que
.DeQueue(p
);
else{
cout
<<"error input"<<endl
;
break;
}
if(v
[i
] == '#'){
++i
;
que
.EnQueue(NULL);
}
else{
p
->left
= new BNode(v
[i
++]);
que
.EnQueue(p
->left
);
}
if(i
<n
){
if(v
[i
] == '#'){
++i
;
que
.EnQueue(NULL);
}
else{
p
->right
= new BNode(v
[i
++]);
que
.EnQueue(p
->right
);
}
}
}
}
void destroyBTree(BTree
*& root
){
if(!root
)
return;
destroyBTree(root
->left
);
destroyBTree(root
->right
);
delete root
;
root
= NULL;
}
void bfsPrint(BTree
* root
){
if(!root
)
return;
Queue que
;
que
.EnQueue(root
);
while (!que
.isEmpty()){
BNode
* e
= NULL;
que
.DeQueue(e
);
cout
<<e
->val
<<" ";
if(e
->left
)
que
.EnQueue(e
->left
);
if(e
->right
)
que
.EnQueue(e
->right
);
}
cout
<<"\n";
}
int calcDegreeNodeCount(BTree
* root
, int degree
){
if(!root
)
return 0;
int left
= calcDegreeNodeCount(root
->left
, degree
);
int right
= calcDegreeNodeCount(root
->right
, degree
);
int deg
= 0;
if(root
->left
)
++deg
;
if(root
->right
)
++deg
;
if(deg
== degree
){
return 1 + left
+ right
;
}
return left
+ right
;
}
int getBTreeHeight(BTree
* root
){
if(!root
)
return 0;
int left
= getBTreeHeight(root
->left
);
int right
= getBTreeHeight(root
->right
);
return 1 + (left
> right
? left
: right
);
}
int getBTreeWidth(BTree
* root
){
if(!root
)
return 0;
BNode
* lastNode
= root
;
BNode
* newLastNode
= NULL;
Queue que
;
que
.EnQueue(root
);
int curWidth
= 0, maxWidth
= 0;
while (!que
.isEmpty()){
BNode
* p
= NULL;
que
.DeQueue(p
);
curWidth
++;
if(p
->left
){
que
.EnQueue(p
->left
);
newLastNode
= p
->left
;
}
if(p
->right
){
que
.EnQueue(p
->right
);
newLastNode
= p
->right
;
}
if(p
== lastNode
){
maxWidth
= maxWidth
>=curWidth
?maxWidth
:curWidth
;
lastNode
= newLastNode
;
curWidth
=0;
}
}
return maxWidth
;
}
void delBTreeLeaves(BTree
*& root
){
if(!root
)
return;
if(!root
->left
&& !root
->right
){
delete root
;
root
= NULL;
return;
}
delBTreeLeaves(root
->left
);
delBTreeLeaves(root
->right
);
}
int getNodeLayer(BTree
* root
, BNode
* p
, int level
){
if(!root
){
return 0;
}
else if(root
== p
){
return level
;
}
else{
int left
= getNodeLayer(root
->left
, p
, level
+1);
if(!left
){
return getNodeLayer(root
->right
, p
, level
+1);
}
else
return left
;
}
}
void bfs(BTree
* root
, vector
<BNode
*>& nodes
){
nodes
.clear();
if(!root
)
return;
Queue que
;
que
.EnQueue(root
);
while (!que
.isEmpty()){
BNode
* p
= NULL;
que
.DeQueue(p
);
nodes
.push_back(p
);
if(p
->left
){
que
.EnQueue(p
->left
);
}
if(p
->right
){
que
.EnQueue(p
->right
);
}
}
}
elem
getBTreeMaxVal(BTree
* root
){
if(!root
){
return 0;
}
int left
=-1, right
=-1;
if(root
->left
)
left
= getBTreeMaxVal(root
->left
);
if(root
->right
)
right
= getBTreeMaxVal(root
->right
);
if(root
->val
>= left
&& root
->val
>= right
)
return root
->val
;
else if(left
>= root
->val
&& left
>= right
){
return left
;
}
else{
return right
;
}
}
void preorder(BTree
* root
, vector
<BNode
*>& nodes
){
if(!root
)
return;
nodes
.push_back(root
);
preorder(root
->left
, nodes
);
preorder(root
->right
, nodes
);
}
void inorder(BTree
* root
, vector
<BNode
*>& nodes
){
if(!root
)
return;
inorder(root
->left
, nodes
);
nodes
.push_back(root
);
inorder(root
->right
, nodes
);
}
void postorder(BTree
* root
, vector
<BNode
*>& nodes
){
if(!root
)
return;
postorder(root
->left
, nodes
);
postorder(root
->right
, nodes
);
nodes
.push_back(root
);
}
void swapNodes(BNode
* root
){
if(!root
->left
&& !root
->right
)
return;
BNode
* temp
= root
->left
;
root
->left
= root
->right
;
root
->right
= temp
;
}
void revertBTree(BTree
* root
){
if(!root
){
return;
}
swapNodes(root
);
revertBTree(root
->left
);
revertBTree(root
->right
);
}
void preOrderPrint(BTree
* root
, int level
){
if(!root
)
return;
cout
<<root
->val
<<" -> "<<level
<<endl
;
preOrderPrint(root
->left
, level
+1);
preOrderPrint(root
->right
, level
+1);
}
int main(){
BTree
* root
= NULL;
int N
= 15;
vector
<elem
> v
= vector
<elem
>(N
);
for (int i
=0; i
<N
; ++i
){
v
[i
] = 'a' + i
;
}
v
[9] = v
[10] = v
[11] = v
[12] = v
[5] = '#';
cout
<<"树的形状: ";
for (int i
=0; i
<N
; ++i
)
cout
<<v
[i
]<<" ";
cout
<<endl
;
cout
<<"createTree"<<endl
;
createBTree(root
, v
);
cout
<<"\nTest bfsPrint(): "<<endl
;
bfsPrint(root
);
cout
<<"\nTest calcDegreeNodeCount(): "<<endl
;
cout
<<"度为1的结点:"<<calcDegreeNodeCount(root
, 1)<<endl
;
cout
<<"度为2的结点:"<<calcDegreeNodeCount(root
, 2)<<endl
;
cout
<<"度为0的结点:"<<calcDegreeNodeCount(root
, 0)<<endl
;
cout
<<"\nTest getBTreeHeight(): "<<endl
;
cout
<<"树的高度为:"<<getBTreeHeight(root
)<<endl
;
cout
<<"\nTest getBTreeWidth(): "<<endl
;
cout
<<"树的宽度为:"<<getBTreeWidth(root
)<<endl
;
cout
<<"\nTest getNodeLayer(): "<<endl
;
vector
<BNode
*> ret
;
bfs(root
, ret
);
cout
<<"node "<<ret
[5]->val
<<" is at layer "
<<getNodeLayer(root
, ret
[5])<<endl
;
cout
<<"\nTest getBTreeMaxVal(): "<<endl
;
cout
<<"树中最大元素:"<<getBTreeMaxVal(root
)<<endl
;
cout
<<"\nTest revertBTree(): "<<endl
;
revertBTree(root
);
cout
<<"树翻转后:"<<endl
;
bfsPrint(root
);
cout
<<"\nTest preOrderPrint(): "<<endl
;
cout
<<"格式:结点值 -> 层次"<<endl
;
preOrderPrint(root
);
destroyBTree(root
);
return 0;
}
【运行结果】