一步一步寫演算法(之排序二叉樹)

2021-06-26 04:43:56 字數 2787 閱讀 5408

**: 

前面我們講過雙向鍊錶的資料結構。每乙個迴圈節點有兩個指標,乙個指向前面乙個節點,乙個指向後繼節點,這樣所有的節點像一顆顆珍珠一樣被一根線穿在了一起。然而今天我們討論的資料結構卻有一點不同,它有三個節點。它是這樣定義的:

[cpp]view plain

copy

print?

typedef

struct _tree_node  

tree_node;  

typedef struct _tree_node

tree_node;

根據上面的資料結構,我們看到每乙個資料節點都有三個指標,分別是:指向父母的指標,指向左孩子的指標,指向右孩子的指標。每乙個節點都是通過指標相互連線的。相連指標的關係都是父子關係。那麼排序二叉樹又是什麼意思呢?其實很簡單,只要在二叉樹的基本定義上增加兩個基本條件就可以了:(1)所有左子樹的節點數值都小於此節點的數值;(2)所有右節點的數值都大於此節點的數值。

既然看到了節點的定義,那麼我們並可以得到,只要按照一定的順序遍歷,可以把二叉樹中的節點按照某乙個順序列印出來。那麼,節點的建立、查詢、遍歷是怎麼進行的呢,二叉樹的高度應該怎麼計算呢?我們一一道來。

1)建立二叉樹節點

[cpp]view plain

copy

print?

tree_node* create_tree_node(int data)    

tree_node* create_tree_node(int data)

分析:我們看到,二叉樹節點的建立和我們看到的鍊錶節點、堆疊節點建立沒有什麼本質的區別。首先需要為節點建立記憶體,然後對記憶體進行初始化處理。最後將輸入引數data輸入到tree_node當中即可。

2)資料的查詢

[cpp]view plain

copy

print?

tree_node* find_data_in_tree_node(const tree_node* ptreenode, int data)    

tree_node* find_data_in_tree_node(const tree_node* ptreenode, int data)

分析:我們的查詢是按照遞迴迭代進行的。因為整個二叉樹是乙個排序二叉樹,所以我們的資料只需要和每乙個節點依次比較就可以了,如果數值比節點資料小,那麼向左繼續遍歷;反之向右繼續遍歷。如果遍歷下去遇到了null指標,只能說明當前的資料在二叉樹中還不存在。

3)資料統計

[cpp]view plain

copy

print?

int count_node_number_in_tree(const tree_node* ptreenode)    

int count_node_number_in_tree(const tree_node* ptreenode)

分析:和上面查詢資料一樣,統計的工作也比較簡單。如果是節點指標,那麼直接返回0即可,否則就需要分別統計左節點樹的節點個數、右節點樹的節點個數,這樣所有的節點總數加起來就可以了。

4)按照從小到大的順序列印節點的資料

[cpp]view plain

copy

print?

void print_all_node_data(const tree_node* ptreenode)  

}  

void print_all_node_data(const tree_node* ptreenode)

}

分析:因為二叉樹本身的特殊性,按順序列印二叉樹的函式本身也比較簡單。首先列印左子樹的節點,然後列印本節點的數值,最後列印右子樹節點的數值,這樣所有節點的數值就都可以列印出來了。

5)統計樹的高度

[cpp]view plain

copy

print?

int calculate_height_of_tree(const tree_node* ptreenode)    

int calculate_height_of_tree(const tree_node* ptreenode)

分析:樹的高度其實是指所有葉子節點中,從根節點到葉子節點的最大高度可以達到多少。當然,程式中表示得已經很明白了,如果節點為空,那麼很遺憾,節點的高度為0;反之如果左子樹的高度大於右子樹的高度,那麼整個二叉樹的節點高度就是左子樹的高度加上1;如果右子樹的高度大於左子樹的高度,那麼整個二叉樹的高度就是右子樹的高度加上1。計算樹的高度在我們設計平衡二叉樹的時候非常有用,特別是測試的時候,希望大家多多理解,熟練掌握。

總結:

2)二叉樹很多的操作是和堆疊緊密聯絡在一起的,如果大家暫時理解不了遞迴,可以用迴圈或者堆疊代替;

3)實踐出真知,大家可以自己對排序二叉樹的**多多練習。不瞞大家說,我個人寫平衡二叉樹不下20多遍,即使這樣也不能保證每次都正確;即使這樣,我每次寫**的都有不同的感覺。

一步一步寫演算法(之排序二叉樹)

前面我們講過雙向鍊錶的資料結構。每乙個迴圈節點有兩個指標,乙個指向前面乙個節點,乙個指向後繼節點,這樣所有的節點像一顆顆珍珠一樣被一根線穿在了一起。然而今天我們討論的資料結構卻有一點不同,它有三個節點。它是這樣定義的 cpp view plain copy typedef struct tree n...

一步一步寫演算法(之排序二叉樹)

前面我們講過雙向鍊錶的資料結構。每乙個迴圈節點有兩個指標,乙個指向前面乙個節點,乙個指向後繼節點,這樣所有的節點像一顆顆珍珠一樣被一根線穿在了一起。然而今天我們討論的資料結構卻有一點不同,它有三個節點。它是這樣定義的 cpp view plain copy typedef struct tree n...

一步一步寫演算法(之排序二叉樹)

前面我們講過雙向鍊錶的資料結構。每乙個迴圈節點有兩個指標,乙個指向前面乙個節點,乙個指向後繼節點,這樣所有的節點像一顆顆珍珠一樣被一根線穿在了一起。然而今天我們討論的資料結構卻有一點不同,它有三個節點。它是這樣定義的 typedef struct tree node tree node 根據上面的資...