1. 程式人生 > >二叉排序樹 C++

二叉排序樹 C++

二叉查找樹 {} 刪除元素 one dem trees system arc oid

二叉排序樹(Binary Sort Tree),又稱二叉查找樹。

1、若左子樹不為空,則左子樹上所有結點的值均小於他的根結構的值;

2、若右子樹不為空,則右子樹上所有結點的值均大於他的根結構的值;

3、他的左、右子樹也分別為二叉排序樹。

使用中序遍歷時,二叉排序樹的輸出順序是由小到大的有序數列。

二叉排序樹類的: C++ 實現:

#include<iostream>
using namespace std;

template<class T>
struct TreeNode
{
    T element;
    TreeNode<T>*parent, *lnode, *rnode;
    TreeNode(){ parent 
= lnode = rnode = NULL; } TreeNode(const T& key) { element = key; parent = lnode = rnode = NULL; } }; template<class T> class BStree { public: BStree() :root(NULL){} //獲取根結點 TreeNode<T>* Getroot(){ return root; } //中序遍歷 void Inorder(TreeNode<T>*node);
//遞歸查找 TreeNode<T>* TreeSearch(TreeNode<T>*node, T key); //叠代查找 TreeNode<T>* IterativeTreeSearch(TreeNode<T>*node, T key); //插入元素 void TreeInsert(T key); //最大值 TreeNode<T>*TreeMax(TreeNode<T>*node); //最小值 TreeNode<T>*TreeMin(TreeNode<T>*node);
//查找前驅結點 TreeNode<T>*TreePredecessor(T key); //查找後繼結點 TreeNode<T>*TreeSuccessor(T key); //用結點 nodeM 替換結點 nodeN,刪除操作的輔助函數 void TransPlant(TreeNode<T>*nodeM, TreeNode<T>*nodeN); //刪除結點是key的元素 void Delete(T key); private: TreeNode<T>* root; }; //中序遍歷 template<class T> void BStree<T>::Inorder(TreeNode<T>*node) { if (node == NULL) return; else { Inorder(node->lnode); cout << node->element << " "; Inorder(node->rnode); } } //遞歸查找,調用時,node的初始值是root template<class T> TreeNode<T>* BStree<T>::TreeSearch(TreeNode<T>*node, T key) { if ((node == NULL) || (key == node->element)) { if (node == NULL) cout << "不存在該元素" << endl; else cout << "存在該元素" << endl; return node; } if (key > node->element) return TreeSearch(node->rnode,key); else return TreeSearch(node->lnode,key); } //叠代查找,node參數為root(根結點) template<class T> TreeNode<T>* BStree<T>::IterativeTreeSearch(TreeNode<T>*node, T key) { while (node != NULL&&key != node->element) { if (key < node->element) node = node->lnode; else node = node->rnode; } if (node == NULL) cout << "不存在該元素" << endl; else cout << "存在該元素" << endl; return node; } //插入元素 template<class T> void BStree<T>::TreeInsert(T key) { TreeNode<T>* y = NULL; TreeNode<T>* x = root; TreeNode<T>* z = new TreeNode<T>(key); //將需要插入的元素放入新建立的結點中 while (x != NULL) //找到要插入位置的雙親結點 { y = x; if (z->element < x->element) x = x->lnode; else x = x->rnode; } z->parent = y; if (y == NULL) // 判斷要插入的是:左 或 右結點 root = z; else if (z->element>y->element) y->rnode = z; else y->lnode = z; } //最大值,一直遍歷所給結點的右子樹 template<class T> TreeNode<T>*BStree<T>::TreeMax(TreeNode<T>*node) { while (node->rnode != NULL) node = node->rnode; cout << "最大值是:" << node->element << endl; return node; } // 最小值,一直遍歷所給結點的左子樹 template<class T> TreeNode<T>*BStree<T>::TreeMin(TreeNode<T>*node) { while (node->lnode != NULL) node = node->lnode; cout << "最小值是:" << node->element << endl; return node; } //查找後繼結點 template<class T> TreeNode<T>*BStree<T>::TreeSuccessor(T key) { TreeNode<T>* x = TreeSearch(root, key); //查找關鍵字key所對應的結點 if (x->rnode != NULL) //如果結點x存在右結點,則直接查找右結點為跟的最小值 return TreeMin(x->rnode); /*若,不存在右結點 1、if(x==x->parent->lnode), 則 x 的後繼元素即是 x 的雙親結點 2、if(x==x->parent->rnode),則 x 的雙親 y 及 y->lnode均小於x, 直到 x 的某一祖先 Yn 為左節點時,Yn 的雙親即是 x 的後繼元素 */ TreeNode<T>*y = x->parent; while (y != NULL&&x == y->rnode) { x = y; y = y->parent; } return y; } //查找前驅結點 template<class T> TreeNode<T>*BStree<T>::TreePredecessor(T key) { TreeNode<T>* x = TreeSearch(root, key); //查找關鍵字key所對應的結點 if (x->lnode != NULL) return TreeMax(x->lnode); //若x的左子樹不為空,查找左子樹的最大值 TreeNode<T>*y = x->parent; while (y != NULL&&x == y->lnode) { x = y; y = y->lnode; } return y; } //用結點 m 替換結點 n,不包括v的左右子樹的更新 template<class T> void BStree<T>::TransPlant(TreeNode<T>*nodeM, TreeNode<T>*nodeN) { if (nodeN->parent == NULL) root = nodeM; else if (nodeN == nodeN->parent->lnode) // nodeN 是左結點,更新nodeN->parent 的左結點 nodeN->parent->lnode = nodeM; else nodeN->parent->rnode = nodeM; if (nodeM != NULL) nodeM->parent = nodeN->parent; } //刪除結點關節字是key的元素 template<class T> void BStree<T>::Delete(T key) { TreeNode<T>*z = IterativeTreeSearch(root,key); //z 是要刪除的結點 if (z->lnode == NULL) TransPlant(z->rnode,z); else if (z->rnode == NULL) TransPlant(z->lnode,z); else { //找要刪除結點的後繼元素, TreeNode<T>*y = TreeMin(z->rnode); //類的成員函數在調用成員函數(模板)時,直接寫函數名,不需要<T> if (y->parent != z) { TransPlant(y->rnode, y); //用 y 的右結點替代 y y->rnode = z->rnode; //y的右結點 = z的右結點 y->rnode->parent = y; } TransPlant(y,z); //用 y替代z y->lnode = z->lnode; y->lnode->parent = y; } }

測試代碼:註:生成的數組a[20]中,若有重復的數字,會有錯誤。

技術分享
#include<iostream>
#include"stdlib.h"
#include<time.h>
#include"BSTreecpp.cpp"
using namespace std;

int main()
{
    //生成要插入的數據
    int max = 500;
    int min = 0;
    srand((unsigned)time(NULL));
    int a[20] = {};
    int x = 0;
    for (int i = 0; i < 20; i++)
    {
        a[i] = rand() % (max - min) + min;
        cout << a[i] << " ";
    }
    cout << "輸入數據:" << endl;
    BStree<int>myTree;
    for (int i = 0; i < 20; i++)
        myTree.TreeInsert(a[i]);
    myTree.Inorder(myTree.Getroot());
    cout << "二叉搜索樹中序遍歷:" << endl;
    //驗證遞歸查找
    int b = 0;
    TreeNode<int>* A = myTree.TreeSearch(myTree.Getroot(), b);
    //驗證叠代查找
    TreeNode<int>* B = myTree.IterativeTreeSearch(myTree.Getroot(), a[2]);
    //驗證求取最大值
    TreeNode<int>* C = myTree.TreeMax(myTree.Getroot());
    //驗證求取最小值
    TreeNode<int>* D = myTree.TreeMin(myTree.Getroot());
    //求取後繼結點
    TreeNode<int>*E = myTree.TreeSuccessor(a[1]);
    cout << a[1] << " 的後繼元素是:" << E->element << endl;
    //求取前驅結點
    TreeNode<int>*F = myTree.TreePredecessor(a[3]);
    cout << a[3] << " 的前驅元素是:" << F->element << endl;
    //驗證刪除結點
    myTree.Delete(a[0]);
    myTree.Inorder(myTree.Getroot());
    cout << "二叉搜索樹刪除元素後:" << endl;
    system("pause");
    return 0;
}
View Code

二叉排序樹 C++