資料結構 樹(三) 二叉查詢樹

2021-10-06 06:00:32 字數 3510 閱讀 6154

二叉查詢樹的性質

例子二叉查詢樹(bst)是一種特殊的二叉樹,又稱為排序二叉樹、二叉搜尋樹、二叉排序樹。二叉查詢樹實際是一棵資料域有序的二叉樹。二叉查詢樹的遞迴定義如下:

要麼二叉查詢樹是一棵空樹。

要麼二叉查詢樹由根結點、左子樹、右子樹組成,其中左子樹和右子樹都是二叉查詢樹,且左子樹上所有結點的資料域均小於或等於根結點的資料域,右子樹上所有結點的資料域均大於根結點的資料域。

查詢將會是從樹根到查詢結點的一條路徑。思路:

如果當前根節點root為空,說明查詢失敗,返回。

如果需要查詢的值x等於當前根節點的資料域root->data,說明查詢成功,訪問它。

如果需要找到的值x小於當前根節點的資料域root->data,說明應該往左子樹查詢,因此向root->lchild遞迴。

如果需要找到的值x大於當前根節點的資料域root->data,說明應該往右子樹查詢,因此向root->rchild遞迴。

//search函式查詢二叉查詢樹中資料域為x的結點

void

search

(node* root,

int x)

if(x == root-

>data)

else

if(x < root-

>data)

else

}

二叉查詢樹中的資料域順序是:左子樹《根節點《右子樹

當查詢失敗時,說明此處是應該插入的位置,在root==null時新建需要插入的節點。

//insert函式將在二叉樹中插入乙個資料域為x的新結點(root加&)

void

insert

(node*

&root,

int x)

if(x == root-

>data)

else

if(x >data)

else

}

先後插入n個結點的過程。

//建立

node*

create

(int data,

int n)

return root;

}

即便是一組相同的數字,如果插入它們的順序不同,最後生成的二叉查詢樹也可能不同。

假設要刪除根節點5,為了使刪除後的二叉樹仍然是一棵二叉查詢樹,一種辦法是以樹中比5小的最大結點(結點4)覆蓋結點5,然後刪除原來的結點4;另一種辦法是把樹中比5大的最小結點(結點6)覆蓋結點5,然後刪除原來的結點6。

二叉查詢樹中比結點權值小的最大結點稱為該結點的前驅,比結點權值大的最小結點稱為該結點的後繼。顯然,結點的前驅是該結點左子樹的最右節點(從左子樹根節點開始不斷沿著root->rchild往下直到rchild==null時的結點),而結點的後繼是該結點右子樹的最左節點(···沿著lchild···lchild····)。

//尋找以root為根結點的樹中的最大權值結點(前驅結點)

node*

findmax

(node* root)

return root;

}//尋找以root為根結點的樹中的最小權值結點(後繼結點)

node*

findmin

(node* root)

return root;

}

用n的前驅或後繼來替代n的刪除操作:

//刪除以root為根結點的樹中權值為x的結點

void

deletenode

(node*

&root,

int x)

else

if(root-

>lchild !=

null

)else

}else

if(root-

>data > x)

else

}

對二叉查詢樹進行中序遍歷,遍歷的結果是有序的

給出n個正整數來作為一棵二叉排序樹的結點的插入順序,問:這串串行是否是該二叉排序出的先序序列或者是該二叉排序樹的映象樹的先序序列,同時輸出這棵樹的後序序列。所謂映象樹是指交換二叉樹的所有結點的左右子樹而形成的樹。

思路:對映象樹的先序遍歷只需要在原樹的先序遍歷時交換左右子樹的訪問順序即可:

//映象樹先序遍歷,結果存放vi

void

preordermirror

(node* root,vector<

int>

&vi)

使用vector來存放初始序列、先序序列、映象樹先序序列,可以方便比較(兩個vector可以直接使用『==』比較);若使用陣列,需要迴圈才能實現比較。

#include

using

namespace std;

struct node

;//插入結點

void

insert

(node* root,

int x)

if(root-

>data > x)

else

}void

preorder

(node* root,vector<

int>

&vi)

//映象樹先序遍歷

void

preordermirror

(node* root,vector<

int>

&vi)

//後序遍歷,結果存放vi

void

postorder

(node* root,vector<

int>

&vi)

//映象樹後序遍歷

void

postordermirror

(node* root,vector<

int>

&vi)

//origin存放原始序列

//pre,post為先序後序,prem,postm為映象樹先序後序

vector<

int> origin,pre,post,prem,postm;

intmain()

preorder

(root,pre)

;//求先序

postorder

(root,post)

;//求後序

postordermirror

(root,postm)

;//求映象後序

preordermirror

(root,prem)

;//求映象先序

if(origin == pre)

}else

if(origin == prem)

}else

return0;

}

資料結構 9 樹 三 ( 二叉樹儲存結構 )

之前已經談過了樹的儲存結構,並且說到順序儲存對樹這一種一對多的關係的結構實現起來比較困難。但是二叉樹是一種特殊的樹,由於它的特殊性,使得用順序儲存結構也可以實現。二叉樹的順序儲存結構就是用一維陣列儲存二叉樹中的結點,並且結點的儲存位置,也就是陣列的下標,要能體現結點之間的邏輯關係,如雙親與孩子的關係...

資料結構之樹(三) 二叉樹定義和性質

二叉樹 binary tree 是n n 0 個結點的有限集合,該集合或者為空集 稱為空二叉樹 或者由乙個根結點和倆棵互不相交的,分別稱為根結點的左子樹和右子樹的二叉樹組成。如圖 二叉樹的特點 1.每個結點最多有倆棵子樹,所以二叉樹中不存在度大於2的結點。2.左子樹和右子樹是有順序的,次序不能任意顛...

資料結構 二叉樹(三)二叉樹的深度

給定一棵二叉樹,求該二叉樹的深度 二叉樹深度定義 從根結點到葉結點依次經過的結點 含根 葉結點 形成樹的一條路徑,最長路徑的節點個數為樹的深度 1.1輸入第一行是乙個整數n,表示二叉樹的結點個數。二叉樹結點編號從1到n,根結點為1,n 10 接下來有n行,依次對應二叉樹的n個節點。每行有兩個整數,分...