二叉树转换成双向链表

Posted joke-shi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树转换成双向链表相关的知识,希望对你有一定的参考价值。

前言

  二叉树我们都是知道,一个节点有两个子节点,分别为左右子节点,树形结构则分叉左右子树。如何把二叉树转换成双向链表,方式方法有许多,这里主要介绍一种方法,直接在二叉树本身的左右链上做文章,采用递归的方式。

  方法步骤如下:

    1. 先转换做子树为链式结构,其递归到做子树最左边的叶子节点;

              2. 链表最初的头节点为左子树的最左叶子节点;

              3. 转换右子树的链式结构;

    4. 记录右子树链式的尾节点;

    5. 合并左子树和右子树的链式结构,

  总之,递归深入到左叶子节点,从左子树递归回退向上深入右子树,最后合并链式的一个捣鼓过程;整个过程可以想象为:从最左下角开始,然后上升,接着进入局部右下角,最后合并,按照上述步骤捣鼓捣鼓直到山崩地裂。

 

编码

#include <iostream>


struct tree_node_t {
    unsigned int value;
    tree_node_t *left;
    tree_node_t *right;
};



int tree_create( tree_node_t *&__root)
{
    int rc = 0;

    __root = nullptr;

    return rc;
}


int tree_push( tree_node_t *&__root, unsigned int __v)
{
    int rc = 0;

    if ( !__root) {
        __root = new tree_node_t();
        if ( nullptr != __root) {
            __root->value = __v;
            __root->left  = nullptr;
            __root->right = nullptr;

        } else { rc = -1; }
    } else {
        if ( __v < __root->value) {
            rc = tree_push( __root->left, __v);
        }

        if ( __v > __root->value) {
            rc = tree_push( __root->right, __v);
        }
    }

    return rc;
}


void tree_each( const tree_node_t *__root)
{
    if ( __root) {
        tree_each( __root->left);

        std::cout << __root->value << " ";

        tree_each( __root->right);
    }
}



void tree_to_list( tree_node_t *&__current, tree_node_t *&__head, tree_node_t *&__tail)
{
    if ( nullptr != __current) {
        tree_node_t *head  = nullptr;
        tree_node_t *tail  = nullptr;

        /** Link of a left subtree */
        if ( __current->left) {
            (void )tree_to_list( __current->left, head, tail); {
                __head          = head;
                __current->left = tail;
                tail->right     = __current;
            }
        } else {
            __head = __current;
        }

        /** Link of a right subtree */
        if ( __current->right) {
            (void )tree_to_list( __current->right, head, tail); {
                __tail            = tail;
                __current->right  = head;
                head->left        = __current;
            }
        } else {
            __tail = __current;
        }
    } else {
        __current = nullptr;
        __head    = nullptr;
        __tail    = nullptr;
    }

    __current = __head;
}


void tree_list_each( const tree_node_t *__head)
{
    if ( __head) {
        std::cout << __head->value << " ";

        tree_list_each( __head->right);
    }
}


int main( int argc, const char **argv)
{
    tree_node_t *root = nullptr;
    tree_create( root);

    srand( time( NULL));

    for ( unsigned int i = 0; i < 32; i++) {
        tree_push( root, rand() % 100);
    }

    std::cout << "
tree_each:
";
    tree_each( root);

    tree_node_t *tmp_head = nullptr;
    tree_node_t *tmp_tail = nullptr;
    tree_to_list( root, tmp_head, tmp_tail);

    std::cout << "
tree_list_each:
";
    tree_list_each( root);
    std::cout << "
";

    return 0;
}

 

注:该代码采用c++11实现,毕竟nullptr是c++11引入,编译时加 -std=c++11 选项。

 

 

    

以上是关于二叉树转换成双向链表的主要内容,如果未能解决你的问题,请参考以下文章

栈和队列----将搜索二叉树转换成双向链表

左神算法书籍《程序员代码面试指南》——2_12将搜索二叉树转换成双向链表★★

新手学习算法----二叉树(将一个二叉查找树按照中序遍历转换成双向链表)

将搜索二叉树转换成双向链表

二叉树与双向链表的转换

二叉树与链表