一.算法思想
二.源代码
//1.递归前序遍历
void PreOrder(BiTreeNode BT) {
if (BT!=NULL) {
Visit(BT); //先访问根节点
PreOrder(BT->Lchild); //递归遍历左子树
PreOrder(BT->Rightchild); //递归遍历右子树
}
}
//2.递归中序遍历
void InOrder(BiTreeNode BT) {
if (BT != NULL) {
PreOrder(BT->Lchild); //递归遍历左子树
Visit(BT); //先访问根节点
PreOrder(BT->Rightchild); //递归遍历右子树
}
}
//3.递归后序遍历
void PostOrder(BiTreeNode BT) {
if (BT != NULL) {
PreOrder(BT->Lchild); //递归遍历左子树
PreOrder(BT->Rightchild); //递归遍历右子树
Visit(BT); //先访问根节点
}
}
//4.非递归前序遍历
void PreOrder2(BiTreeNode BT) {
StackNode SqStack = new StackStruct;
InitStack(SqStack); //初始化栈SqStack
BiTreeNode p = BT;//p为工作指针
while (p!=NULL||StackIsEmpty(SqStack)) { //栈不空或p不为空时循环
if (p != NULL) { //一路向左
Visit(p); //访问当前结点,并入栈
Push(SqStack,p);
p = p->Lchild; //左孩子不为空则一直向左走
}
else { //上个结点的左孩子为空,将上个结点出栈,并转向该结点的右子树
Pop(SqStack,p);
p = p->Rightchild;
}
}
}
//5.非递归中序遍历
void InOrder2(BiTreeNode BT) {
StackNode SqStack = new StackStruct;
InitStack(SqStack); //初始化栈SqStack
BiTreeNode p = BT;//p为工作指针
while (p != NULL || StackIsEmpty(SqStack)) { //栈不空或p不为空时循环
if (p != NULL) { //一路向左
Push(SqStack, p);
p = p->Lchild; //左孩子不为空则一直向左走
}
else { //上个结点的左孩子为空,将上个结点出栈,访问出栈结点并转向该结点的右子树
Pop(SqStack, p);
Visit(p);
p = p->Rightchild;
}
}
}
//6.非递归后序遍历
void PostOrder(BiTreeNode BT) {
StackNode SqStack = new StackStruct;
InitStack(SqStack); //初始化栈SqStack
BiTreeNode p = BT;//p为工作指针
BiTreeNode r = NULL;//r指向最近访问过的结点
while (p!=NULL || !StackIsEmpty(SqStack)) { //左子树或栈不为空时进行循环
if (p!=NULL) { //左子树不为空则一路向左
Push(SqStack,p); //将结点入栈
p = p->Lchild;
}
else { //左子树为空,则向右访问
GetTop(SqStack,p); //读栈顶结点(非出栈)
if (p->Rightchild!=NULL&&r!=p->Rightchild) { //右子树不为空且未被访问过
p = p->Rchilid;
Push(SqStack, p); //将结点入栈
p = p->Lchild; //一路向左
}
else //右子树为空或已被访问过
{
Pop(SqStack,p); //将结点从栈中弹出
Visit(p); //访问当前结点
r = p; //记录已访问过的结点
p = NULL; //每次出栈访问完一个结点相当于遍历完以该结点为根的子树,故需将P置为NULL
}
}
}
}
//7.层次遍历
void LevelOrder(BiTreeNode BT) {
SqQueue Sq = new SqQueueStrcut; //初始化队列
BiTreeNode p;
EnQueue(Sq,BT); //将根节点入队
while (isEmpty(Sq)) { //队列不空则循环
DeQueue(Sq,p); //出队
Visit(p);
if (p->Lchild!=NULL) {
EnQueue(Sq, p->Lchild); //左子树不空,则将左子树根节点入队
}
if (p->Rightchild != NULL) {
EnQueue(Sq, p->Rightchild); //右子树不空,则将右子树根节点入队
}
}
}
//8.反层次遍历
void InvertLevelOrder(BiTreeNode BT) {
BiTreeNode p;
SqQueue Sq = new SqQueueStrcut; //初始化队列
StackNode SqStack = new StackStruct;
InitStack(SqStack); //初始化栈SqStack
InitQueue(Sq);
EnQueue(Sq, BT); //将根节点入队
while (isEmpty(Sq)) { //队列不空则循环
DeQueue(Sq, p); //出队
Push(SqStack,p); //入栈
if (p->Lchild != NULL) {
EnQueue(Sq, p->Lchild); //左子树不空,则将左子树根节点入队
}
if (p->Rightchild != NULL) {
EnQueue(Sq, p->Rightchild); //右子树不空,则将右子树根节点入队
}
}
while (!StackIsEmpty(SqStack)) { //进行自下而上,从右到左的层次遍历
Pop(SqStack,p);
Visit(p->data); //访问结点
}
}