搜索二叉树

来源:互联网 发布:vs2017 golang 编辑:程序博客网 时间:2024/04/29 02:25

搜索二叉树的性质

    1. 每个节点都有一个作为搜索依据的关键码(key),所有节点的关       键码互不相同。    2. 左子树上所有节点的关键码(key)都小于根节点的关键码(key)。    3. 右子树上所有节点的关键码(key)都大于根节点的关键码(key)。    4. 左右子树都是二叉搜索树。

例如:
这里写图片描述
第二棵树中,左边的8比根节点5大,右边的4比根节点5小.不满足搜索二叉树的性质。


搜索二叉树的插入

在插入一个数后,依然满足搜索二叉树。

插入分为:
1、为空树,就直接插入。
2、从根节点依次比较,比根节点小,往左树找,比根节点大,往右树找。找到后进行插入。
3、有了这个数就直接返回,不进行插入。
非递归:

bool Insert(const K& key)//非递归插入    {        if (_root == NULL)//为空树,直接插入        {            _root = new Node(key);            return true;        }        Node* cur = _root;        Node* parent = NULL;        while (cur)        {            parent = cur;            if (key > cur->_key)//左树进行找            {                cur = cur->_right;            }            else if (key < cur->_key)//右树进行找            {                cur = cur->_left;            }            else//没找到直接返回            {                return false;            }        }        if (key < parent->_key)        {            parent->_left = new Node(key);        }        else        {            parent->_right = new Node(key);        }        return true;    }

递归:

bool _InsertR(Node*& cur, size_t key)//递归插入    {        if (cur == NULL)        {            cur = new Node(key);            return true;        }        if (key < cur->_key)        {            _InsertR(cur->_left,key);        }        else if(key > cur->_key)        {            _InsertR(cur->_right,key);        }        else        {            return false;        }    }

搜索二叉树的查找

查找分为:
1、空树,直接返回false。
2、与根节点比较,比根节点小,左子树找,比根节点大,右子树找。找到后返回true。
3、没找到,返回false。
非递归:

bool Find(const K& key)//非递归插入    {        if (_root == NULL)//空树            return false;        Node* cur = _root;        while (cur)        {            if (key < cur->_key)//左树找            {                cur = cur->_left;            }            else if (key > cur->_key)//右树找            {                cur = cur->_right;            }            else//找到            {                return true;            }        }        return false;    }

递归:

bool _FindR(Node*& cur, size_t key)//递归查找    {        if (cur == NULL)            return false;        if (key < cur->_key)        {            _FindR(cur->_left, key);        }        else if (key > cur->_key)        {            _FindR(cur->_right, key);        }        else        {            return true;        }        return false;    }

搜索二叉树的删除

在删除一个数后,依然满足搜索二叉树。

删除分为:
1、空树,直接返回。
2、先找这个数,找不到返回。
3、找到后,左子树为空。
4、找到后,右子树为空。
5、找到后,左右都不为空。
大致情况为:

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

非递归:

