【数据结构】二叉树的线索化!!

二叉树的缺点:

在二叉树的数据结构里面,如果是利用递归的方式创建的,那么就存在栈溢出的缺陷,如果采用循环的方式创建的话,那么就存在着空间复杂度过高的缺点。
同时在二叉树里面如果含有N个结点的话,那么没有使用的结点指针就含有(N+1)个,那么就造成大量的结点指针浪费。

解决方法

如果在创建二叉树的时候将这些没有使用的结点指针用来存储这些结点的前驱和后继结点 ,那么在遍历的时候就会更加的方便。
  • 前序线索化:
    二叉树前序线索化

    • 将二叉树线索化之后,那么遍历二叉树的元素就会大大减少对内存的浪费。

    前序线索化代码:

void PreThrade(Node* root,Node*& prev)                              //Thrade from front
        {
            if(NULL == root)
                return ;
            if(NULL == root->leftTree)
            {
                root->leftTree = prev;
                root->leftThrade = THRADE;
            }
            if(prev && NULL == prev->rightTree)
            {
                prev->rightTree = root;
                prev->rightThrade = THRADE;
            }
            prev = root;
            if(LINK == prev->leftThrade)
            {
                _PreThrade(root->leftTree,prev);
            }
            if(LINK == root->rightThrade)
            {
                _PreThrade(root->rightTree,prev);
            }

        }
  • 中序线索化二叉树
    这里写图片描述
    中序线索化代码:
void _InThrade(Node* root,Node*& prev)                  //Thrade tree from mid
        {
            if(NULL == root)
                return ;
            if(LINK == root->leftThrade)
                _InThrade(root->leftTree,prev);

            if(NULL == root->leftTree)
            {
                root->leftTree = prev;
                root->leftThrade = THRADE;
            }
            if(prev && NULL == prev->rightTree)
            {
                prev->rightTree = root;
                prev->rightThrade = THRADE;
            }
            prev = root;
            if(LINK == root->rightThrade)
                _InThrade(root->rightTree,prev);
        }
  • 后序线索化二叉树
    这里写图片描述
    后序线索化代码:
void _BackThrade(Node* root,Node*& prev)              //Theade tee from back
        {
            if(NULL == root)
                return ;
            if(LINK == root->leftThrade)
                _BackThrade(root->leftTree,prev);
            if(LINK == root->rightThrade)
                _BackThrade(root->rightTree,prev);
            if(NULL == root->leftTree)
            {
                root->leftTree = prev;
                root->leftThrade = THRADE;
            }
            if(prev && NULL == prev->rightThrade)
            {
                prev->rightTree = root;
                prev->rightThrade = THRADE;
            }
            prev = root;
        }
  • 线索化二叉树的前序遍历:
  • 代码
 void _PreOrder(Node* root)
        {
            if(NULL == root)
                return ;
            while(root)
            {
                while(LINK == root->leftThrade)
                {
                    cout<<root->data<<" ";
                    if(root->leftTree)
                        root = root->leftTree;
                }
                if(NULL == root)
                    return ;
                cout<<root->data<<" ";
                root = root->rightTree;
                if(NULL == root)
                    return ;
                while(THRADE == root->rightThrade && NULL != root->rightTree)
                {
                    cout<<root->data<<" ";
                    root = root->rightTree;
                }
            }
        }
  • 后序线索化遍历:

代码:

 void _BackOrder(Node* root,Node* prev)
        {
            if(NULL == root)
                return ;
            Node* cur = root;
            while(cur)
            {
                while(cur->leftTree != prev && cur->leftThrade == LINK)             //走完树的左子树
                    cur = cur->leftTree;

                while(cur && cur->rightThrade == THRADE)                //走连在一起的后继结点
                {
                    cout<<cur->data<<" ";
                    prev = cur;
                    cur = cur->rightTree;
                }
                if(root == cur)      //判断cur是不是根结点
                {
                    cout<<cur->data<<" ";
                    return ;
                }
                while(cur && cur->rightTree == prev)      
                {
                    cout<<cur->data<<" ";
                    prev = cur;
                    cur = cur->parent;
                }
                if(cur && cur->rightThrade == LINK)
                    cur = cur->rightTree;
            }
        }
  • 注:这里的的后序遍历的时候要考虑左单支和右单支的情况!!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值