二叉樹的遍歷

2021-09-26 03:32:42 字數 2430 閱讀 2460

二叉樹的遍歷是指通過一定的順序訪問二叉樹的所有結點。遍歷方法一般有四種:先序遍歷、中序遍歷、後序遍歷和層次遍歷,其中,前三種一般使用深度優先搜尋(dfs)實現,而層次遍歷一般使用廣度優先搜尋(bfs)實現

把一顆二叉樹分為三個部分:根節點、左子樹、右子樹,且對左子樹和右子樹可以同樣進行這樣的劃分,這樣對樹的遍歷就可以分為對這三個部分的遍歷,這三種方法中,左子樹一定要先於右子樹遍歷,且所謂的「先中後」都是指根節點root在遍歷中的位置,因此先序遍歷的訪問順序是根節點-左子樹-右子樹;中序遍歷的訪問順序是左子樹-根節點-右子樹;後序遍歷的訪問順序是左子樹-右子樹-根節點。

對先序遍歷來說,總是先訪問根節點root,再訪問左子樹和右子樹,因此先序遍歷的順序是根節點-左子樹-右子樹

為了實現遞迴的先序遍歷,需要得到兩樣東西:遞迴式和遞迴邊界。其中遞迴式已經可以由先序遍歷直接得到,即先訪問根節點(可以做任何事情),再遞迴訪問左子樹,最後遞迴訪問右子樹,遞迴邊界就是子樹為空

先序遍歷的**如下:

void preorder(node *root)

//訪問根節點root,例如將其資料域輸出

printf("%d\n",root->data);

//訪問左子樹

preorder(root->lchild);

//訪問右子樹

preorder(root->rchild);

}

由於先序遍歷先訪問根節點,因此對一顆二叉樹的先序遍歷序列,序列的第乙個一定是乙個根節點。例如再上面的例子中,對整顆二叉樹,a是先序遍歷的第乙個,因此a是根節點,而對a的左子樹的三個結點,它們的先序序列是bde,由於b是第乙個,因此b是這顆樹的根節點。

中序遍歷的實現思路和先序遍歷相同,只不過把對根節點的訪問放到左子樹和右子樹中間,**如下:

void inorder(node *root)

//訪問左子樹

inorder(root->lchild);

//訪問根節點root,例如將其資料域輸出

printf("%d\n",root->data);

//訪問右子樹

inorder(root->rchild);

}

由於中序遍歷總是把根節點放在左子樹和右子樹中間,因此只要知道根節點,就可以通過根節點在中序遍歷中的位置區分出左子樹和右子樹。

與上述兩種方法思路相同,只是把根節點放在最後訪問

**如下:

void postorder(node *root)

//訪問左子樹

postorder(root->lchild);

//訪問右子樹

postorder(root->rchild);

//訪問根節點root,例如將其資料域輸出

printf("%d\n",root->data);

}

後序遍歷總是把根節點放在最後訪問,這和先序遍歷恰好相反。因此對後序遍歷來說,序列的最後乙個肯定是根結點

總的來說,無論是先序遍歷序列還是後序遍歷序列,都必須知道中序遍歷序列才能唯一的確定一棵樹,這是因為通過先序遍歷和後序遍歷都只能得到根節點,而只有中序遍歷才能把根節點的左右子樹分開,從而遞迴生成一顆二叉樹。當然,這個做法需要保證在所有元素都不相同時才能使用。

層次遍歷是指按層次的順序從根節點向下逐層進行遍歷,且對同一層的結點從左到右遍歷

層次遍歷相當於對二叉樹從根節點開始的廣度優先搜尋,其基本思路如下:

將根節點root加入佇列q

取出隊首結點,訪問它

如果該結點有左孩子,將左孩子入隊

如果該結點有右孩子,將右孩子入隊

返回2,知道隊列為空

按照上述描述寫出**如下:

//層次遍歷

void layerorder(node *root)

}

可以發現,這裡使用的佇列中的元素是node*型而不是node型。這是因為佇列中儲存的知識原元素的乙個副本,因此如果佇列中直接存放node 型,當需要修改隊首元素時,就會無法對原元素進行修改(即只修改了佇列中的副本),故讓佇列中存放node型變數的位址,也就是node*型變數。這樣就可以通過訪問位址去修改原元素,就不會有問題了。

另外還需指出,很多題目當中要求計算出每個結點所處的層次,這時就需要在二叉樹結點的定義中新增乙個記錄層次layer的變數

struct node;
需要在根節點入隊前就先令根節點的layer為1來表示根節點是第一層(也可以令根節點的層號為0,由題意而定),之後再now-lchild和noe-rchild入隊前,把它們的層號都記為當前結點的層號加1

**如下:

//層次遍歷

void layerorder(node *root)

if(now->rchild!=null)

}

}

二叉樹的遍歷 二叉樹遍歷與儲存

在資料結構中,二叉樹是非常重要的結構。例如 資料庫中經常用到b 樹結構。那麼資料庫是如何去單個查詢或者範圍查詢?首先得理解二叉樹的幾種遍歷順序 先序 中序 後序 層次遍歷。先序 根節點 左子樹 右子樹 中序 左子樹 根節點 右子樹 後序 左子樹 右子樹 根節點 按層級 class node if c...

構建二叉樹 遍歷二叉樹

陣列法構建二叉樹 public class main public static void main string args 用陣列的方式構建二叉樹 public static void createbintree 把linkedlist集合轉成二叉樹的形式 for int j 0 j 最後乙個父節...

玩轉二叉樹(二叉樹的遍歷)

時間限制 400 ms 記憶體限制 65536 kb 長度限制 8000 b 判題程式 standard 作者 陳越 給定一棵二叉樹的中序遍歷和前序遍歷,請你先將樹做個鏡面反轉,再輸出反轉後的層序遍歷的序列。所謂鏡面反轉,是指將所有非葉結點的左右孩子對換。這裡假設鍵值都是互不相等的正整數。輸入格式 ...