bool Remove(const K& key)    {        if (_root == NULL)//空树,删除不了 ,返回false            return false;        Node* cur = _root;        Node* parent = NULL;        Node* del = NULL;        while (cur)        {            if (key < cur->_key)//找的数比根节点小,在左子树上继续找            {                parent = cur;                cur = cur->_left;            }            else if (key > cur->_key)//找的数比根节点大,在右子树上继续找            {                parent = cur;                cur = cur->_right;            }            else//找到了            {                if (cur->_left == NULL)//找到的节点的左为空                {                    if (parent == NULL)                        _root = cur->_right;                    else                    {                        if (cur == parent->_right)                            parent->_right = cur->_right;                        else                            parent->_left = cur->_right;                    }                    del = cur;                }                else if (cur->_right == NULL)//找到的节点右为空(包括左右都为空的)                {                    if (parent == NULL)                        _root = cur->_left;                    else                    {                        if (cur == parent->_left)                            parent->_left = cur->_left;                        else                            parent->_right = cur->_left;                    }                    del = cur;                }                else//找到的节点左右都不为空,用替换法删除(左子树的最右节点,右子树的最左节点)                {                    Node* subNode = cur->_left;                    Node* tmp = cur;                    while (subNode->_right)                    {                        tmp = subNode;                        subNode = subNode->_right;                    }                    swap(subNode->_key, cur->_key);                    if (subNode == tmp->_left)                        tmp->_left = subNode->_right;                    else                        tmp->_right = subNode->_right;                    del = subNode;                }                delete del;                del = NULL;                return true;            }        }        return false;    }

递归:

bool _RemoveR(Node*& cur,size_t key)    {        if (cur == NULL)        {            return false;        }        if (key < cur->_key)        {            _RemoveR(cur->_left, key);        }        else if (key > cur->_key)        {            _RemoveR(cur->_right, key);        }        else        {            Node* del = cur;            if (cur->_left == NULL)            {                cur = cur->_left;            }            else if (cur->_right == NULL)            {                cur = cur->_right;            }            else            {                Node* parent = cur;                Node* subNode = cur->_left;                while (subNode->_right)                {                    parent = subNode;                    subNode = subNode->_right;                }                swap(subNode->_key, cur->_key);                if (parent->_right = subNode)                    parent->_right = subNode->_right;                else                    parent->_left = subNode->_right;                del = subNode;            }            delete del;            del = NULL;            return true;        }        return false;    }

代码实现:

"SearchBinaryTree.h"#pragma oncetemplate <class K>struct SearchBinaryTreeNode{    K _key;    SearchBinaryTreeNode<K>* _left;    SearchBinaryTreeNode<K>* _right;    SearchBinaryTreeNode(const K& key)        :_key(key)        , _left(NULL)        , _right(NULL)    {}};template <class K>class SearchBinaryTree{    typedef SearchBinaryTreeNode<K> Node;public:    SearchBinaryTree()//无参构造        :_root(NULL)    {}    SearchBinaryTree(K* a, size_t n)//构造函数    {        _root = NULL;        for (size_t i = 0; i < n; ++i)        {            InsertR(a[i]);        }    }    ~SearchBinaryTree()    {        _Destory(_root);    }    bool Insert(const K& key)//非递归插入    {        if (_root == NULL)        {            _root = new Node(key);            return true;        }        Node* cur = _root;        Node* parent = NULL;        while (cur)        {            parent = cur;            if (key > cur->_key)            {                cur = cur->_right;            }            else if (key < cur->_key)            {                cur = cur->_left;            }            else            {                return false;            }        }        if (key < parent->_key)        {            parent->_left = new Node(key);        }        else        {            parent->_right = new Node(key);        }        return true;    }    bool InsertR(const K& key)    {        return _InsertR(_root, key);    }    bool Remove(const K& key)    {        if (_root == NULL)//空树,删除不了 ,返回false            return false;        Node* cur = _root;        Node* parent = NULL;        Node* del = NULL;        while (cur)        {            if (key < cur->_key)//找的数比根节点小,在左子树上继续找            {                parent = cur;                cur = cur->_left;            }            else if (key > cur->_key)//找的数比根节点大,在右子树上继续找            {                parent = cur;                cur = cur->_right;            }            else//找到了            {                if (cur->_left == NULL)//找到的节点的左为空                {                    if (parent == NULL)                        _root = cur->_right;                    else                    {                        if (cur == parent->_right)                            parent->_right = cur->_right;                        else                            parent->_left = cur->_right;                    }                    del = cur;                }                else if (cur->_right == NULL)//找到的节点右为空(包括左右都为空的)                {                    if (parent == NULL)                        _root = cur->_left;                    else                    {                        if (cur == parent->_left)                            parent->_left = cur->_left;                        else                            parent->_right = cur->_left;                    }                    del = cur;                }                else//找到的节点左右都不为空,用替换法删除(左子树的最右节点,右子树的最左节点)                {                    Node* subNode = cur->_left;                    Node* tmp = cur;                    while (subNode->_right)                    {                        tmp = subNode;                        subNode = subNode->_right;                    }                    swap(subNode->_key, cur->_key);                    if (subNode == tmp->_left)                        tmp->_left = subNode->_right;                    else                        tmp->_right = subNode->_right;                    del = subNode;                }                delete del;                del = NULL;                return true;            }        }        return false;    }    bool RemoveR(const K& key)    {        return _RemoveR(_root, key);    }    bool Find(const K& key)    {        if (_root == NULL)            return false;        Node* cur = _root;        while (cur)        {            if (key < cur->_key)            {                cur = cur->_left;            }            else if (key > cur->_key)            {                cur = cur->_right;            }            else            {                return true;            }        }        return false;    }    bool FindR(const K& key)    {        return _FindR(_root, key);    }    void InOrder()    {        _InOrder(_root);        cout << endl;    }protected:    bool _FindR(Node*& cur, size_t key)    {        if (cur == NULL)            return false;        if (key < cur->_key)        {            _FindR(cur->_left, key);        }        else if (key > cur->_key)        {            _FindR(cur->_right, key);        }        else        {            return true;        }        return false;    }    bool _RemoveR(Node*& cur,size_t key)    {        if (cur == NULL)        {            return false;        }        if (key < cur->_key)        {            _RemoveR(cur->_left, key);        }        else if (key > cur->_key)        {            _RemoveR(cur->_right, key);        }        else        {            Node* del = cur;            if (cur->_left == NULL)            {                cur = cur->_left;            }            else if (cur->_right == NULL)            {                cur = cur->_right;            }            else            {                Node* parent = cur;                Node* subNode = cur->_left;                while (subNode->_right)                {                    parent = subNode;                    subNode = subNode->_right;                }                swap(subNode->_key, cur->_key);                if (parent->_right = subNode)                    parent->_right = subNode->_right;                else                    parent->_left = subNode->_right;                del = subNode;            }            delete del;            del = NULL;            return true;        }        return false;    }    bool _InsertR(Node*& cur, size_t key)    {        if (cur == NULL)        {            cur = new Node(key);            return true;        }        if (key < cur->_key)        {            _InsertR(cur->_left,key);        }        else if(key > cur->_key)        {            _InsertR(cur->_right,key);        }        else        {            return false;        }    }    void _Destory(Node* cur)    {        if (cur == NULL)            return;        _Destory(cur->_left);        _Destory(cur->_right);        delete cur;        cur = NULL;    }    void _InOrder(Node*& cur)    {        if (cur == NULL)            return;        _InOrder(cur->_left);        cout << cur->_key << " ";        _InOrder(cur->_right);    }protected:    Node* _root;};void TestSearchBinaryTree(){    int a[] = { 5, 1, 2, 8, 3, 9, 4, 6, 7, 0 };    SearchBinaryTree<int> t(a,sizeof(a)/sizeof(a[0]));}"Test.cpp"#include <iostream>using namespace std;#include "SearchBinaryTree.h"int main(){    TestSearchBinaryTree();    return 0;}
1 0
原创粉丝点击