线索化二叉树

来源:互联网 发布:希腊经济知乎 编辑:程序博客网 时间:2024/06/14 04:13

中序线索化(递归):

图形解析:

这里写图片描述

代码如下:

//中序线索化    void InorderThreading()    {       Node* prev = NULL;       _InoderThreading(_root, prev);    }void _InoderThreading(Node* cur, Node* & prev)    {       if (cur)       {           _InoderThreading(cur->_left, prev);           if (NULL == cur->_left)//当前节点的左节点需要线索化           {               cur->_left = prev;               cur->_leftType = THREAD;           }           if (prev && NULL == prev->_right)//当前节点的前驱的右节点需要线索化           {               prev->_right = cur;               prev->_rightType = THREAD;           }           prev = cur;//更新prev           _InoderThreading(cur->_right, prev);       }    }

中序遍历中序线索化:

这里写图片描述

代码如下:

    //中序遍历    void InOrder()    {       _InOrder(_root);       cout << endl;    }//中序线索二叉树的中序遍历算法    void InorderThd()    {       Node* cur = _root;       while (cur)       {           //查找最左节点           while (cur->_leftType == LINK)           {               cur = cur->_left;           }           cout << cur->_data << " ";           //方法1           while (cur->_rightType == THREAD)           {               cur = cur->_right;               if (NULL == cur)               {                  return;               }               cout << cur->_data << " ";           }           //执行到此处-->说明右节点为右子树           cur = cur->_right;       }    }

前序线索化二叉树:

