我们要先搞清楚二叉树的特点:每个结点最多有两颗子树,即二叉树不存在度大于2的结点;二叉树的子树有左右之分,其子树的次序不能颠倒。
满二叉树:在一颗二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子结点都在同一层上。
完全二叉树:如果一颗具有N个结点的二叉树的结构与二叉树的前N个结点的结构相同,称为完全二叉树。
二叉树的性质:
- 若规定根节点的层数为1,则一颗非空二叉树的第i层上最多有2^i-1(i>0)个结点
- 若规定只有根节点的二叉树的深度为1,则深度为K的二叉树的最大结点个数是2^K - 1(K>=0)
- 对任何一个二叉树,如果其叶结点个数为n0,度为2的非叶结点个数为n2,则有n0 = n2 + 1
- 具有n个结点的完全二叉树的深度K为log2(n + 1)上取整
对于具有n个结点的完全二叉树,如果按照从上至下,从左至右的顺序对所有结点从0开始编号,则对于序号为i的结点有:
*若i > 0,双亲序号:(i - 1)/2;
i = 0,i 为根节点编号,无双亲结点
*若2i + 1 < n,左孩子序号:2i + 1,否则无左孩子
*若2i + 2 < n,右孩子序号:2i + 2,否则无右孩子在下边代码中会用到栈和队列的一些操作,在我前边的博客中我有实现,就不在这里写了。
1.创建二叉树
创建二叉树我们该如何创建呢?我们应该按照它的先序遍历的顺序创建,先创建根结点,再创建左子树,再创建右子树
BTNode* BuyBTNode(BDataType data)
{
BTNode* NewNode = (BTNode*)malloc(sizeof(BTNode));
if (NULL == NewNode)
{
printf("创建结点失败!\n");
return;
}
else
{
NewNode->_data = data;
NewNode->_pLeft = NULL;
NewNode->_pRight = NULL;
}
return NewNode;
}
void CreateBinTree(BTNode** pRoot, BDataType* str, int size, int* index, BDataType invalid)
{
assert(pRoot);
while ((*index) < size && str[*index] != invalid)
{
//创建根结点
(*pRoot) = BuyBTNode(str[*index]);
//创建左子树
(*index)++;
CreateBinTree(&(*pRoot)->_pLeft, str, size, index, invalid);
//创建右子树
(*index)++;
CreateBinTree(&(*pRoot)->_pRight, str, size, index, invalid);
}
}
void test()
{
BTNode* pRoot;
BTNode* NewRoot;
BDataType str[] = "ABD###CE##F";
int size = strlen(&str);
int index = 0;
int ret = 0;
BDataType invalid = '#';
CreateBinTree(&pRoot, str, size, &index, invalid);
}
在这里我们为什么要传index的地址过去呢?是因为我们用了递归调用,当一层函数完了之后会返回上一层,如果只是把index传过来,在一层内index的改变不会引起上一层函数中index值的改变(形参的改变不能引起实参的改变),这样index是不会一直增大的,所以要传它的地址,才会引起值的改变。
前/中/后遍历二叉树(递归):
前序遍历:根结点—>左孩子—->右孩子
中序遍历:左孩子—>根结点—>右孩子
后序遍历:左孩子—>右孩子—>根结点
void PreOrder(BTNode* pRoot)
{
if (NULL == pRoot)
return;
//遍历根结点
printf("%c ", pRoot->_data);
//遍历根结点的左子树
PreOrder(pRoot->_pLeft);
//遍历根结点的右子树
PreOrder(pRoot->_pRight);
}
void InOrder(BTNode* pRoot)
{
if (NULL == pRoot)
return;
//遍历根结点的左子树
InOrder(pRoot->_pLeft);
//遍历根结点
printf("%c ", pRoot->_data);
//遍历根结点的右子树
InOrder(pRoot->_pRight);
}
void PosOrder(BTNode* pRoot)
{
if (NULL == pRoot)
return;
//遍历根结点的左子树
PosOrder(pRoot->_pLeft);
//遍历根结点的右子树
PosOrder(pRoot->_pRight);
//遍历根结点
printf("%c ", pRoot->_data);
}
前/中/后遍历二叉树(非递归):
前序遍历:我们需要借助栈来解决,但还是先遍历根结点,再遍历根节点的左孩子,再遍历右孩子,我们先让根结点入栈,取栈顶元素(此时就是根结点),再让栈顶元素出栈,遍历栈顶元素的根结点,把它的右孩子入栈,再遍历它的左孩子,直到栈为空时出while循环,我们就遍历完了。
void PreOrderNor(BTNode* pRoot)
{
Stack s;
SDataType pCur = NULL;
StackInit(&s);
StackPush(&s, pRoot);
while (!StackEmpty(&s))
{
pCur = StackTop(&s);
StackPop(&s);
while (pCur)
{
printf("%c ", pCur->_data);
if (pCur->_pRight)
{
StackPush(&s, pCur->_pRight);
}
pCur = pCur->_pLeft;
}
}
}
中序遍历:
void InOrderNor(BTNode* pRoot)
{
Stack s;
SDataType pCur = NULL;
SDataType Top = NULL;
StackInit(&s);
StackPush(&s, pRoot);
pCur = StackTop(&s);
StackPop(&s);
//找以pCur为根的二叉树的最左侧的一个结点,并保存所经过路径的所以结点
while (!StackEmpty(&s) || pCur)
{
while (pCur)
{
StackPush(&s, pCur);
pCur = pCur->_pLeft;
}
Top = StackTop(&s);
printf("%c ", Top->_data);
StackPop(&s);
if (Top->_pRight)
pCur = Top->_pRight;
}
}
后序遍历:
在后序遍历中,我们要把最近遍历的那个结点标记出来,不然就会造成死循环。
void PosOrderNor(BTNode* pRoot)
{
Stack s;
SDataType pCur = NULL;
SDataType pPrev = NULL;//标记最近访问过的结点
SDataType Top = NULL;
StackInit(&s);
StackPush(&s, pRoot);
pCur = StackTop(&s);
StackPop(&s);
while (!StackEmpty(&s) || pCur)
{
while (pCur)
{
StackPush(&s, pCur);
pCur = pCur->_pLeft;
}
Top = StackTop(&s);
//以Top为根的二叉树的根节点不能遍历,除非它的右子树为空/右子树已经遍历了
if (Top->_pRight == NULL || Top->_pRight == pPrev)
{
printf("%c ", Top->_data);
pPrev = Top;
StackPop(&s);
}
else
pCur = Top->_pRight;
}
}
层序遍历二叉树
void LevelOrder(BTNode* pRoot)
{
Queue q;
QDataType ret = NULL;
if (NULL == pRoot)
return NULL;
QueueInit(&q);
QueuePush(&q, pRoot);
while (!QueueIsEmpty(&q))
{
ret = QueueFront(&q);
printf("%c ", ret->_data);
if (ret->_pLeft)
QueuePush(&q, ret->_pLeft);
if (ret->_pRight)
QueuePush(&q, ret->_pRight);
QueuePop(&q);
}
}
求二叉树的高度
我们用递归调用,当根结点都不存在时,高度肯定为0,树的高度是它左子树和右子树哪个树的高度高,我们取哪个,再用子树的高度加上1(根结点),就是这颗树的高度
int Height(BTNode* pRoot)
{
if (NULL == pRoot)
return 0;
return Height(pRoot->_pLeft) > Height(pRoot->_pRight) ? Height(pRoot->_pLeft) + 1 : Height(pRoot->_pRight) + 1;
}
求二叉树中结点的个数
这个也很简单,我们只需要用根结点左子树的个数加上右子树结点的个数,再加上根结点(1),就是二叉树中结点的个数了。在这里我们又用的是递归函数,可以看出在二叉树中,递归函数很重要,如果递归还不是很明白的话,自己可以多搜写资料学习学习,学习递归最好的方法就是要画,在电脑画板上我们最好把每一层的调用画出来,这样就看的更清楚了。
int GetBTNodeCount(BTNode* pRoot)
{
if (NULL == pRoot)
return 0;
else
return GetBTNodeCount(pRoot->_pLeft) + GetBTNodeCount(pRoot->_pRight) + 1;
}
求叶子结点的个数
如果一个结点的左右孩子都为空的话,它肯定是叶子结点。整颗树的叶子结点个数就是根结点左子树叶子结点的个数加上根结点右子树上叶子结点的个数。
int GetLeafNodeCount(BTNode* pRoot)
{
if (NULL == pRoot)
return 0;
else if (pRoot->_pLeft == NULL && pRoot->_pRight == NULL)
return 1;
else
return GetLeafNodeCount(pRoot->_pLeft) + GetLeafNodeCount(pRoot->_pRight);
}
求二叉树中第K层结点的个数
求第K层结点的个数不好求,我们可以求K - 1层所有结点(左子树、右子树)孩子的个数。
int GetKLevelNodeCount(BTNode* pRoot, int K)
{
if (pRoot == NULL)
return 0;
else if (K == 0)
return 1;
return GetKLevelNodeCount(pRoot->_pLeft, K - 1) + GetKLevelNodeCount(pRoot->_pRight, K - 1);
}
判断一个结点是否在一颗二叉树中
如果存在了,返回1,如果不是根结点,我们在它的左子树中找,如果还没找到,我们在它的右子树中找。
int IsBTNodeInBiTree(BTNode* pRoot, BDataType data)
{
if (NULL == pRoot)
return 0;
if (pRoot->_data == data)
return 1;
IsBTNodeInBiTree(pRoot->_pLeft, data);
IsBTNodeInBiTree(pRoot->_pRight, data);
}
判断一颗二叉树是否是完全二叉树
int IsCompleteBinTree(BTNode* pRoot)
{
if (NULL == pRoot)
return 1;
int IsFlag = 0;
Queue q;
QDataType ret = NULL;
QueueInit(&q);
QueuePush(&q, pRoot);
while (!QueueIsEmpty(&q))
{
ret = QueueFront(&q);
if (IsFlag == 1)//如果是完全二叉树,说明后边的结点没有左右孩子
{
if (ret->_pLeft || ret->_pRight)
return 0;
}
if (ret->_pLeft && ret->_pRight)
{
QueuePush(&q, ret->_pLeft);
QueuePush(&q, ret->_pRight);
}
else if (ret->_pLeft) //该结点只有左孩子,没有右孩子,说明该结点是那个临界结点,它之后的所有结点都没有左右孩子的话,这课树就是完全二叉树,IsFlag标记为1
{
QueuePush(&q, ret->_pLeft);
IsFlag = 1;
}
else if (ret->_pRight)
{
return 0;
}
else //该结点左右孩子都不存在
{
IsFlag = 1;
//return;
}
QueuePop(&q);
}
return 1;
}
下面我们来看看整体代码吧:
BinTree.c
#include"BinTree.h"
BTNode* BuyBTNode(BDataType data)
{
BTNode* NewNode = (BTNode*)malloc(sizeof(BTNode));
if (NULL == NewNode)
{
printf("创建结点失败!\n");
return;
}
else
{
NewNode->_data = data;
NewNode->_pLeft = NULL;
NewNode->_pRight = NULL;
}
return NewNode;
}
void CreateBinTree(BTNode** pRoot, BDataType* str, int size, int* index, BDataType invalid)
{
assert(pRoot);
while ((*index) < size && str[*index] != invalid)
{
//创建根结点
(*pRoot) = BuyBTNode(str[*index]);
//创建左子树
(*index)++;
CreateBinTree(&(*pRoot)->_pLeft, str, size, index, invalid);
//创建右子树
(*index)++;
CreateBinTree(&(*pRoot)->_pRight, str, size, index, invalid);
}
}
void PreOrder(BTNode* pRoot)
{
if (NULL == pRoot)
return;
//遍历根结点
printf("%c ", pRoot->_data);
//遍历根结点的左子树
PreOrder(pRoot->_pLeft);
//遍历根结点的右子树
PreOrder(pRoot->_pRight);
}
void InOrder(BTNode* pRoot)
{
if (NULL == pRoot)
return;
//遍历根结点的左子树
InOrder(pRoot->_pLeft);
//遍历根结点
printf("%c ", pRoot->_data);
//遍历根结点的右子树
InOrder(pRoot->_pRight);
}
void PosOrder(BTNode* pRoot)
{
if (NULL == pRoot)
return;
//遍历根结点的左子树
PosOrder(pRoot->_pLeft);
//遍历根结点的右子树
PosOrder(pRoot->_pRight);
//遍历根结点
printf("%c ", pRoot->_data);
}
BTNode* CopyBinTree(BTNode* pRoot)
{
BTNode* NewRoot = NULL;
if (pRoot != NULL)
{
//复制根结点
NewRoot = pRoot;
//复制左子树
CopyBinTree(pRoot->_pLeft);
//复制右子树
CopyBinTree(pRoot->_pRight);
}
else
return NULL;
return NewRoot;
}
void DestroyBinTree(BTNode** pRoot)
{
assert(pRoot);
if (*pRoot == NULL)
{
return;
}
//删除左子树
DestroyBinTree(&(*pRoot)->_pLeft);
//删除右子树
DestroyBinTree(&(*pRoot)->_pRight);
//删除根结点
free(*pRoot);
(*pRoot) = NULL;
}
int GetBTNodeCount(BTNode* pRoot)
{
if (NULL == pRoot)
return 0;
else
return GetBTNodeCount(pRoot->_pLeft) + GetBTNodeCount(pRoot->_pRight) + 1;
}
int GetLeafNodeCount(BTNode* pRoot)
{
if (NULL == pRoot)
return 0;
else if (pRoot->_pLeft == NULL && pRoot->_pRight == NULL)
return 1;
else
return GetLeafNodeCount(pRoot->_pLeft) + GetLeafNodeCount(pRoot->_pRight);
}
int GetKLevelNodeCount(BTNode* pRoot, int K)
{
if (pRoot == NULL)
return 0;
else if (K == 0)
return 1;
return GetKLevelNodeCount(pRoot->_pLeft, K - 1) + GetKLevelNodeCount(pRoot->_pRight, K - 1);
}
int Height(BTNode* pRoot)
{
if (NULL == pRoot)
return 0;
return Height(pRoot->_pLeft) > Height(pRoot->_pRight) ? Height(pRoot->_pLeft) + 1 : Height(pRoot->_pRight) + 1;
}
BTNode* LeftChild(BTNode* pNode, BTNode** ch, BDataType data)
{
if (pNode == NULL)
return NULL;
if (pNode->_data == data)
return *ch = pNode->_pLeft;
else
{
LeftChild(pNode->_pLeft, ch, data);
LeftChild(pNode->_pRight, ch, data);
}
}
BTNode* RightChild(BTNode* pNode, BTNode** ch, BDataType data)
{
if (pNode == NULL)
return NULL;
if (pNode->_data == data)
return *ch = pNode->_pRight;
else
{
RightChild(pNode->_pLeft, ch, data);
RightChild(pNode->_pRight, ch, data);
}
}
int IsBTNodeInBiTree(BTNode* pRoot, BDataType data)
{
if (NULL == pRoot)
return 0;
if (pRoot->_data == data)
return 1;
IsBTNodeInBiTree(pRoot->_pLeft, data);
IsBTNodeInBiTree(pRoot->_pRight, data);
}
BTNode* GetBTNodeParent(BTNode* pRoot, BTNode** ch, BDataType data)
{
if (NULL == pRoot)
return NULL;
if (pRoot->_pLeft && pRoot->_pLeft->_data == data)
return *ch = pRoot;
if (pRoot->_pRight && pRoot->_pRight->_data == data)
return *ch = pRoot;
GetBTNodeParent(pRoot->_pLeft, ch, data);
GetBTNodeParent(pRoot->_pRight, ch, data);
}
void Swap(BTNode** left, BTNode** right)
{
BTNode* tmp = NULL;
tmp = *left;
*left = *right;
*right = tmp;
}
void MirrorBinTree(BTNode* pRoot)
{
if (NULL == pRoot)
return NULL;
Swap(&pRoot->_pLeft, &pRoot->_pRight);
MirrorBinTree(pRoot->_pLeft);
MirrorBinTree(pRoot->_pRight);
}
void MirrorBinTreeNor(BTNode* pRoot)
{
Queue q;
QueueInit(&q);
QueuePush(&q, pRoot);
while (!QueueIsEmpty(&q))
{
QDataType cur = QueueFront(&q);
if (cur->_pLeft)
QueuePush(&q, cur->_pLeft);
if (cur->_pRight)
QueuePush(&q, cur->_pRight);
Swap(&cur->_pLeft, &cur->_pRight);
QueuePop(&q);
}
}
void LevelOrder(BTNode* pRoot)
{
Queue q;
QDataType ret = NULL;
if (NULL == pRoot)
return NULL;
QueueInit(&q);
QueuePush(&q, pRoot);
while (!QueueIsEmpty(&q))
{
ret = QueueFront(&q);
printf("%c ", ret->_data);
if (ret->_pLeft)
QueuePush(&q, ret->_pLeft);
if (ret->_pRight)
QueuePush(&q, ret->_pRight);
QueuePop(&q);
}
}
int IsCompleteBinTree(BTNode* pRoot)
{
if (NULL == pRoot)
return 1;
int IsFlag = 0;
Queue q;
QDataType ret = NULL;
QueueInit(&q);
QueuePush(&q, pRoot);
while (!QueueIsEmpty(&q))
{
ret = QueueFront(&q);
if (IsFlag == 1)//如果是完全二叉树,说明后边的结点没有左右孩子
{
if (ret->_pLeft || ret->_pRight)
return 0;
}
if (ret->_pLeft && ret->_pRight)
{
QueuePush(&q, ret->_pLeft);
QueuePush(&q, ret->_pRight);
}
else if (ret->_pLeft) //该结点只有左孩子,没有右孩子,说明该结点是那个临界结点,它之后的所有结点都没有左右孩子的话,这课树就是完全二叉树,IsFlag标记为1
{
QueuePush(&q, ret->_pLeft);
IsFlag = 1;
}
else if (ret->_pRight)
{
return 0;
}
else //该结点左右孩子都不存在
{
IsFlag = 1;
//return;
}
QueuePop(&q);
}
return 1;
}
void PreOrderNor(BTNode* pRoot)
{
Stack s;
SDataType pCur = NULL;
StackInit(&s);
StackPush(&s, pRoot);
while (!StackEmpty(&s))
{
pCur = StackTop(&s);
StackPop(&s);
while (pCur)
{
printf("%c ", pCur->_data);
if (pCur->_pRight)
{
StackPush(&s, pCur->_pRight);
}
pCur = pCur->_pLeft;
}
}
}
void InOrderNor(BTNode* pRoot)
{
Stack s;
SDataType pCur = NULL;
SDataType Top = NULL;
StackInit(&s);
StackPush(&s, pRoot);
pCur = StackTop(&s);
StackPop(&s);
//找以pCur为根的二叉树的最左侧的一个结点,并保存所经过路径的所以结点
while (!StackEmpty(&s) || pCur)
{
while (pCur)
{
StackPush(&s, pCur);
pCur = pCur->_pLeft;
}
Top = StackTop(&s);
printf("%c ", Top->_data);
StackPop(&s);
if (Top->_pRight)
pCur = Top->_pRight;
}
}
void PosOrderNor(BTNode* pRoot)
{
Stack s;
SDataType pCur = NULL;
SDataType pPrev = NULL;//标记最近访问过的结点
SDataType Top = NULL;
StackInit(&s);
StackPush(&s, pRoot);
pCur = StackTop(&s);
StackPop(&s);
while (!StackEmpty(&s) || pCur)
{
while (pCur)
{
StackPush(&s, pCur);
pCur = pCur->_pLeft;
}
Top = StackTop(&s);
//以Top为根的二叉树的根节点不能遍历,除非它的右子树为空/右子树已经遍历了
if (Top->_pRight == NULL || Top->_pRight == pPrev)
{
printf("%c ", Top->_data);
pPrev = Top;
StackPop(&s);
}
else
pCur = Top->_pRight;
}
}
test.c
#include"BinTree.h"
void test()
{
BTNode* pRoot;
BTNode* NewRoot;
BDataType str[] = "ABD###CE##F";
int size = strlen(&str);
int index = 0;
int ret = 0;
BDataType invalid = '#';
CreateBinTree(&pRoot, str, size, &index, invalid);
BTNode* ch = NULL;
RightChild(pRoot,&ch,'C');
printf("%c\n", ch->_data);
ret = Height(pRoot);
printf("%d\n", ret);
NewRoot = CopyBinTree(pRoot);
DestroyBinTree(&NewRoot);
printf("前序遍历:");
PreOrder(NewRoot);
printf("\n");
printf("中序遍历:");
InOrder(NewRoot);
printf("\n");
printf("后序遍历:");
PosOrder(NewRoot);
printf("\n");
}
void IsBTNodeInBiTree_test()
{
BTNode* pRoot;
BTNode* NewRoot;
BDataType str[] = "ABD###CE##F";
int size = strlen(&str);
int index = 0;
int ret = 0;
BDataType invalid = '#';
CreateBinTree(&pRoot, str, size, &index, invalid);
ret = IsBTNodeInBiTree(pRoot, 'G');
if (1 == ret)
printf("该结点在二叉树中\n");
else
{
printf("该结点不在二叉树中\n");
}
}
void GetBTNodeParent_test()
{
BTNode* pRoot;
BTNode* NewRoot;
BDataType str[] = "ABD###CE##F";
int size = strlen(&str);
int index = 0;
BTNode* ch = NULL;
BDataType invalid = '#';
CreateBinTree(&pRoot, str, size, &index, invalid);
GetBTNodeParent(pRoot, &ch, 'C');
printf("%c\n", ch->_data);
}
void MirrorBinTree_test()
{
BTNode* pRoot;
BTNode* NewRoot;
BDataType str[] = "ABD###CE##F";
int size = strlen(&str);
int index = 0;
BTNode* ch = NULL;
BDataType invalid = '#';
CreateBinTree(&pRoot, str, size, &index, invalid);
printf("前序遍历:");
PreOrder(pRoot);
printf("\n");
printf("中序遍历:");
InOrder(pRoot);
printf("\n");
printf("后序遍历:");
PosOrder(pRoot);
printf("\n");
MirrorBinTreeNor(pRoot);
printf("前序遍历:");
PreOrder(pRoot);
printf("\n");
}
void LevelOrder_test()
{
BTNode* pRoot;
BTNode* NewRoot;
BDataType str[] = "ABD###CE##F";
int size = strlen(&str);
int index = 0;
BTNode* ch = NULL;
BDataType invalid = '#';
CreateBinTree(&pRoot, str, size, &index, invalid);
printf("前序遍历:");
PreOrder(pRoot);
printf("\n");
printf("层序遍历:");
LevelOrder(pRoot);
printf("\n");
}
void IsCompleteBinTree_test()
{
BTNode* pRoot;
BTNode* NewRoot;
//BDataType str[] = "ABD###CE##F";
BDataType str[] = "ABD##E##CF";
int size = strlen(&str);
int index = 0;
BTNode* ch = NULL;
BDataType invalid = '#';
CreateBinTree(&pRoot, str, size, &index, invalid);
printf("前序遍历:");
PreOrder(pRoot);
printf("\n");
int ret = IsCompleteBinTree(pRoot);
if (1 == ret)
printf("是完全二叉树\n");
else
printf("不是完全二叉树\n");
}
void PreOrderNor_test()
{
BTNode* pRoot;
BTNode* NewRoot;
BDataType str[] = "ABD###CE##F";
int size = strlen(&str);
int index = 0;
BTNode* ch = NULL;
BDataType invalid = '#';
CreateBinTree(&pRoot, str, size, &index, invalid);
printf("前序遍历:");
PreOrder(pRoot);
printf("\n");
printf("非递归前序遍历:");
PreOrderNor(pRoot);
printf("\n");
}
void InOrdreNor_test()
{
BTNode* pRoot;
BTNode* NewRoot;
BDataType str[] = "ABD###CE##F";
int size = strlen(&str);
int index = 0;
BTNode* ch = NULL;
BDataType invalid = '#';
CreateBinTree(&pRoot, str, size, &index, invalid);
printf("中序遍历:");
InOrder(pRoot);
printf("\n");
printf("非递归中序遍历:");
InOrderNor(pRoot);
printf("\n");
}
void PosOrdreNor_test()
{
BTNode* pRoot;
BTNode* NewRoot;
BDataType str[] = "ABD###CE##F";
int size = strlen(&str);
int index = 0;
BTNode* ch = NULL;
BDataType invalid = '#';
CreateBinTree(&pRoot, str, size, &index, invalid);
printf("后序遍历:");
PosOrder(pRoot);
printf("\n");
printf("非递归后序遍历:");
PosOrderNor(pRoot);
printf("\n");
}
int main()
{
//test();
//IsBTNodeInBiTree_test();
//GetBTNodeParent_test();
//MirrorBinTree_test();
//LevelOrder_test();
//IsCompleteBinTree_test();
//RebuildBinTree_test();
//PreOrderNor_test();
//InOrdreNor_test();
PosOrdreNor_test();
return 0;
}