833系列——二叉排序树
考綱中,二叉排序樹在“查找”章節,要求為:二叉排序樹及其基本操作。
其基本操作有:查找操作,插入操作,刪除操作
一:定義
二叉排序樹(Binary Sort Tree),又稱二叉查找樹,它是一顆空樹,或者是具有以下性質的二叉樹:
若它的左子樹不空,則左子樹上所有結點的值均小于它的根節點的值。
若它的右子樹不空,則右子樹上所有結點的值均大于它的根節點的值。
它的左右子樹也都是二叉排序樹
二:首先定義一個二叉樹的結構
1 struct BSTree 2 { 3 int data; 4 BSTree *lchild, *rchild; 5 BSTree(int d = 0, BSTree *l = NULL, BSTree *r = NULL) 6 { 7 data = d; 8 lchild = l; 9 rchild = r; 10 } 11 };三:建立一個二叉排序樹
二叉排序樹的建立,其實就是由一個空樹,一個一個的插入數據形成的,也就是需要插入操作
而在插入操作中,我們需要找到插入數據合適的位置,這里又可以看做是查找操作
插入操作有遞歸和循環兩種寫法
循環寫法:
void insertTree1(BSTree* &root, int key) {if(root == NULL){BSTree *s = new BSTree(key);root = s;return;}BSTree *t = root;while(t->data != key){if(key > t->data && t->rchild != NULL)t = t->rchild;else if(key < t->data && t->lchild != NULL)t = t->lchild;else if(key > t->data && t->rchild == NULL){BSTree *s = new BSTree(key);t->rchild = s;}else if(key < t->data && t->lchild == NULL){BSTree *s = new BSTree(key);t->lchild = s;}} }遞歸寫法:
void insertTree2(BSTree* &root, int key) {if(root == NULL){BSTree *s = new BSTree(key);root = s;return;}if(key > root->data)insertTree2(root->rchild, key);elseinsertTree2(root->lchild,key); }查找操作由插入操作簡單修改得到,不再上代碼
四:刪除操作(重點)
刪除節點有三種情況:
要刪除的點為葉子節點,直接刪除即可;
要刪除的點只有左子樹,或只有右子樹,刪除節點后,將左子樹或右子樹整體移動到被刪除節點的位置即可;
要刪除的節點即有左子樹,又有右子樹;
第一、二種情況可以合并為第二種,第三種情況比較復雜
根據二叉排序樹的定義,節點刪除后,這個位置應該由與它大小相鄰的數代替,對于下面這張圖:
假設要刪除的節點為47,那么能夠代替這個位置的就是37和48,可以發現,這兩個數都有一個特點,37為47的左子樹中的最右子樹,48為47的右子樹的最左子樹
基于此可以這樣做:假定每次都用較小的數來代替,也就是37,此時51這邊整體就不用動了,只需要將37移動到47的位置,然后將37的整個左子樹移動到37原來的位置
代碼:
void Delete(BSTree* &node) {if(node->lchild == NULL){BSTree *temp = node;node = node->rchild;delete(temp);}else if(node->rchild == NULL){BSTree *temp = node;node = node->lchild;delete(temp);}else //用與該節點臨近且小于的點代替 {BSTree *newnode = node->lchild;BSTree *temp = node;while(newnode->rchild != NULL){temp = newnode;newnode = newnode->rchild;}node->data = newnode->data;if(temp != node)temp->rchild = newnode->lchild;elsetemp->lchild = newnode->lchild;delete(newnode);} } void DeleteTree(BSTree* &root, int key) {if(root == NULL)return;if(key == root->data)Delete(root);else if(key > root->data)return DeleteTree(root->rchild, key);elsereturn DeleteTree(root->lchild, key); }五:遍歷及測試數據
建好二叉排序樹后,使用中序遍歷,即可得到一個排好序的數列
void InOrder(BSTree *root) {if(root != NULL){InOrder(root->lchild);cout << root->data << " ";InOrder(root->rchild);} }測試數據
int main() {int a[12] = {29, 36, 62, 88, 58, 47, 35, 73, 51, 99, 37, 93};BSTree *root = NULL;for(int i=0; i<12; i++){insertTree2(root, a[i]);}InOrder(root);cout << endl;DeleteTree(root, 47);InOrder(root);return 0; }?
轉載于:https://www.cnblogs.com/flyuz/p/9484100.html
總結
以上是生活随笔為你收集整理的833系列——二叉排序树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DialogFragment 将数据传回
- 下一篇: 某净化设备公司