二叉樹迭代器演算法

2021-09-07 21:37:08 字數 2049 閱讀 4024

二叉樹(binary tree)的前序、中序和後續遍歷是演算法和資料結構中的基本問題,基於遞迴的二叉樹遍歷演算法更是遞迴的經典應用。

假設二叉樹結點定義如下:

struct node
中序遞迴遍歷演算法:

// c++

void inorder(node *node)

do_something(node);

if (null != node->right)

}

前序和後序遍歷演算法類似。

但是,僅有遍歷演算法是不夠的,在許多應用中,我們還需要對遍歷本身進行抽象。假如有乙個求和的函式sum,我們希望它能應用於鍊錶,陣列,二叉樹等等不同的資料結構。這時,我們可以抽象出迭代器(iterator)的概念,通過迭代器把演算法和資料結構解耦了,使得通用演算法能應用於不同型別的資料結構。我們可以把sum函式定義為:

int sum(iterator it)
鍊錶作為一種線性結構,它的迭代器實現非常簡單和直觀,而二叉樹的迭代器實現則不那麼容易,我們不能直接將遞迴遍歷轉換為迭代器。究其原因,這是因為二叉樹遞迴遍歷過程是編譯器在呼叫棧上自動進行的,程式設計師對這個過程缺乏足夠的控制。既然如此,那麼我們如果可以自己來控制整個呼叫棧的進棧和出棧不是就達到控制的目的了嗎?我們先來看看二叉樹遍歷的非遞迴演算法:

// c++

void inorder(node *node)

do }

while (!stack.empty());

}while (!stack.empty());

}

通過基於棧的非遞迴演算法我們獲得了對於遍歷過程的控制,下面我們考慮如何將其封裝為迭代器呢? 這裡關鍵在於理解遍歷的過程是由棧的狀態來表示的,所以顯然迭代器內部應該包含乙個棧結構,每次迭代的過程就是對棧的操作。假設迭代器的介面為:

class iterator ;
下面是乙個二叉樹中序遍歷迭代器的實現:

//c++

class inorderiterator : public iterator

}virtual node* next()

node *top = mstack.top();

mstack.pop();

if (null != top->right)

}return top;

}private:

std::stackmstack;

};

下面我們再來考察一下這個迭代器實現的時間和空間複雜度。很顯然,由於棧中最多需要儲存所有的結點,所以其空間複雜度是o(n)的。那麼時間複雜度呢?一次next()呼叫也最多會進行n次棧操作,而整個遍歷過程需要呼叫n次next(),那麼是不是整個迭代器的時間複雜度就是o(n^2)呢?答案是否定的!因為每個結點只會進棧和出棧一次,所以整個迭代過程的時間複雜度依然為o(n)。其實,這和遞迴遍歷的時空複雜度完全一樣。

除了上面顯式利用棧控制**執行順序外,在支援yield語義的語言(c#, python等)中,還有更為直接的做法。下面基於yield的二叉樹中序遍歷的python實現:

// python

def inorder(t):

if t:

for x in inorder(t.left):

yield x

yield t.label

for x in inorder(t.right):

yield x

yield與return區別的一種通俗解釋是yield返回時系統會保留函式呼叫的狀態,下次該函式被呼叫時會接著從上次的執行點繼續執行,這是一種與棧語義所完全不同的流程控制語義。我們知道python的直譯器是c寫的,但是c並不支援yield語義,那麼直譯器是如何做到對yield的支援的呢? 有了上面把遞迴遍歷變換為迭代遍歷的經驗,相信你已經猜到python直譯器一定是對yield**進行了某種變換。如果你已經能夠實現遞迴變非遞迴,不妨嘗試一下能否寫一段編譯程式將yield**變換為非yield**。

二叉樹演算法

include include include define elementtype int node structure constructor typedef struct bt binarytreenode,btroot function declear inorder btroot root...

二叉樹演算法

二叉樹的遍歷演算法 1.先序遍歷 對每乙個節點將其看作根節點按照根左右的順序進行遍歷。示例 void preordertree node root 先序遍歷二叉樹 return 2.中序遍歷 對每乙個節點將其看作根節點按照左根右的順序進行便利。示例 void inordertree node roo...

二叉樹演算法

include include define maxsize 20 define max 20 int count 0 int count1 0 int depth int du1 0 int du2 0 樹的儲存結構 typedef struct nodebinode,bitree 棧的儲存結構 ...