二叉查找树C++实现

二分查找树特点:

(1) 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;

(2) 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

(3) 任意节点的左、右子树也分别为二叉查找树。

(4) 没有键值相等的节点(no duplicate nodes)。

前序遍历:中左右

中序遍历:左中右

序遍历:左右中

二叉查找树的重点在于如何找节点的前驱节点和后继节点

#pragma once
#include <iostream>
using namespace std;

template <class T>
class BSTNode
{
public:
    T key;
    BSTNode *parent;
    BSTNode *left;
    BSTNode *right;

    BSTNode(T value, BSTNode *p, BSTNode *l, BSTNode *r):key(value),parent(p),left(l),right(r)
    {

    }
};

template <class T>
class BSTree
{
private:
    BSTNode<T> *mRoot;

public:
    BSTree():mRoot(NULL){}
    ~BSTree(){}

    // 前序排序
    void preOrder()
    {
        preOrder(mRoot);
    }
    void inOrder()
    {
        inOrder(mRoot);
    }
    void postOrder()
    {
        postOrder(mRoot);
    }
    // 查找二叉树中键值为key的节点
    BSTNode<T>* SearchKey(const T key)
    {
        return SearchKey(mRoot, key);
    }
    BSTNode<T>* minKey()
    {
        return minKey(mRoot);
    }
    BSTNode<T>* maxKey()
    {
        return maxKey(mRoot);
    }
    // 插入节点
    void insert( T key)
    {
        BSTNode<T> *z = new BSTNode<T>(key, NULL, NULL, NULL);

        if (z == NULL)
        {
            return;
        }
        insert(mRoot, z);
    }

private:
    // 前序排序
    void preOrder(BSTNode<T> *tree) const
    {
        if (tree != NULL)
        {
            cout << tree->key << " ";
            preOrder(tree->left);
            preOrder(tree->right);
        }
    }

    // 中序排序
    void inOrder(BSTNode<T> *tree) const
    {
        if (tree != NULL)
        {
            preOrder(tree->left);
            cout << tree->key << " ";
            preOrder(tree->right);
        }
    }

    // 后序排序
    void postOrder(BSTNode<T> *tree) const
    {
        if (tree != NULL)
        {
            preOrder(tree->left);
            preOrder(tree->right);
            cout << tree->key << " ";
        }
    }
    BSTNode<T>* SearchKey(BSTNode<T>* pNode, const T key) const
    {
        // 递归查找
        /*if (pNode = NULL || key == pNode->key)
        {
            return pNode;
        }
        else if (key > pNode->key)
        {
            return SearchKey(pNode->right);
        }
        else
        {
            return SearchKey(pNode->left);
        }*/

        // 非递归查找
        BSTNode<T>* x = pNode;
        while (x != NULL)
        {
            if (key > x->key)
            {
                x = x->right;
            }
            else if (key < x->key)
            {
                x = x->left;
            }
            else
            {
                return x;
            }
        }

        return NULL;
    }
    // 将节点插入到二叉树中
    void insert(BSTNode<T>* &tree, BSTNode<T> *Node)
    {
        BSTNode<T> *y = NULL;
        BSTNode<T> *x = tree;
        while (NULL != x)
        {
            y = x;
            if (Node->key > x->key)
            {
                x = x->right;
            }
            else
            {
                x = x->left;
            }
        }

        Node->parent = y;       // 这到后面两句为关键代码
        if (NULL == y)
        {
            tree = Node;
        }
        else if (Node->key > y->key)
        {
            y->right = Node;
        }
        else
        {
            y->left = Node;
        }
    }
    // 查找最小节点
    BSTNode<T>* minKey(BSTNode<T>* pNode) const
    {
        while (pNode != NULL)
        {
            pNode = pNode->left;
        }

        return pNode;
    }
    BSTNode<T>* maxKey(BSTNode<T>* pNode) const
    {
        while (pNode != NULL)
        {
            pNode = pNode->right;
        }

        return pNode;
    }
    // 找节点(x)的后继节点。即查找二叉树中数值大于该节点的最小值
    BSTNode<T>* Successor(BSTNode<T>* x)
    {
        // 分三种情况
        // 1. x有右孩子,找到以右孩子为根的子树的最小节点
        // 2. x没有右孩子,当x为左孩子,则x的父节点为后继节点
        // 2. x没有右孩子,当x为右孩子,则找x的最低父节点,并且该父节点具有左孩子
        if (x->right != NULL)
        {
            return minKey(x->right);
        }
        BSTNode<T>* y = x->parent;
        while ((NULL != y) &&(x == y->right))
        {
            x= y;
            y = y->parent;
        }

        return y;
    }
    // 找结点(x)的前驱结点。即查找"二叉树中数据值小于该结点"的"最大结点"
    BSTNode<T>* BSTree<T>::predecessor(BSTNode<T> *x)
    {
        // 如果x存在左孩子,则"x的前驱结点"为 "以其左孩子为根的子树的最大结点"。
        if (x->left != NULL)
            return maxKey(x->left);

        // 如果x没有左孩子。则x有以下两种可能:
        // (01) x是"一个右孩子",则"x的前驱结点"为 "它的父结点"。
        // (01) x是"一个左孩子",则查找"x的最低的父结点,并且该父结点要具有右孩子",找到的这个"最低的父结点"就是"x的前驱结点"。
        BSTNode<T>* y = x->parent;
        while ((y!=NULL) && (x==y->left))
        {
            x = y;
            y = y->parent;
        }

        return y;
    }

