前言
二叉樹我們都是知道,一個節點有兩個子節點,分別為左右子節點,樹形結構則分叉左右子樹。如何把二叉樹轉換成雙向鏈表,方式方法有許多,這里主要介紹一種方法,直接在二叉樹本身的左右鏈上做文章,采用遞歸的方式。
方法步驟如下:
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 選項。
