#pragma
once
#include
<assert.h>
#include
<queue>
#include
<stack>
template
<
class
T
>
struct
BinaryTreeNode
{
BinaryTreeNode
<
T
>* _left;
BinaryTreeNode
<
T
>* _right;
T
_data;
BinaryTreeNode(
const
T
&
x
)
:_left(
NULL
)
,_right(
NULL
)
,_data(
x
)
{}
};
template
<
class
T
>
class
BinaryTree
{
typedef
BinaryTreeNode
<
T
>
Node
;
public
:
BinaryTree()
:_root(
NULL
)
{}
BinaryTree(
const
T
*
a
,
size_t
size
,
const
T
&
invalid
)
{
size_t
index = 0;
_root = _CreateTree(
a
,
size
,
invalid
, index);
}
BinaryTree(
const
BinaryTree
<
T
>&
t
)
{
_root = _Copy(
t
._root);
}
// t1 = t2 ==> t1.operator=(&t1, t2)
// 传统写法
//BinaryTree<T>& operator=(const BinaryTree<T>& t)
//{
// if (this != &t)
// {
// this->_Destory(this->_root);
// this->_root = _Copy(t._root);
// }
// return *this;
//}
// t1 = t2 ==> t1.operator=(&t1, t2)
// 现代写法 == 强盗式逻辑
// t1 = t1
/*BinaryTree<T>& operator=(BinaryTree<T> t)
{
swap(this->_root, t._root);
return *this;
}*/
// t1 = t2
BinaryTree
<
T
>& operator=(
const
BinaryTree
<
T
>&
t
)
{
if
(
this
!= &
t
)
{
BinaryTree
<
T
> tmp(
t
);
swap(
this
->_root, tmp._root);
}
return
*
this
;
}
~BinaryTree()
{
_Destory(_root);
_root =
NULL
;
}
void
PrevOrder()
{
_PrevOrder(_root);
cout<<endl;
}
void
InOrder()
{
_InOrder(_root);
cout<<endl;
}
void
PostOrder()
{
_PostOrder(_root);
cout<<endl;
}
/*size_t Size()
{
return _Size(_root);
}*/
size_t
Size()
{
size_t
size = 0;
_Size(_root, size);
return
size;
}
size_t
Depth()
{
return
_Depth(_root);
}
// 换一种思路实现
size_t
LeafSize()
{
return
_LeafSize(_root);
}
size_t
GetKLevel(
size_t
k
)
{
assert
(k > 0);
return
_GetKLevel(_root,
k
);
}
Node
* Find(
const
T
&
x
)
{
return
_Find(_root,
x
);
}
void
LevelOrder()
{
if
(_root ==
NULL
)
return
;
queue<
Node
*> q;
q.push(_root);
while
(!q.empty())
{
Node
* front = q.front();
q.pop();
cout<<front->_data<<
" "
;
if
(front->_left)
q.push(front->_left);
if
(front->_right)
q.push(front->_right);
}
cout<<endl;
}
void
PrevOrderNonR()
{
stack<
Node
*> s;
if
(_root)
s.push(_root);
while
(!s.empty())
{
Node
* top = s.top();
cout<<top->_data<<
" "
;
s.pop();
if
(top->_right)
s.push(top->_right);
if
(top->_left)
s.push(top->_left);
}
cout<<endl;
}
void
InOrderNonR()
{
stack<
Node
*> s;
Node
* cur = _root;
while
(cur || !s.empty())
{
while
(cur)
{
s.push(cur);
cur = cur->_left;
}
Node
* top = s.top();
cout<<top->_data<<
" "
;
s.pop();
cur = top->_right;
}
cout<<endl;
}
void
PostOrderNonR()
{
stack<
Node
*> s;
Node
* prev =
NULL
;
Node
* cur = _root;
while
(cur || !s.empty())
{
while
(cur)
{
s.push(cur);
cur = cur->_left;
}
Node
* top = s.top();
if
(top->_right ==
NULL
|| top->_right == prev)
{
cout<<top->_data<<
" "
;
s.pop();
prev = top;
}
else
{
cur = top->_right;
}
}
cout<<endl;
}
protected
:
Node
* _Copy(
Node
*
root
)
{
if
(
root
==
NULL
)
return
NULL
;
Node
* newRoot =
new
Node
(
root
->_data);
newRoot->_left = _Copy(
root
->_left);
newRoot->_right = _Copy(
root
->_right);
return
newRoot;
}
void
_Destory(
Node
*
root
)
{
if
(
root
==
NULL
)
return
;
_Destory(
root
->_left);
_Destory(
root
->_right);
delete
root
;
}
Node
* _CreateTree(
const
T
*
a
,
size_t
size
,
const
T
&
invalid
,
size_t
&
index
)
{
Node
* root =
NULL
;
if
(
index
<
size
&&
a
[
index
] !=
invalid
)
{
root =
new
Node
(
a
[
index
]);
root->_left = _CreateTree(
a
,
size
,
invalid
, ++
index
);
root->_right = _CreateTree(
a
,
size
,
invalid
, ++
index
);
}
return
root;
}
void
_PrevOrder(
Node
*
root
)
{
if
(
root
==
NULL
)
return
;
cout<<
root
->_data<<
" "
;
_PrevOrder(
root
->_left);
_PrevOrder(
root
->_right);
}
void
_InOrder(
Node
*
root
)
{
if
(
root
==
NULL
)
return
;
_InOrder(
root
->_left);
cout<<
root
->_data<<
" "
;
_InOrder(
root
->_right);
}
void
_PostOrder(
Node
*
root
)
{
if
(
root
==
NULL
)
return
;
_PostOrder(
root
->_left);
_PostOrder(
root
->_right);
cout<<
root
->_data<<
" "
;
}
/*size_t _Size(Node* root)
{
if (root == NULL)
return 0;
return _Size(root->_left)+ _Size(root->_right)+1;
}*/
/*size_t _Size(Node* root)
{
static size_t sSize = 0;
if (root == NULL)
return sSize;
++sSize;
_Size(root->_left);
_Size(root->_right);
return sSize;
}*/
void
_Size(
Node
*
root
,
size_t
&
size
)
{
static
size_t
sSize = 0;
if
(
root
==
NULL
)
return
;
++
size
;
_Size(
root
->_left,
size
);
_Size(
root
->_right,
size
);
}
size_t
_Depth (
Node
*
root
)
{
if
(
root
==
NULL
)
{
return
0;
}
int
left = _Depth(
root
->_left);
int
right = _Depth(
root
->_right);
return
left > right ? left+1 : right+1;
}
size_t
_LeafSize(
Node
*
root
)
{
if
(
root
==
NULL
)
{
return
0;
}
if
(
root
->_left ==
NULL
&&
root
->_right ==
NULL
)
{
return
1;
}
return
_LeafSize(
root
->_left) + _LeafSize(
root
->_right);
}
size_t
_GetKLevel(
Node
*
root
,
size_t
k
)
{
if
(
root
==
NULL
)
return
0;
if
(
k
== 1)
return
1;
return
_GetKLevel(
root
->_left,
k
-1) + _GetKLevel(
root
->_right,
k
-1);
}
Node
* _Find(
Node
*
root
,
const
T
&
x
)
{
if
(
root
==
NULL
)
return
NULL
;
if
(
root
->_data ==
x
)
return
root
;
Node
* ret = _Find(
root
->_left,
x
);
if
(ret)
return
ret;
return
_Find(
root
->_right,
x
);
}
protected
:
Node
* _root;
};
void
TestBinaryTree()
{
int
a1[10] = {1, 2, 3,
'#'
,
'#'
, 4,
'#'
,
'#'
, 5, 6};
BinaryTree
<
int
> t(a1,
sizeof
(a1)/
sizeof
(a1[0]),
'#'
);
t.PrevOrder();
t.InOrder();
t.PostOrder();
cout<<
"Tree Size?"
<<t.Size()<<endl;
cout<<
"3 Level?"
<<t.GetKLevel(3)<<endl;
BinaryTreeNode
<
int
>* ret = t.Find(6);
cout<<
"Find 6 ?:"
<<ret->_data<<endl;
t.LevelOrder();
t.PrevOrderNonR();
t.InOrderNonR();
t.PostOrderNonR();
}