二叉树转换成双向链表
前言
二叉树我们都是知道,一个节点有两个子节点,分别为左右子节点,树形结构则分叉左右子树。如何把二叉树转换成双向链表,方式方法有许多,这里主要介绍一种方法,直接在二叉树本身的左右链上做文章,采用递归的方式。
方法步骤如下:
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 << "\ntree_each:\n"; 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 << "\ntree_list_each:\n"; tree_list_each( root); std::cout << "\n"; return 0; }
注:该代码采用c++11实现,毕竟nullptr是c++11引入,编译时加 -std=c++11 选项。