二叉樹展開為鍊錶

2021-10-02 09:53:58 字數 3070 閱讀 6398

給定乙個二叉樹,原地將它展開為鍊錶。

例如,給定二叉樹

1/ \

2   5

/ \   \

3   4   6

將其展開為:1\

2\3\

4\5\

6解法1: 前序遍歷,

1.先儲存舊的右子樹,

2.把左子樹賦值給root.right,把左子樹置為nil

3.遍歷找到最右邊的節點,把舊的右子樹接到最右邊的葉子節點上

4.根節點處理完成,向下遞迴直到結束.

#import #import "node.h"

node * inittree()

node * inittree1()

void showtreeinfo(node * root)

nslog(@"%@",root);

showtreeinfo(root.left);

showtreeinfo(root.right);

}/** 原地展開,一開始想的是前序遍歷一下,把每個節點放到陣列裡,然後把陣列串起來就可以了,後來查了查,原地的意思.

在電腦科學中,乙個原地演算法(in-place algorithm)是一種使用小的,固定數量的額外之空間來轉換資料的演算法。

當演算法執行時,輸入的資料通常會被要輸出的部份覆蓋掉。*/

// 遞迴實現

void flatten(node * root)

if (root.left == nil)

// 儲存的舊的右子樹,把舊的右子樹放到拼接後的最右邊

node * oldright = root.right ;

root.right = root.left;

root.left = nil;

// 找到拼接後的最右邊葉子節點

node * rightmost = root.right;

while (rightmost.right)

rightmost.right = oldright;

flatten(root.right);

}int main()

還是同樣的思路,可以用迴圈來解決

// 非遞迴實現,

void flatten(node * root)

rightmost.right = oldright;

}// 繼續下乙個節點

root = root.right;

}}

解法2, 哼,我是解決問題的,管你什麼原地不原地的, 用最簡單的思路, 效率不太好o(2n),但是直觀啊,好閱讀好理解啊

1.前序遍歷,把每個節點加入到陣列中,

2.遍歷陣列,把每個節點的left置nil,右節點置為陣列中的下乙個元素.

// 前序遍歷,把節點都加入到陣列中

nsmutablearray * array = nil;

void addtreeinfo(node * root)

[array addobject:root];

addtreeinfo(root.left);

addtreeinfo(root.right);

}// 陣列實現,

void flatten(node * root)

flatten(root.right);

flatten(root.left);

if (prenode)

prenode = root;

}

最後4個解法來乙個彙總的. 

#import #import "node.h"

node * inittree()

node * inittree1()

void showtreeinfo(node * root)

nslog(@"%@",root);

showtreeinfo(root.left);

showtreeinfo(root.right);

}/** 原地展開,一開始想的是前序遍歷一下,把每個節點放到陣列裡,然後把陣列串起來就可以了,後來查了查,原地的意思.

在電腦科學中,乙個原地演算法(in-place algorithm)是一種使用小的,固定數量的額外之空間來轉換資料的演算法。

當演算法執行時,輸入的資料通常會被要輸出的部份覆蓋掉。*/

#pragma mark - 解法1,遞迴前序

// 遞迴實現

void flatten1(node * root)

if (root.left == nil)

// 儲存的舊的右子樹,把舊的右子樹放到拼接後的最右邊

node * oldright = root.right ;

root.right = root.left;

root.left = nil;

// 找到拼接後的最右邊葉子節點

node * rightmost = root.right;

while (rightmost.right)

rightmost.right = oldright;

flatten1(root.right);

}#pragma mark - 解法1,非遞迴前序

// 非遞迴實現,

void flatten2(node * root)

rightmost.right = oldright;

}// 繼續下乙個節點

root = root.right;

}}#pragma mark - 解法2,陣列前序

// 前序遍歷,把節點都加入到陣列中

nsmutablearray * array = nil;

void addtreeinfo(node * root)

[array addobject:root];

addtreeinfo(root.left);

addtreeinfo(root.right);

}// 陣列實現,

void flattenarray(node * root)

- (nsstring *)description

@end

二叉樹展開為鍊錶

給定乙個二叉樹,原地將它展開為鍊錶。例如,給定二叉樹 將其展開為 以根節點為基準,先處理左子樹,然後處理右子樹,當其左右子樹均轉化為鍊錶之後,再處理以該根節點所代表的樹,將其右子樹賦給臨時變數,設root.right root.left,並將左子樹置空,然後將臨時變數賦給root.right。pub...

二叉樹展開為鍊錶

給定乙個二叉樹,原地將它展開為鍊錶。例如,給定二叉樹 1 2 5 3 4 6將其展開為 1 2 3 4 5 6 解法解法一 1.對樹進行先序遍歷,把每遍歷乙個節點就將該節點入隊 2.遍歷完之後,對佇列進行出隊操作 3.每齣乙個節點,就將該節點的left指標置為null,右指標指向下乙個出隊的節點 d...

114 二叉樹展開為鍊錶

首先是原地演算法的定義 演算法原地工作的含義是指不需要任何額外的輔助,演算法所需要的輔助空間不隨著問題的規模而變化,是乙個確定的值。通過觀察示例可以知道,我們可以猜想,大方向是前序遍歷。第一種思路 dfs。設定乙個全域性的指標 這種做法有點脫離原地演算法,因為多開闢了乙個指標變數 核心思想是拿到乙個...