二叉排序树binary_sort_tree

当你希望获取快速的查找时间,快速的插入删除时间,并且遍历是有序的 数据结构, 你需要的就是二叉排序树了。

AVL二叉平衡树,红黑树都是binary sort tree,  这就是STL中的map为什么(中序)遍历,key是有序输出的原因!

注意: 二叉排序树,平均插入,查找O(logn), 但如果不平衡,极端情况,查找为O(n), 一棵斜树。 所以,利用平衡可以提高效率。


为了简化,仅列出一般的binary sort tree 的常用函数编码, 暂时不考虑平衡因素。主要包括:: 构建,查找,插入,删除


代码实现:C++语言: 贴彩色代码可用:http://fayaa.com/code/new/

BinarySortTree.h:

/*
简化操作, 不考虑data相等情况,即所有左子树均小于根节点,所有右子树均大于跟节点
*/

#include <iostream>

typedef struct BinaryTreeNode
{
     int data;
    BinaryTreeNode * lchild;
    BinaryTreeNode * rchild;
} BinaryTreeNode, *BinaryTree;

class BinarySortTree
{
public:
    BinarySortTree();
    ~BinarySortTree( void);

     void InsertNode( int data);
     void DeleteNode( int data);
     void BuildBinarySortTree( int * data_array,  int size);
     bool Find( int data);
     // 中序遍历打印
     void PrintTree( void);

private:
     void InsertNode(BinaryTree & root,  int data);
     void DeleteNode(BinaryTree & node);
     void DeleteNode(BinaryTree & root,  int data);
     bool Find(BinaryTree root,  int data);
     void PrintTree(BinaryTree root);
     void ClearTree(BinaryTree root);
    BinaryTree root_;
};

BinarySortTree.cpp:

C++语言高亮代码由发芽网提供

#include "BinarySortTree.h"

using namespace std;

BinarySortTree::BinarySortTree(): root_(NULL)
{
}

BinarySortTree::~BinarySortTree( void)
{
    ClearTree(root_);
}

void BinarySortTree::BuildBinarySortTree( int * data_array,  int size)
{
     for ( int i= 0; i<size; ++i)
    {
         int data = data_array[i];
        InsertNode(root_, data);
    }
}

void BinarySortTree::InsertNode( int data)
{
    InsertNode(root_, data);
}

// 必须传引用,否则不能链接新节点。
void BinarySortTree::InsertNode(BinaryTree & root,  int data)
{
    BinaryTreeNode * key = root;
    BinaryTreeNode * parent = key;
     // 递归可以很容易实现,非递归效率更高
     while (key != NULL)
    {
        parent = key;
         if (data < key->data)
        {
            key = key->lchild;
        }
         else if (data > key->data)
        {
            key = key->rchild;
        }
         else
        {  // 已有data,不再插入
             return;
        }
    }
     // key == NULL, 创建节点
    key =  new BinaryTreeNode();
    key->data = data;
    key->lchild = NULL;
    key->rchild = NULL;
     // 将新创建的节点,连入树中
     if (parent != NULL)
    {
         if (data < parent->data)
        {
            parent->lchild = key;
        }
         else if (data > parent->data)
        {
            parent->rchild = key;
        }
    } 
     else
    {
         // 传引用的原因!!
        root = key;
    }
}

void BinarySortTree::DeleteNode( int data)
{
    DeleteNode(root_, data);
}

void BinarySortTree::DeleteNode(BinaryTree & root,  int data)
{
     if (root == NULL)
    {
        cout <<  "Delete operation CANNOT find "<< data <<  " in this binary sort tree" << endl;
         return;
    }
     if (data < root->data)
    {
        DeleteNode(root->lchild, data);
    }
     else if (data > root->data)
    {
        DeleteNode(root->rchild, data);
    }
     else  // find data
    {
        DeleteNode(root);
    }
}

void BinarySortTree::DeleteNode(BinaryTree & node)
{
     if (node == NULL)
    { // shoulde come here
        cout << "SHOULD NOT deleting a null Node!! " << endl;
         return;
    }
    BinaryTreeNode * delete_node = node;
     if (node->rchild == NULL)
    { // 如果只有左子树,直接删除节点,并将左子树挂接到父节点
        node = node->lchild;
         delete delete_node;
    }
     else if (node->lchild == NULL)
    { // 如果只有右子树,直接删除节点,并将右子树挂接到父节点
        node = node->rchild;
         delete delete_node;
    }
     else
    { // 如果左右子树均存在,找直接前驱,替换节点
        BinaryTreeNode * delete_node_parent = node;
        delete_node = node->lchild;
         while (delete_node->rchild != NULL)
        {
            delete_node_parent = delete_node;
            delete_node = delete_node->rchild;
        }
        node->data = delete_node->data; // 完成节点交换
        // 重新建立节点的链接

         if (delete_node_parent->rchild == delete_node)
        {
            delete_node_parent->rchild = delete_node->lchild;
        }
         else 
        {
            delete_node_parent->lchild = delete_node->lchild;
        }
         delete delete_node;
    }
}

bool BinarySortTree::Find( int data)
{
     return Find(root_, data);
}

bool BinarySortTree::Find(BinaryTree root,  int data)
{
     if (root == NULL)
    {
         return false;
    }
     if (data == root->data)
    {
         return true;
    }
     else if (data < root->data)
    {
        Find(root->lchild, data);
    }
     else if (data > root->data)
    {
        Find(root->rchild, data);
    }
}

void BinarySortTree::PrintTree( void)
{
    PrintTree(root_);
    cout << endl;
}

void BinarySortTree::PrintTree(BinaryTree root)
{
     if (root_ == NULL)
    {
        cout<< "This is an empty tree!" << endl;
         return;
    }
     if (root == NULL)
    {
         return;
    }
    BinaryTreeNode * p_node = root;
     // 递归实现中序遍历, 也可以借用栈非递归实现
    PrintTree(p_node->lchild);
    cout << p_node->data <<  " \t ";
    PrintTree(p_node->rchild);
}

void BinarySortTree::ClearTree(BinaryTree root)
{
     if (root == NULL)
    {
         return;
    }
     if (root->lchild != NULL)
    {
        ClearTree(root->lchild);
    }
     if (root->rchild != NULL)
    {
        ClearTree(root->rchild);
    }
     // 删除节点
     delete root;
}

main.cpp  测试代码:

#include <iostream>
#include "BinarySortTree.h"

int main( int argc,  const char ** argv)
{
     int test_array[] = { 62885847357351993793};
     int arr_size =  sizeof(test_array)/ sizeof( int);
    BinarySortTree tree;
    tree.BuildBinarySortTree(test_array, arr_size);
    tree.PrintTree();
     if (tree.Find( 35))
    {
        tree.DeleteNode( 35);
    }
     if (tree.Find( 62))
    {
        tree.DeleteNode( 62);
    }
     if (tree.Find( 87))
    {
        tree.DeleteNode( 87);
    }
     if (tree.Find( 35))
    {
        tree.DeleteNode( 37);
    }
    tree.PrintTree();
    tree.DeleteNode( 189);

     return  0;
}

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值