資料結構,資料結構與演算法
動態尋找
當尋找表以順序儲存結構儲存且需要保持有序時,若對尋找表進行插入、刪除或排序操作,就必須移動大量的記錄,當記錄數很多時,這種移動的代價很大。
若尋找表無序,則插入刪除可無需移動大量記錄,但於尋找不利。
利用樹的形式組織尋找表,可以對尋找表進行動態高效的尋找。
二叉排序樹
二叉排序樹(Binary Sort Tree或Binary Search Tree) 的定義為:二叉排序樹或者是空樹,或者是滿足下列性質的二叉樹。
(1) :若左子樹不為空白,則左子樹上所有結點的值(關鍵字)都小於根結點的值;
(2) :若右子樹不為空白,則右子樹上所有結點的值(關鍵字)都大於根結點的值;
(3) :左、右子樹都分別是二叉排序樹。
結論:若按中序遍曆一棵二叉排序樹,所得到的結點序列是一個遞增序列。
BST樹的尋找
1 尋找思想 ①若根結點為空白,則表示尋找失敗; ②根節點非空,將給定的K值與二叉排序樹的根結點的關鍵字進行比較若相等: 則尋找成功; ③ 給定的K值小於BST的根結點的關鍵字:繼續在該結點的左子樹上進行尋找; ④ 給定的K值大於BST的根結點的關鍵字:繼續在該結點的右子樹上進行尋找。
2 演算法實現BSTNode *BST_Serach(BSTNode *T , KeyType key){ if (T==NULL) return(NULL) ;else { if (T->key==key) ) return(T) ;else if (key< T->key) ) return(BST_Serach(T->Lchild, key)) ; else return(BST_Serach(T->Rchild, key)) ;}}
BST樹的插入
插入的過程與尋找類似,只是當尋找不成功時,根據關鍵字與根結點的大小,將新結點(關鍵字的值)插入根結點的相應孩子的位置(左或者右). 在BST樹中插入一個新結點,要保證插入後仍滿足BST的性質。
1 插入思想
在BST樹中插入一個新結點x時,若BST樹為空白,則令新結點x為插入後BST樹的根結點;否則,將結點x的關鍵字與根結點T的關鍵字進行比較:
① 若相等: 不需要插入;
② 若x.keykey:結點x插入到T的左子樹中;
③ 若x.key>T->key:結點x插入到T的右子樹中。
演算法實現⑴ 遞迴演算法⑵ 非遞迴演算法void Insert_BST (BSTNode *T , KeyType key){ BSTNode *x, *p , *q ;x=(BSTNode *)malloc(sizeof(BSTNode)) ;X->key=key; x->Lchild=x->Rchild=NULL ;if (T==NULL) T=x ;else { p=T ; while (p!=NULL){ if (p->key==x->key ) return ; q=p ; /*q作為p的父結點 */ if (x->key< p->key) ) p=p->Lchild ; else p=p->Rchild ; } if (x->key<q->key ) q->Lchild=x ; else q->Rchild=x ; }}
對於一個無序序列可以通過構造一棵BST樹而變成一個有序序列。
由演算法知,每次插入的新結點都是BST樹的葉子結點,即在插入時不必移動其它結點,僅需修改某個結點的指標。
利用BST樹的插入操作,可以從空樹開始逐個插入每個結點,從而建立一棵BST樹
二叉排序樹效能
二叉排序樹尋找關鍵字的比較次數,等於該結點所在的層次數(尋找成功); 若尋找不成功,其比較次數最多為樹的深度。
對於一棵具有n個結點的樹來說,其深度介於㏒2n+1與n之間。
二叉排序樹的形態對於尋找效率至關重要,或者說,一棵二叉排序樹不一定就能提高尋找的速度,而是要看這棵樹的形態。
平衡二叉排序樹
如果能構造出一棵左右子樹相對“均衡”的樹,則樹的深度就會比較小,就能體現出二叉排序樹的良好性質,尋找時能得到最好的效率,這就是平衡二叉排序樹。
平衡二叉排序樹(Balanced Binary Tree或Height-Balanced Tree)是在1962年由俄羅斯數學家Adelson-Velskii和Landis提出的,又稱AVL樹。
平衡二叉樹的定義
平衡二叉樹或者是空樹,或者是滿足下列性質的二叉樹。
⑴ 左子樹和右子樹深度之差的絕對值不大於1;
⑵ 左子樹和右子樹也都是平衡二叉樹。
平衡因子(Balance Factor) :二叉樹上結點的左子樹的深度減去其右子樹深度。
平衡二叉樹上每個結點的平衡因子只可能是-1、0和1,如果有一個結點的平衡因子的絕對值大於1, 該二叉樹就不是平衡二叉樹。
如果一棵二叉樹既是二叉排序樹又是平衡二叉樹,稱為平衡二叉排序樹(Balanced Binary Sort Tree) 。
結點類型定義如下:
typedef struct BNode{ KeyType key ; /* 關鍵字域 */int Bfactor ; /* 平衡因子域 */… /* 其它資料域 */struct BNode *Lchild , *Rchild ;}BSTNode ;
在平衡二叉排序樹上執行尋找的過程與二叉排序樹上的尋找過程完全一樣,即在AVL樹上執行尋找時,和給定的K值比較的次數不超過樹的深度。
具有n個結點的AVL樹,最大深度是多少?
含義n個結點的平衡二叉樹的最大深度是O(㏒2n)
在平衡二叉排序樹上進行尋找的平均尋找長度和
㏒2n同一個數量級,平均時間複雜度為O(㏒2n)。
平衡二叉排序樹的構造
基本思想
在構建二叉排序樹的過程中,每當插入(刪除)一個結點時,
先檢查是否因插入而破壞了平衡,
若是,則找出最小不平衡子樹,在保持二叉排序樹特性的前提下,調整最小不平衡子樹中各結點之間的連結關係,進行相應的旋轉,使之成為新的平衡子樹。