线索二叉树(Threaded Binary Tree)

来源:互联网 发布:java websocket 跨域 编辑:程序博客网 时间:2024/06/05 17:38

  二叉树中容易找到结点的左右孩子信息,但该结点在某一序列中的直接前驱和直接后继只能在某种遍历过程中动态获得。先依遍历规则把每个结点某一序列中对应的前驱和后继线索预存起来,这叫做”线索化”。这样,从任一结点出发都能快速找到其某一序列中前驱和后继,且不必借助堆栈。
  A threaded binary tree is a binary tree variant that allows fast traversal: given a pointer to a node in a threaded tree, it is possible to cheaply find its in-order successor (and/or predecessor).  
  The problem with recursive algorithm is that, because of its recursion, it uses stack space proportional to the height of a tree. If the tree is fairly balanced, this amounts to O(log n) space for a tree containing n elements. In the worst case, when the tree takes the form of a chain, the height of the tree is n so the algorithm takes O(n) space.

  A binary tree with n nodes would have 2n links, most of which would be unused. Total number of non-null links for an n node tree = n −1. Therefore, total number of unused null links = 2n − (n −1) = n +1 That’s a lot of wasted memory for large n. Threads could be set up on those unused links allowing one to traverse the tree iteratively

  A threaded binary tree defined as follows:
  “A binary tree is threaded by making all right child pointers that would normally be null point to the inorder successor of the node (if it exists), and all left child pointers that would normally be null point to the inorder predecessor of the node.”

  Types of threaded binary trees:
  1) Single Threaded: each node is threaded towards either the in-order predecessor or successor (left or right).
  2) Double threaded: each node is threaded towards both the in-order predecessor and successor (left and right).

Single Threaded:

struct Node {    int data;    Node *left, *right;    bool rightThread;  }

  Since right pointer is used for two purposes, the boolean variable rightThread is used to indicate whether right pointer points to right child or inorder successor. Similarly, we can add leftThread for a double threaded binary tree.

// Utility function to find leftmost node in atree rooted with nstruct Node* leftMost(struct Node *n){    if (n == NULL)       return NULL;    while (n->left != NULL)        n = n->left;    return n;}// C code to do inorder traversal in a threadded binary treevoid inOrder(struct Node *root){    struct Node *cur = leftmost(root);    while (cur != NULL)    {        cout<<cur->data;        // If this node is a thread node, then go to        // inorder successor        if (cur->rightThread)            cur = cur->right;        else // Else go to the leftmost child in right subtree            cur = leftmost(cur->right);    }}


Double threaded:

线索化:
  将一棵二叉树进行线索化就是为其空指针赋值的过程,所以需要对二叉树进行对应的遍历(如构建前序线索二叉树,就需要对二叉树进行前序遍历);如下例子是通过递归将一棵二叉树线索化为一棵中序线索二叉树:

void InOrderThreaded(ThreadedNode *cur, ThreadedNode *pre) {        if(cur==NULL)                return;        else {                /**                 * 中序遍历:首先处理左子树,然后当前节点,最后右子树                 * */                InOrderThreaded(cur->left, pre);                /**                 * 首先对当前节点的Lthread和Rthread标志进行初始化                 * */                if(cur->left==NULL)                        cur->Lthread=1;                else                        cur->Lthread=0;                if(cur->right==NULL)                        cur->Rthread=1;                else                        cur->Rthread=0;                /**                 * 一开始pre需要设置为NULL,但是也可以创建一个head节点,这样就                 * 不用每次都进行pre!=NULL的判断                 * */                if(pre!=NULL) {                        /**                         * 完成前一个节点的后续线索化                         * */                        if(pre->Rthread==1)                                pre->right=cur;                        /**                         * 完成当前节点的前驱线索化                         * */                        if(cur->Lthread==1)                                cur->left=pre;                }                pre=cur;                InOrderThreaded(cur->right, pre);        }}

  在线索化之后就可以进行前序、中序、后续遍历啦。

0 0
原创粉丝点击