void _PreOrderThreading(Node* cur,Node*& prev)    {       if (NULL == cur)       {           return;       }       if (NULL == cur->_left)       {           cur->_left = prev;           cur->_leftType = THREAD;       }       if (prev && NULL == prev->_right)       {           prev->_right = cur;           prev->_rightType = THREAD;       }       prev = cur;//更新prev的值       if (cur->_leftType == LINK)//因为是先线索化后进行递归,为了避免死循环,所以需要判断       {           _PreOrderThreading(cur->_left, prev);       }       if (cur->_rightType == LINK)       {           _PreOrderThreading(cur->_right, prev);       }    }

前序遍历前序线索化二叉树:

前序线索化二叉树的前序遍历算法(下面的代码很坑、有问题):

//前序遍历二叉树    void PreOrderThd()    {       Node* cur = _root;       while (cur)       {           //访问左子树           while (cur->_leftType == LINK)           {               cout << cur->_data << " ";               cur = cur->_left;           }           //此时的cur->_leftType == THREAD           cout << cur->_data << " ";           //1.子问题  2.cur->_rightType = THREAD           while (cur->_rightType == THREAD)           {               cur = cur->_right;               cout << cur->_data << " ";           }           cur = cur->_right;//子问题       }    }

测试代码1如下:

int array1[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };    BinaryTreeThd<int> bt1(array1, sizeof(array1) / sizeof(int), '#');    bt1.PreOrder();    bt1.PreOrderThreading();    bt1.PreOrderThd();

结果如下:

这里写图片描述

测试代码2如下:

  int array[15] = { 1, 2, '#', 3, '#', '#', 4, 5, '#', 6, '#', 7, '#', '#', 8 };    BinaryTreeThd<int> bt(array, sizeof(array) / sizeof(int), '#');    bt.PreOrder();    bt.PreOrderThreading();    bt.PreOrderThd();

这里写图片描述

很明显,结果不对,下面我们来仔细分析其中存在的问题:

这里写图片描述

将上面的程序改之:

//前序遍历二叉树    void PreOrderThd()    {       Node* cur = _root;       while (cur)       {           //访问左子树           while (cur->_leftType == LINK)           {               cout << cur->_data << " ";               cur = cur->_left;           }           //此时的cur->_leftType == THREAD           cout << cur->_data << " ";           cur = cur->_right;       }    }

测试代码如下:

void TestBinary(){    int array1[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };    BinaryTreeThd<int> bt1(array1, sizeof(array1) / sizeof(int), '#');    bt1.PreOrder();    bt1.PreOrderThreading();    bt1.PreOrderThd();    cout << endl;    int array[15] = { 1, 2, '#', 3, '#', '#', 4, 5, '#', 6, '#', 7, '#', '#', 8 };    BinaryTreeThd<int> bt(array, sizeof(array) / sizeof(int), '#');    bt.PreOrder();    bt.PreOrderThreading();    bt.PreOrderThd();}

结果如下:

这里写图片描述

代码如下:

#pragma once#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>#include <assert.h>using namespace std;enum PointerType{    LINK,    THREAD,};template<class T>struct BinaryTreeThdNode{    BinaryTreeThdNode(const T& value)    :_data(value)    , _left(NULL)    , _right(NULL)    , _leftType(LINK)    , _rightType(LINK)    {}    T _data;    BinaryTreeThdNode<T>* _left;    BinaryTreeThdNode<T>* _right;    PointerType _leftType;//标记是否需要线索化    PointerType _rightType;};template<class T>class BinaryTreeThd{    typedef BinaryTreeThdNode<T> Node;public:    BinaryTreeThd(const Node* node)       :_root(node)    {}    BinaryTreeThd(const T* arr, size_t size, const T& invalid)    {       size_t index = 0;       _root = _CreatTree(arr, size, invalid, index);    }    //先序遍历    void PreOrder()    {       _PreOrder(_root);       cout << endl;    }    //中序遍历    void InOrder()    {       _InOrder(_root);       cout << endl;    }    //后序遍历    void PostOrder()    {       _PostOrder(_root);       cout << endl;    }    //中序线索化    void InorderThreading()    {       Node* prev = NULL;       _InoderThreading(_root, prev);    }//中序线索二叉树的中序遍历算法    void InorderThd()    {       Node* cur = _root;       while (cur)       {           //查找最左节点           while (cur->_leftType == LINK)           {               cur = cur->_left;           }           cout << cur->_data << " ";           //方法1           while (cur->_rightType == THREAD)           {               cur = cur->_right;               if (NULL == cur)               {                  return;               }               cout << cur->_data << " ";           }           //执行到此处-->说明右节点为右子树           cur = cur->_right;       }    }    //前序线索二叉树的前序遍历算法    void PreOrderThreading()    {       Node* prev = NULL;       _PreOrderThreading(_root, prev);       if (NULL == prev)       {           prev->_rightType = THREAD;       }    }    void PreOrderThd()    {       if (NULL == _root)       {           return;       }       Node* cur = _root;       while (cur)       {           //访问根节点           cout << cur->_data << " ";           //访问左子树           while (cur->_leftType == LINK)           {               cur = cur->_left;               cout << cur->_data << " ";           }           //此时的cur->_leftType == THREAD           while (cur->_rightType == THREAD)           {               cur = cur->_right;               cout << cur->_data << " ";           }           cur = cur->_right;//子问题       }    }    //后序线索化二叉树    void PostOrderThreading()    {       Node* prev = NULL;       _PostOrderThreading(_root,prev);    }    //后序遍历    void PostOrderThd()    {       if (NULL == _root)       {           return;       }       Node* cur = NULL;       while (cur)       {           while (LINK == cur->_leftType || Link == cur->_rightType)           {               if (LINK == cur->_leftType)               {                  cur = cur->_left;               }               if (LINK == cur->_rightType)               {                  cur = cur->_right;               }           }           cout << cur->_data << " ";           Node* p = NULL;       }    }protected:    //左、右、根    void _PostOrderThreading(Node* cur,Node*& prev)    {       if (NULL == cur)       {           return;       }           _PostOrderThreading(cur->_left, prev);           _PostOrderThreading(cur->_right, prev);       if (NULL == cur->_left)       {           cur->_left = prev;           cur->_leftType = THREAD;       }       if (prev && NULL == prev->_right)       {           prev->_right = cur;           prev->_rightType = THREAD;       }       prev = cur;//更新prev的值    }    void _PreOrderThreading(Node* cur,Node*& prev)    {       if (NULL == cur)       {           return;       }       if (NULL == cur->_left)       {           cur->_left = prev;           cur->_leftType = THREAD;       }       if (prev && NULL == prev->_right)       {           prev->_right = cur;           prev->_rightType = THREAD;       }       prev = cur;//更新prev的值       if (cur->_leftType == LINK)//因为是先线索化后进行递归,为了避免死循环,所以需要判断       {           _PreOrderThreading(cur->_left, prev);       }       if (cur->_rightType == LINK)       {           _PreOrderThreading(cur->_right, prev);       }    }    void _PreOrder(Node* root)    {       if (root)       {           cout << root->_data << " ";           _PreOrder(root->_left);           _PreOrder(root->_right);       }    }    void _InOrder(Node* root)    {       if (root)       {           _InOrder(root->_left);           cout << root->_data << " ";           _InOrder(root->_right);       }    }    void _PostOrder(Node* root)    {       if (root)       {           _PostOrder(root->_left);           _PostOrder(root->_right);           cout << root->_data << " ";       }    }    void _InoderThreading(Node* cur, Node* & prev)    {       if (cur)       {           _InoderThreading(cur->_left, prev);           if (NULL == cur->_left)//当前节点的左节点需要线索化           {               cur->_left = prev;               cur->_leftType = THREAD;           }           if (prev && NULL == prev->_right)//当前节点的前驱的右节点需要线索化           {               prev->_right = cur;               prev->_rightType = THREAD;           }           prev = cur;//更新prev           _InoderThreading(cur->_right, prev);       }    }    Node* _CreatTree(const T* arr, size_t size, const T& invalid, size_t& index)    {       Node* newRoot = _root;       if (index < size && arr[index] != invalid)       {           newRoot = new Node(arr[index]);           newRoot->_left = _CreatTree(arr, size, invalid, ++index);           newRoot->_right = _CreatTree(arr, size, invalid, ++index);       }       return newRoot;    }private:    Node* _root;};前序线索化二叉树:void _PreOrderThreading(Node* cur,Node*& prev)    {       if (NULL == cur)       {           return;       }       if (NULL == cur->_left)       {           cur->_left = prev;           cur->_leftType = THREAD;       }       if (prev && NULL == prev->_right)       {           prev->_right = cur;           prev->_rightType = THREAD;       }       prev = cur;//更新prev的值       if (cur->_leftType == LINK)//因为是先线索化后进行递归,为了避免死循环,所以需要判断       {           _PreOrderThreading(cur->_left, prev);       }       if (cur->_rightType == LINK)       {           _PreOrderThreading(cur->_right, prev);       }    }

中序线索化二叉树的迭代器:

template<class T>struct BinaryTreeThdIterator{    typedef BinaryTreeThdNode<T> Node;    typedef BinaryTreeThdIterator<T> self;    BinaryTreeThdIterator(Node* node)       :_node(node)    {}    T& operator*()    {       return _node->_data;    }    T* operator->()    {       return &(_node->_data);    }    self& operator++()    {       //后继       if (_node->_rightType == THREAD)       {           _node = _node->_right;       }       else//子问题       {           Node* cur = _node->_right;           while (cur->_leftType == LINK)           {               cur = cur->_left;           }           _node = cur;       }       return *this;    }    bool operator!=(const self& cur)const    {       return _node != cur._node;    }    bool operator==(const self& cur)const    {       return _node == cur._node;    }    Node* _node;};

总结:
本文概要:1.中序线索化二叉树
2.中序遍历中序线索化二叉树
3.前序线索化二叉树
4.前序遍历前序线索化二叉树(易入坑)
5.中序线索化二叉树的迭代器