二叉树的前序线索化超详细注释程序,小白专用(C++)

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;

/*
本程序实现二叉树的建立和前序线索化,并输出前序遍历的结果。

测试输入:ABD##EF###C#G##

     A
    / \
   B   C
  /\   /\
 D  E  # G
/\  /\   /\
# # F #  # #
   /\
  # #

*/

//二叉树节点
typedef struct BinaryTreeNode{

    char value; //节点的存储内容,一个字符

    int ltag; //二叉树节点的坐标记,1表示指针指向孩子,0表示指针指向前驱
    struct BinaryTreeNode * lchild; //二叉树节点的左孩子

    int rtag; //二叉树节点的右标记,1表示指针指向孩子,0表示指针指向后继
    struct BinaryTreeNode * rchild; //二叉树节点的右孩子

}BTnode,*BTnodePointer;

//由前序序列创建普通二叉树,是最基础的二叉树
BTnodePointer createBinaryTree(void) {

    BTnodePointer T; //用于返回创建的子树的指针
    char temp;
    cin >> temp; //获取用户输入
    if (temp == '#') T = NULL; //用户输入#表示没有孩子,指针为NULL,子树就是NULL。(这里的T指代所有将要被赋值的位置的指针变量)
    else { //用户输入了其他内容,那么输入什么什么就是节点的值
        T = (BTnodePointer)malloc(sizeof(BTnode));
        T->value = temp;
        T->ltag = T->rtag = 1; //每个节点初始都认为是既有左孩子又有右孩子的,哪怕孩子是空,以后线索化的时候再改tag
        T->lchild = createBinaryTree(); //根据前序序列创建二叉树的顺序是,先本节点赋值,再递归创建左子树,再递归创建右子树
        T->rchild = createBinaryTree();
    }
    return T; //如果用户什么也没输入或者是已经将“以本节点为根节点的子树”赋值完成,那么就return T,结束本层的递归,回到上一层的递归中去
}

//将给定的二叉树前序线索化
BTnodePointer pre = NULL; //pre表示前驱节点,初始化为NULL
void preThreading(BTnodePointer T) {
    if (T == NULL) return; //当前节点是空什么也不做
    if (T->lchild == NULL){ //当前节点左孩子为空,那么左孩子应指向前驱pre
        T->lchild = pre;
        T->ltag = 0; 
    }
    if (pre != NULL && pre->rchild == NULL) { //pre结点右孩子为空,那么右孩子应指向后继节点,也就是当前节点T
        pre->rchild = T;
        pre->rtag = 0;
    }
    pre = T; //更新pre为当前节点
    if (T->ltag == 1) preThreading(T->lchild); //有左孩子递归线索化左子树
    if (T->rtag == 1) preThreading(T->rchild); //有右孩子递归线索化右子树
    return;
}

//根据前序线索二叉树输出前序序列
void preThreadingPrint(BTnodePointer T) {
    while (T != NULL) { //只要当前节点不为空
        cout << T->value << " "; //输出当前节点的内容
        if (T->ltag == 1) T = T->lchild; //如果有左孩子,那么左孩子必为后继节点
        else T = T->rchild; /*如果没有左孩子,那么左孩子指向了当前节点的前驱。
                              如果右孩子存在,那么右孩子就是后继,
                              如果右孩子不存在,那么右孩子肯定指向后继节点,
                              除非是最后一个节点右孩子会指向NULL,
                              那么此时恰好跳出while循环,输出结束*/
    }
    cout << endl;
    return;
}

//主运行函数
void binaryTree(void) {

    //T就是创建的二叉树的根节点的指针,定义的时候还没有这个树,先赋值为NULL
    BTnodePointer T, pre = NULL;

    cout << "输入二叉树的前序序列,输入#表示空指针,程序会根据输入自动创建一棵二叉树(建议输入内容不要超过20个字符)。" << endl;
    T = createBinaryTree();
    cout << "二叉树创建完成!接下来进行前序线索化。" << endl;
    preThreading(T);
    cout << "线索化完成!按照前序线索二叉树的性质输出前序序列:" << endl;
    preThreadingPrint(T);

    return;
}

int main() {

    binaryTree();

    system("pause");
    return 0;
}

 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值