// 遍历时 不要忘记对t是否为空的判断
#include<iostream>
using namespace std;
typedef struct TreeNode
{
int val;
TreeNode * lchild;
TreeNode * rchild;
}TrNode;
//先序遍历
void preOrder(TrNode *t)
{
if (!t) return;
cout << t->val << endl;
preOrder(t->lchild);
preOrder(t->rchild);
}
//中序遍历
void inOrder(TrNode *t)
{
if (!t) return;
inOrder(t->lchild);
cout << t->val << endl;
inOrder(t->rchild);
}
//后序遍历
void postOrder(TrNode *t)
{
if (!t) return;
postOrder(t->lchild);
postOrder(t->rchild);
cout << t->val << endl;
}
int main()
{
//最原始的方法构建二叉树
TrNode *t1, *t2, *t3, *t4, *t5;
t1 = (TrNode*)malloc(sizeof(TrNode));
t2 = (TrNode*)malloc(sizeof(TrNode));
t3 = (TrNode*)malloc(sizeof(TrNode));
t4 = (TrNode*)malloc(sizeof(TrNode));
t5 = (TrNode*)malloc(sizeof(TrNode));
t1->val = 1;
t2->val = 2;
t3->val = 3;
t4->val = 4;
t5->val = 5;
t1->lchild = t2;
t1->rchild = t3;
t2->lchild = t4;
t2->rchild = NULL;
t3->rchild = t5;
t3->lchild = NULL;
t4->rchild = NULL;
t4->lchild = NULL;
t5->rchild = NULL;
t5->lchild = NULL;
cout << "先序遍历" << endl;
preOrder(t1);
cout << "中序遍历" << endl;
inOrder(t1);
cout << "后序遍历" << endl;
postOrder(t1);
system("pause");
return 0;
}
先序遍历
1
2
4
3
5
中序遍历
4
2
1
3
5
后序遍历
4
2
5
3
1
请按任意键继续. . .
//计算树的叶节点的数目:叶节点(既没有左子树也没有右子树)
定义一个全局变量 leafNodeNum 函数调用 countLeafNode(t1)
void countLeafNode(TrNode *t)
{
if (!t) return;
if (!t->lchild && !t->rchild) leafNodeNum++;
countLeafNode(t->lchild);
countLeafNode(t->rchild);
}
//计算树的高度 函数调用 int hight = treeHight(t1)
//计算树的高度
int treeHight(TrNode *t)
{
int depthLeft = 0;
int depthRight = 0;
int depVal = 0;
if (!t) return 0;
depthLeft = treeHight(t->lchild); //求左子树的高度
depthRight = treeHight(t->rchild); //求右子树的高度
depVal = 1 + ((depthLeft > depthRight) ? depthLeft : depthRight);//注意加1
return depVal;
}
//copy树
调用 TrNode *newTree = CopyTree(t1);
preOrder(newTree);//前序遍历进行验证
//Copy树
TrNode* CopyTree(TrNode *t)
{
if (!t) return NULL;
TrNode *newLp = NULL;//新建左子树
TrNode *newRp = NULL;//新建右子树
TrNode *newNode = NULL;//新建头结点
if (t->lchild)
{
newLp = CopyTree(t->lchild);//如果左子树存在,那么继续copy左子树
}
if (t->rchild) //如果右子树存在,那么继续copy右子树
{
newRp = CopyTree(t->rchild);
}
newNode = (TrNode*)malloc(sizeof(TrNode));
newNode->lchild = newLp;
newNode->rchild = newRp;
newNode->val = t->val;
return newNode;
}
//非递归的形式遍历二叉树(中序) 利用栈
思路:(1)如果节点有左子树,那么该节点入栈,如果没有左子树,访问该节点
(2)如果节点有右子树,重复步骤(1)
(3)如果节点没有右子树(节点访问完毕)从栈顶回退
TrNode *goLeft(TrNode *t, stack<TrNode*> s)
{
if (!t) return NULL;
while (t)
{
s.push(t); //如果某节点左子树存在 那么该节点入栈
t = t->lchild;
}
return t;
}
void inOrder(TrNode *t1)
{
stack<TrNode*> s;//用于存储存在左子树的节点
//先找到t的左子树中 没有左子树的节点 如果某节点左子树存在 那么该节点入栈
TrNode *t = goLeft(t1, s);
while (t)
{
cout << t->val << endl;
if (t->rchild)
{
t = goLeft(t->rchild,s);
}
else if (!s.empty())
{
t = s.top();
s.pop();
}
else
{
t = NULL;
}
}
}