    // 删除二叉树中的节点,并返回被删除的节点
    //BSTNode<T>* RemoveNode(BSTNode<T>* &tree, BSTNode<T>* pNode)
    //{
    //    BSTNode<T>* x = tree;

    //    while (NULL != x && pNode->key != x->key)
    //    {
    //        if (pNode->key > x->key)
    //        {
    //            x = x->right;
    //        }
    //        else if (pNode->key < x->key)
    //        {
    //            x = x->left;
    //        }
    //    }

    //    // 找到或x为空

    //}
};

时间: 2024-10-13 02:08:43

二叉查找树C++实现的相关文章

C语言实现二叉查找树

#include<stdio.h> #include<stdlib.h> /* * 数据结构:二叉查找树,即左孩子<父节点<右孩子 * C语言实现 * 2015-9-13 */ typedef struct TreeNode *PtrToNode; typedef PtrToNode Tree; typedef PtrToNode Position; struct TreeNode { int Element; Tree Left; //节点左孩子 Tree Right

按层遍历二叉查找树

<算法>中二叉查找树一节的习题:按层遍历二叉查找树. 可以使用队列来管理二叉查找树中的节点,节点按照如下方法入队出队: 节点x入队 当队列不为空时使用队列的第一个元素first 如果节点first.left不为空则将fisrt.left入队 如果节点first.right不为空则将first.right入队 将first节点出队 /** * Created by elvalad on 2014/12/5. * 按层遍历二叉查找树 */ import java.util.Iterator; im

二叉查找树BST 模板

二叉查找树BST 就是二叉搜索树 二叉排序树. 就是满足 左儿子<父节点<右儿子 的一颗树,插入和查询复杂度最好情况都是logN的,写起来很简单. 根据BST的性质可以很好的解决这些东西 1.查询值 int Search(int k,int x) { if(x<a[k].key && a[k].l) Search(a[k].l,x); else if(x>a[k].key && a[k].r) Search(a[k].r,x); else retur

二叉查找树

二叉查找(搜索)树(Binary Search Tree)又称二叉排序树(Binary Sort Tree),是基于二叉树,BST具有下列性质:1.若左子树不空,则其左子树上的所有结点的值均小于根结点的值:2.若右子树不空,则其右子树上的所有结点的值均大于根结点的值:3.左.右子树也分别为二叉查找树. 结点类 public class BinaryNode {      Integer data;      BinaryNode leftChild;      BinaryNode rightC

平衡树初阶——AVL平衡二叉查找树+三大平衡树(Treap + Splay + SBT)模板【超详解】

平衡树初阶——AVL平衡二叉查找树 一.什么是二叉树 1. 什么是树. 计算机科学里面的树本质是一个树状图.树首先是一个有向无环图,由根节点指向子结点.但是不严格的说,我们也研究无向树.所谓无向树就是将有向树的所有边看成无向边形成的树状图.树是一种递归的数据结构,所以我们研究树也是按照递归的方式去研究的. 2.什么是二叉树. 我们给出二叉树的递归定义如下: (1)空树是一个二叉树. (2)单个节点是一个二叉树. (3)如果一棵树中,以它的左右子节点为根形成的子树都是二叉树,那么这棵树本身也是二叉

java 二叉查找树

//接口+抽象类+实现类package wangChaoPA实习工作练习.com.进阶篇.二叉查找树; import java.util.Iterator;public interface Tree<E extends Comparable<E>>{    // 从树中删除e    boolean delete(E e); // 树的大小    int getSize(); // 中序遍历树    void inorder(); // 把e插入到tree中    boolean i

[二叉查找树] 二叉排序树

题目描述 输入一系列整数,建立二叉排序数,并进行前序,中序,后序遍历. 输入 输入第一行包括一个整数n(1<=n<=100).接下来的一行包括n个整数. 输出 可能有多组测试数据,对于每组数据,将题目所给数据建立一个二叉排序树,并对二叉排序树进行前序.中序和后序遍历.每种遍历结果输出一行.每行最后一个数据之后有一个空格. 样例输入 1 2 2 8 15 4 21 10 5 39 样例输出 2 2 2 8 15 8 15 15 8 21 10 5 39 5 10 21 39 5 10 39 21

图解数据结构(7)——二叉查找树及平衡二叉查找树(一共14篇)

这篇将是最有难度和挑战性的一篇,做好心理准备!十.二叉查找树(BST)前一篇介绍了树,却未介绍树有什么用.但就算我不说,你也能想得到,看我们Windows的目录结构,其实就是树形的,一个典型的分类应用.当然除了分类,树还有别的作用,我们可以利用树建立一个非常便于查找取值又非常便于插入删除的数据结构,这就是马上要提到的二叉查找树(Binary Search Tree),这种二叉树有个特点:对任意节点而言,左子(当然了,存在的话)的值总是小于本身,而右子(存在的话)的值总是大于本身. 这种特性使得我

二叉查找树 _ 二叉排序树 _ 二叉搜索树_C++

一.数据结构背景+代码变量介绍 二叉查找树,又名二叉排序树,亦名二叉搜索树 它满足以下定义: 1.任意节点的子树又是一颗二叉查找树,且左子树的每个节点均小于该节点,右子树的每个节点均大于该节点. 2.由1可推出,任意节点的左孩子小于该节点,右孩子大于该节点 以上讨论的是左(右)孩子(子树)存在的情况 它的中序遍历是一个升序的排序 在参考代码中,我们定义有: 主程序中,k代表插入或删除或查找的节点的值 root,根节点位置:a[i],第 i 号节点的值:cl[i],第 i 号节点左孩子的位置:cr