您好,登錄后才能下訂單哦!
● 二叉搜索樹滿足以下條件的二叉樹:
1、每個節點都有一個作為搜索依據的關鍵碼(key),所有節點的關鍵碼互不相同。
2、左子樹上所有節點的關鍵碼(key)都小于根節點的關鍵碼(key)。
3、右子樹上所有節點的關鍵碼(key)都大于根節點的關鍵碼(key)。
4、左右子樹都是二叉搜索樹。
● 二叉搜索樹的插入過程如下:
1、若當前的二叉搜索樹為空,則插入的元素為根節點。
2、若插入的元素值小于根節點值,則將元素插入到左子樹中。
3、若插入的元素值大于根節點值,則將元素插入到右子樹中。
4、找到插入的位置和插入的位置的父結點,進行鏈接。
template<class T> void BSTree<T>::Insert(const T& key, const T& value)//非遞歸算法進行插入 { if (_root == NULL) { _root = new Node(key, value); return; } Node* prev = NULL; Node* cur = _root; while (cur)//在樹中找到插入的位置 { if (key < cur->_key) { prev = cur; cur = cur->_left; } else if (key > cur->_key) { prev = cur; cur = cur->_right; } } cur = new Node(key, value);//建立新結點,并判斷具體位置進行鏈接 if (prev->_key > cur->_key) { prev->_left = cur; } if (prev->_key < cur->_key) { prev->_right = cur; } } template<class T> void BSTree<T>::Insert_R(const T& key, const T& value)//遞歸算法進行插入 { _insert_r(_root, key, value); } template<class T> void BSTree<T>::_insert_r(Node*& root, const T& key, const T& value)//遞歸 { if (root == NULL)//root為空時,開辟新結點 { root = new Node(key, value); return; } Node* cur = root; if (key < cur->_key) _insert_r(cur->_left, key, value); if (key > cur->_key) _insert_r(cur->_right, key, value); }
● 二叉搜索樹的查找過程如下:
1、若當前的二叉搜索樹為空,則結束函數。
2、若查找的元素值小于根節點值,則在當前結點的左子樹中查找。
3、若查找的元素值大于根節點值,則在當前結點的右子樹中查找。
template<class T> BSTNode<T>* BSTree<T>::Find(const T& key)//非遞歸算法進行查找 { Node* cur = _root; while (cur) { if (key < cur->_key) { cur = cur->_left; } else if (key > cur->_key) { cur = cur->_right; } else { return cur; } } return NULL; } template<class T> BSTNode<T>* BSTree<T>::Find_R(const T& key)//遞歸 { return _find_r(_root, key); } template<class T> BSTNode<T>* BSTree<T>::_find_r(Node*& root, const T& key)//遞歸算法進行查找 { if (root == NULL)//root為空時為沒找到 { return NULL; } if (key < root->_key) return _find_r(root->_left, key); else if (key > root->_key) return _find_r(root->_right, key); else return root; }
● 二叉搜索樹的刪除,分兩種情況進行處理:
1、找到要刪除的結點cur和cur的父親結點prev。
2、情況一:cur只有一個子樹或沒有子樹。首先考慮刪除的結點為根結點時,直接_root指向它的子樹;
再考慮cur的左為空、右為空還是左右都為空,進行刪除,鏈接。
3、情況二:cur左右子樹都不為空。首先找到cur右子樹的最左下結點del,然后進行交換,通過替換法刪除del,并使prev的指向置空。
template<class T> void BSTree<T>::Remove(const T& key)//非遞歸算法進行刪除 { if (_root == NULL) { return; } Node* prev = NULL; Node* cur = _root; while (cur)//找到要刪除的結點cur { if (key < cur->_key) { prev = cur; cur = cur->_left; } else if (key > cur->_key) { prev = cur; cur = cur->_right; } else break; } //情況一:cur只有一個孩子或沒有孩子,注意考慮cur為根結點時,prev=NULL if (cur->_left == NULL || cur->_right == NULL) { if (cur->_left == NULL)//cur只有右孩子 { if (prev == NULL)//cur為根結點時 _root = cur->_right; else if (prev->_left == cur) prev->_left = cur->_right; else prev->_right = cur->_right; } else if (cur->_right == NULL)//cur只有左孩子 { if (prev == NULL)//cur為根結點時 _root = cur->_left; else if (prev->_left == cur) prev->_left = cur->_left; else prev->_right = cur->_left; } //刪除cur并置空,包含了cur的左右為空的情況 delete cur; cur = NULL; } //情況二:cur有左右子樹,替換法刪除 else { //先找到cur結點右子樹的最左下結點del Node* del = cur; prev = del; del = del->_right; while (del->_left) { prev = del; del = del->_left; } //替換法,刪除結點del,注意使prev的指向置空 swap(cur->_key, del->_key); swap(cur->_value, del->_value); if (prev->_left == del) prev->_left = NULL; else if (prev->_right == del) prev->_right = NULL; delete del; del = NULL; } } template<class T> void BSTree<T>::Remove_R(const T& key)//遞歸算法進行刪除 { _remove_r(_root, key); } template<class T> void BSTree<T>::_remove_r(Node*& root, const T& key)//遞歸 { if (_root == NULL) { return; } if (key < root->_key) _remove_r(root->_left, key); else if (key > root->_key) _remove_r(root->_right, key); else { //情況一:只有一個子樹或沒有,直接使root重新賦值 if (root->_left == NULL || root->_right == NULL) { Node* del = root; if (root->_left == NULL) root = root->_right; else if (root->_right == NULL) root = root->_left; else root = NULL; delete del; del = NULL; } else//情況二:左右子樹都不為空 { Node* cur = root->_right;//root右子樹最左下結點,交換兩個結點的值 while (cur->_left) { cur = cur->_left; } swap(root->_key, cur->_key); swap(root->_value, cur->_value); _remove_r(root->_right, key);//在root的右子樹上刪除key,轉換成情況一中左子樹一定為空 } } }
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。