普通二叉排序树

来源:互联网 发布:网络平台计划书 编辑:程序博客网 时间:2024/05/17 03:54

1.二叉查找树(BST,Binary Search Tree)
注意和堆排序中的堆区分开。
参考我的博客,常见内排序算法中的堆排序。
定义:1)如果左子树不空,那么左子树的所有节点均小于根节点
         2)如果右子树不空,那么右子树的所有节点均大于根节点
         3)左右子树也都是BST


1.1二叉查找树的查找
如何在二叉查找树上查找某个为key的节点?
首先比较key和根节点,如果其大小等于根节点,退出;
如果小于根节点,递归搜索左子树;
如果大于根节点,递归搜索右子树。

 

1.2如何在二叉查找树中插入一个节点
1)如果树上已经有关键字相等的节点,不插入
2)否则,要插入的节点,必定是叶子节点,利用1.1中的查找算法,查找不成功的最后一
个节点必然是要插入节点的父亲节点。然后判定要插入节点是该父亲节点的左孩子还是右孩子。

 

1.3如何在二叉查找树上删除一个节点
1)找到该节点d
2)删除该节点d并修改相应指针。
   我看严蔚敏老师那本树上搞的甚是复杂,我老婆比较厉害,帮我总结了个简单的,先看性质,再看图说话。
   性质:对于二叉排序树上的任意一个节点,如果它有子树,则有如下性质, 其左子树的最右侧子树的值是小于它的最大值,

   其右子树的最左侧子树的值是大于它的最小值,这个小于它的最大值和大于它的最小值都可以替代删除节点做根。我取左子树的最右侧

   子树。
   删除节点d,共有四种情况:

   1)d的左右子树均NULL,删除d,把d父亲节点的相应指针置NULL。

        提醒:注意图片2中的特殊情况,d没有父亲,删除d后,整个树为NULL。

 

 

 

                                  

                       图片1                                                                         图片2

 


   2)d的左子树不空,右子树NULL,删除d,把d的左子树链接到d的父亲节点。

        提醒:图片4中的特殊情况,d无父亲节点,删除d后,整个树的根需要变动,否则我们将失去树根。

        

                             

           图片3                                                                                图片4

 


   3)d的左子树NULL,右子树不空,删除d,把d的右子树链接到d的父亲节点

        提醒:图片6中的特殊情况,d无父亲节点,删除d后,整个树根要变动,否则我们将永远失去树根。

                            

                    图片5                                                                    图片6

 


   4)d有左子树和右子树,d转左子树,然后向右直到最右r,修改d的关键字为r的关键字,删除r,将r的左子树链接到r的父亲(r不可能有

        右子树

        

                                                             图片7       

 

 

1.4二叉查找树的宽度优先遍历
写这个功能,主要是为了测试上面1.1,1.2,1.3几个功能的实现是否正确,可以自己造几个
数据插入,然后调用我写的宽度优先遍历打印出来和自己手工画的做比较。
用了STL中的list做队列,没有自己写队列。

 

1.5二叉查找树的中序遍历
中序遍历的结果是一个有序序列,这也可以作为一种排序方法。

完整代码(没有实现遍历并删除所有节点,道理都一样,懒得写了,你可自己写):

#include <iostream>#include <list>using namespace std;struct BstTreeNode{    int key;    struct BstTreeNode *left;    struct BstTreeNode *right;};struct BstTreeNode *parent = NULL;struct BstTreeNode *search_result = NULL;//BST search bool bst_search(struct BstTreeNode *root, int key) {    if(root == NULL) {         return false;    }    if(key == root->key) {        search_result = root;        return true;    }    if(key < root->key) {        parent = root;        return bst_search(root->left, key);    }    if(key > root->key) {        parent = root;        return bst_search(root->right, key);    }}//BST addbool bst_add(struct BstTreeNode *root, int key) {    parent = NULL;    search_result = NULL;    if(bst_search(root, key)) {        return false; //already have this node    }    else if(parent != NULL){        struct BstTreeNode *node = new BstTreeNode;        node->key = key;        node->left = NULL;        node->right = NULL;        if(key < parent->key)            parent->left = node;        else            parent->right = node;                return true;    }    return false;}//BST Delete//Use C++ reference to record the root of the tree//bool bst_delete(struct BstTreeNode * &root, int key) {    parent = NULL;    search_result = NULL;    if(!bst_search(root, key)) {        return false; //have nod this node    }    if(search_result->left == NULL && search_result->right == NULL) {        if(parent != NULL) {            if(search_result == parent->left)                parent->left = NULL;            else if(search_result == parent->right)                parent->right = NULL;        }        else {            root = NULL;        }        delete search_result;    }    else if(search_result->left != NULL && search_result->right == NULL) {        if(parent != NULL) {            if(search_result == parent->left)                parent->left = search_result->left;            else if(search_result == parent->right)                parent->right = search_result->left;        }        else {            root = search_result->left;        }        delete search_result;    }    else if(search_result->left == NULL && search_result->right != NULL) {        if(parent != NULL) {            if(search_result == parent->left)                parent->left = search_result->right;            else if(search_result == parent->right)                parent->right = search_result->right;        }        else {            root = search_result->right;        }        delete search_result;    }    else {        struct BstTreeNode *replace = search_result->left;        struct BstTreeNode *replace_parent= replace;        while(replace->right) {            replace_parent = replace;            replace = replace->right;        }        search_result->key = replace->key;        if(replace == replace_parent->left)            replace_parent->left = replace->left;        else if(replace == replace_parent->right)            replace_parent->right = replace->left;        delete replace;    }    return true;} //BST traverse, width first search//Use STL list as a list structure for ease, I do not implement a list //Of course, you can implement a list yourself//void bst_traverse_wfs(struct BstTreeNode *root) {    list<BstTreeNode *> my_list;    if(root != NULL) {        my_list.push_back(root);    }    else {        return;    }    while(!my_list.empty()) {        struct BstTreeNode *tmp = my_list.front();        if(tmp->left)            my_list.push_back(tmp->left);        if(tmp->right)            my_list.push_back(tmp->right);        cout<<tmp->key<<" ";        my_list.pop_front();    }    cout<<endl;} //BST traverse, depth first search, inorder//Inorder recursive implementvoid bst_traverse_dfs_inorder(struct BstTreeNode *root) {    if(root == NULL)        return;    bst_traverse_dfs_inorder(root->left);    cout<<root->key<<" ";    bst_traverse_dfs_inorder(root->right);}int main() {    /*                  7     *            3           9     *         2     5         10     *        1     4 6            *             */    struct BstTreeNode *root = new BstTreeNode;    root->key = 7;    root->left = NULL;    root->right = NULL;    //construct & print    bst_add(root,3);    bst_add(root,9);    bst_add(root,2);    bst_add(root,5);    bst_add(root,10);    bst_add(root,1);    bst_add(root,4);    bst_add(root,6);    bst_traverse_wfs(root);    bst_traverse_dfs_inorder(root);    cout<<endl;    cout<<"************************"<<endl;    //delete & print    bst_delete(root, 7);    bst_traverse_wfs(root);    bst_traverse_dfs_inorder(root);    cout<<endl;    cout<<"************************"<<endl;    return 0;}




原创粉丝点击