二叉查找樹 / 二叉搜索樹 數據結構原理、示例和算法實現

二叉查找樹

  • 特點
    1. 左子樹所有值都小於根值
    2. 右子樹所有值都大於根值
    3. 理論上不能有相同

  • 操作
    • 查找
    • 插入
    • 刪除

查找

  1. 判斷與根值是否相等,相等則完成
  2. 否則,判斷與根值大小關係
  3. 若小於根值,則:當目標值存在時,值一定左子樹裏
  4. 若大於根值,則:當目標值存在時,值一定右子樹裏
  5. 當搜索到空時,則不存在
BST search( keytype  k, BST  F ) // k:目標值;F:當前查找子樹的根節點
{
	p = F ;
	if ( p == NULL ) return Null ;
	else if (k == p->data.key) return p; // 相等,查找成功
	else if (k <  p->data.key) // 目標值小於根值
		return search (k,  p->lchild); // 進入左子樹
	else if (k >  p->data.key) // 目標值大於根值
		return search (k,  p->rchild); // 進入右子樹
}

插入

  • 核心點:值一定在樹的最底端插入
  • 因此,從根節點往下搜索合適的插入位置時,一定要到一個***“空位”(NULL)才能新建節點***
  • 依據性質:左子樹的所有值一定小於根值,右子樹的所有值一定小於根值
    • 在任意一個時刻,小於根值則插入左子樹,大於根值則插入右子樹
    • 當選擇的子樹爲空時則插入(新建節點)
      • 程序中的這一步:先假設不爲空,進入這一節點(NULL),再在進入迭代時
Void Insert (Records R, BST &F)
{  
    if ( F == NULL ) { // 已經查找到底層,可以插入新節點
       		F = new CellType ; // 新建節點
           	F->data = R ; // 存值
           	F->lchild = NULL ; // 預設左右子樹都爲NULL
           	F->rchild = NULL ;
    }
    else  if ( R.key < F->data.key ) // 插入的值小於根值,往左子樹插入
           Insert ( R , F->lchild )
    else  if ( R.key >= F->data.key ) // 插入的值大於根值,往右子樹插入
           Insert ( R , F->rchild )
}

刪除

刪除三類結點:

  1. 被刪除的結點是葉子結點
  2. 被刪除的結點只有一顆非空的左子樹或右子樹
  3. 被刪除的結點有兩棵非空的子樹

Void  Delete ( keytype  k ,BST  &F )
{  
  if ( F != NULL )
     if ( k < F->data.key ) Delete( k, f->lchild ) ; // 目標值比根值小,進入左兒子
     else if  ( k > F->data.key ) Delete( k, f->rchild ); // 目標值比根值大,進入右兒子
     else // 找到該元素,開始刪除
             if ( F->rchild == NULL ) F = F->lchild ; // 一邊兒子爲空,則用另一邊兒子代替
        else if ( F->lchild == NULL ) F = F->rchild ;
        else  F->data = DeleteMin(F->rchild) // 兩邊都有兒子,進行DeleteMin操作
}
// 取右子樹中最小的(即最左兒子),DeleteMin以此爲例
// 同理,也可以取左子樹最大
Records  DeleteMin( F ) // F:右子樹的根
{
	records tmp ;
	BST  p ;
	if ( F->lchild == NULL ) { // 已經找到最左兒子
		p = F ;
		tmp = F->data ; // 暫存節點的信息
		F = F->rchild ; // 該節點刪除,右兒子補上(無左兒子 and 可能是空)
		Delete p ; // 刪除p(當前F)節點
		return tmp ; // 返回data給上個函數要刪除的點,即將右子樹的最左兒子的移到刪除點的位置
	}
	else
		return ( DeleteMin( F->lchild ) ; // 未找到最左,繼續往左找
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章