二叉树 二叉搜索树 索引二叉搜树 二叉平衡树 c++ 模板继承 代码

二叉树 二叉搜索树 索引二叉搜树 二叉平衡树 c++ 模板继承 代码_第1张图片


不积跬步,无以至千里



反思

  1. 如何处理异常?
  2. 节点类型要不要继承?
  3. 做好单个函数功能的测试,越早越好。
  4. 如何找到边界值和负例?
  5. 一个函数不要做多余事,办好一件事就够了。
  6. 具体细节
讨论:二叉搜索树的删除

思路:用当前值的前驱代替自己,之后删除前驱

  1. 如果前驱不存在呢?

    • 法一,找后继代替自己,然后删除后继【本文方案】

      • 如何删除后继?利用后继没有左孩子的特性,找后继的父亲和右儿子相连
    • 法二,没有前驱,说明没有左孩子,直接删除当前节点,再让父亲左(右需要判断)指针和右孩子连接

      • 可以递归么?不断找前驱的前驱,直到没有前驱。但是会移动很多节点。
  2. 具体代码细节
T getMax(BPtr root, bool del = false, BPtr father = nullptr);//声明默认是不用删除,父指针在删除成立时有效

template
inline int BSTree::remove(const T target)
{
    BPtr ptr = nullptr;
    BPtr fptr = nullptr;
    bool isleft = false;

    if (find(this->m_root,target, ptr, fptr) != FAIL) {

        isleft = (fptr->rChild->val != target);

        if (isLeaf(ptr)) {//叶子直接删除
            delete ptr;
            if (isleft) {
                fptr->lChild = nullptr;
            }
            else {
                fptr->rChild = nullptr;
            }
            return OK;
        }

        if (ptr->lChild == nullptr) {
            ptr->val = getMin(ptr->rChild, true, ptr);
            //以当前节点ptr右孩子的最小值(后继)代替自己,同时删除后继
        }
        else {
            ptr->val = getMax(ptr->lChild, true, ptr);
        }
    }

    return OK;
}

template
inline T BSTree::getMin(BPtr root, bool del,BPtr father)
{
    //非法输入
    if (!root) return FAIL;

    //开始,root是father的右孩子,即在右子树找最小值
    bool isRight = true;
    BPtr p = root;

    while (p->lChild != nullptr) {
        father = p;
        p = p->lChild;
        isRight = false;//现在成了左孩子
    }

    T ans = p->val;
    if (del) {
        if (isRight) {
            father->rChild = p->rChild;
        }
        else {
            father->lChild = p->rChild;
        }
        free(p);
        p = nullptr;
    }
    return ans;
}


/*  可不可以把getMin()和delNext()分离出来呢?
*   如getmin()单纯返回now_ptr右子树的最小值next
*   可以用find(next,ptr,fptr)找到next父亲【相当于找了一趟next,但是函数分工明确,getMin不用干多余的活儿】
*   然后,判断isRight【next是他父亲的哪个孩子】
*   最后,连接他父亲和next的右孩子【后继没左孩子,有的话他就不会是左孩子了】
*/
讨论:平衡二叉搜索树的删除

思路:递归

* 如果是叶子直接删除,调整平衡
* 如果只有一个孩子,先连接父亲和孩子,再删除,最后调整平衡
* 如果两个孩子都有,找从左子树找前驱覆盖当前值
    * 如果恰好是左孩子,先连接当前值和左孩子的右儿子
      然后删除,这时一定平衡想想为什么?
    * 否则,从左子树里递归删除前驱

还有更好的结构吗?

讨论:平衡二叉搜索树的调整平衡
  1. 保存头上部分【当前节点的父亲】,和当前的高度oldH
  2. 向上找第一个不平衡的结点ptr
  3. 判断ptr的不平衡类型并旋转
  4. 连接头部【调整后,下半部分的根结点有改变】,小心父节点是空
  5. 调整后的树高不变【等于oldH】调整完毕,否则递归调整父亲节点。

代码

  • BTree.h
#pragma once

#include
#include
#include
#include
#include
using namespace std;

/*状态码*/
const int FAIL = -1;
const int OK = 0;
const int ERROR = -3;


//定义二叉树节点
template
struct BTNode
{    
    T val;   
    BTNode *lChild, *rChild;
    BTNode() :val(0), lChild(nullptr), rChild(nullptr) {}
    BTNode(T x, BTNode *l = nullptr, BTNode *r = nullptr) 
        : val(x), lChild(l), rChild(r) {}
};


//定义索引二叉树节点
template
struct indexBTNode
{
    //帮助不大不需要继承
    int val;
    int leftSize;
    indexBTNode *lChild, *rChild;

    indexBTNode() :val(0), leftSize(0), lChild(nullptr), rChild(nullptr) {}
    indexBTNode(T x, indexBTNode *l = nullptr, indexBTNode *r = nullptr)
        : val(x),leftSize(0), lChild(l), rChild(r) {}
};



//定义平衡树节点
template
struct AVLNode :BTNode
{
    int height;
    AVLNode* lChild, *rChild,*fPtr;
    AVLNode():height(0),lChild(nullptr), rChild(nullptr), fPtr(nullptr) {
        this->val = 0;
    }
    AVLNode(const T data) :
        height(0), lChild(nullptr), rChild(nullptr), fPtr(nullptr) {
        this->val = data;
    }

};


/*
    这里保证继承的类之间都是同一种节点类型
    子指针可以转化为父指针
*/

typedef int DATATYPE;
typedef indexBTNode* BPtr;



/*通用的一些函数*/
template
BPtr newNode(const T x) {
    return new indexBTNode(x);
}

template
BPtr newNode(BPtr &father, T x) {
    BPtr node = new AVLNode(x);
    node->fPtr = father;//给父指针赋值
    return node;
}


bool isLeaf(BPtr node) {
    if (node == nullptr) return false;
    return node->lChild == nullptr && node->rChild == nullptr;
}

void error(string str) {
    cout <<"errr:" <
class BTree
{
public:
    BTree(){
        m_root = newNode(-1);
    }
    ~BTree();

    int show();
    void preVisit(BPtr p);

protected:
    //保证继承可以访问到根指针
    BPtr m_root;
private:
    void destroy(BPtr p);
};

template
inline int BTree::show()
{
    if (m_root == nullptr) return FAIL;
    cout << "list = [";
    preVisit(m_root);
    cout << "]" << endl;
    return OK;
}

template
inline void BTree::preVisit(BPtr p)
{
    if (p == nullptr) return;
    cout << " " << p->val;
    preVisit(p->lChild);
    preVisit(p->rChild);
}


template
inline void BTree::destroy(BPtr p)
{
    if (p == nullptr) return;

    destroy(p->lChild);
    destroy(p->rChild);
    delete p;
}

template
inline BTree::~BTree()
{
    destroy(m_root);
    m_root = nullptr;
}
  • BSTree.h
#pragma once

#include"BTree.h"

template
class BSTree :    public BTree
{
public:
    BSTree() {}
    BSTree(const vector& arr);//不含重复元素

    //在指定子树上查找
    int find(BPtr root, const T target, BPtr &ptr, BPtr &fptr);
    //默认在整棵树上找
    int find(const T target);
    //
    T findMax() { return getMax(this->m_root); }
    T findMin() { return getMin(this->m_root); }

    //insert remove
    int remove(const T target);
    int insert(const T target);


private:
    //找到前驱或后继并删除该节点
    int findNextVal(BPtr ptr);
protected:
    T getMax(BPtr root, bool del = false, BPtr father = nullptr);
    T getMin(BPtr root, bool del = false, BPtr father = nullptr);
};

template
inline BSTree::BSTree(const vector& arr)
{
    this->m_root =newNode(arr[0]);
    int n = arr.size();
    for (int i = 1; i < n; ++i) {
        insert(arr[i]);
    }
}


template
inline int BSTree::find(BPtr root, const T target, BPtr &ptr, BPtr &fptr)
{
    if (root == nullptr) {
        ptr = fptr = nullptr;
        return FAIL;
    }

    ptr = fptr= root;

    while (ptr != nullptr)
    {
        T data = ptr->val;
        if (data == target) return OK;//细节:如果最后考虑相等会怎样?父指针?

        fptr = ptr;
        if (data < target) {
            ptr = ptr->rChild;
        }
        else {
            ptr = ptr->lChild;
        }
    }

    return FAIL;
}

template
inline int BSTree::find(const T target)
{
    if (this->m_root == nullptr) {
        return FAIL;
    }

    BPtr ptr= this->m_root;

    while (ptr != nullptr)
    {
        T data = ptr->val;
        if (data == target) 
            return OK;
        if (data < target) {
            ptr = ptr->rChild;
        }
        else {
            ptr = ptr->lChild;
        }
    }

    return FAIL;

}

template
inline T BSTree::getMax(BPtr root, bool del,BPtr father)
{
    //非法输入
    if (!root) return FAIL;

    //开始,root是father的左孩子,即在左子树找最大值
    bool isLeft = true;
    BPtr p = root;

    while (p->rChild != nullptr) {
        father = p;
        p = p->rChild;
        isLeft = false;//现在成了右孩子
    }

    T ans = p->val;
    //这里的写法有点省劲,找最大值和删除揉在一起了
    //否则需要返回最值(前驱)的父指针
    if (del) {
        if (isLeft) {
            father->lChild = p->lChild;
        }
        else {
            father->rChild = p->lChild;
        }
        free(p);
        p = nullptr;
    }

    return ans;
}

template
inline T BSTree::getMin(BPtr root, bool del,BPtr father)
{
    //非法输入
    if (!root) return FAIL;

    //开始,root是father的右孩子,即在右子树找最小值
    bool isRight = true;
    BPtr p = root;

    while (p->lChild != nullptr) {
        father = p;
        p = p->lChild;
        isRight = false;//现在成了左孩子
    }

    T ans = p->val;
    if (del) {
        if (isRight) {
            father->rChild = p->rChild;
        }
        else {
            father->lChild = p->rChild;
        }
        free(p);
        p = nullptr;
    }
    return ans;
}


template
inline int BSTree::remove(const T target)
{
    BPtr ptr = nullptr;
    BPtr fptr = nullptr;
    bool isleft = false;

    if (find(this->m_root,target, ptr, fptr) != FAIL) {

        isleft = (fptr->rChild->val != target);

        if (isLeaf(ptr)) {
            delete ptr;
            if (isleft) {
                fptr->lChild = nullptr;
            }
            else {
                fptr->rChild = nullptr;
            }
            return OK;
        }

        //ptr->val = findNextVal(ptr);
        //等价于下面一句,用前驱或后继替代
        if (ptr->lChild == nullptr) {
            ptr->val = getMin(ptr->rChild, true, ptr);
        }
        else {
            ptr->val = getMax(ptr->lChild, true, ptr);
        }
        
    }

    return OK;
}

template
inline int BSTree::insert(const T target)
{
    BPtr ptr=nullptr;
    BPtr fptr=nullptr;
    
    if (find(this->m_root,target, ptr, fptr) == FAIL) {
        //新值才插入,不含重复值
        BPtr _node = newNode(target);
        if (fptr->val > target) {
            fptr->lChild = _node;
        }
        else {
            fptr->rChild = _node;
        }
    }
    return 0;
}

template
inline int BSTree::findNextVal(BPtr ptr)
{//返回当前值的前驱或后继,并删除前驱或后继,一个函数干的事太多,调了好久
    int ans = 0;
    BPtr p = nullptr;
    BPtr f = nullptr;//前驱或后继的父亲
    if (ptr->lChild == nullptr) {
        p = ptr->rChild;

        if (p->lChild == nullptr) {
            ptr->rChild = p->rChild;
            ans = p->val;
            free(p);
            return ans;
        }

        while (p->lChild) {
            f = p;
            p = p->lChild;
        }

        ans = p->val;

        f->lChild = p->rChild;
        free(p);
    }
    else {//这里相当于查找最大值并删除getMax
        p = ptr->lChild;

        if (p->rChild == nullptr) {
            ptr->lChild = p->lChild;
            ans = p->val;
            free(p);
            return ans;
        }

        while (p->rChild) {
            f = p;
            p = p->rChild;
        }

        ans = p->val;

        f->rChild = p->lChild;
        free(p);
    }

    return ans;
}


void test_bstree() {
    vector a = { 9,5,4,6,15,10,16,14,13 };
    BSTree Sbt(a);
    Sbt.show();

    Sbt.remove(9);
    Sbt.show();

    Sbt.insert(11);
    Sbt.remove(14);
    Sbt.show();

    Sbt.remove(5);
    Sbt.insert(12);
    Sbt.show();
    Sbt.remove(16);
    Sbt.show();

}
  • AVL.h
#pragma once
#include"BSTree.h"

template
class AVLTree:public BSTree
{
public:
    AVLTree(){
        this->m_root = newNode(10);
    }
    AVLTree(vector& vec);

    //插入结点
    void insert(BPtr &root, T x, BPtr fptr=nullptr);
    
    //指定子树中删除结点
    int remove(BPtr &t, T x);
    //默认从整棵树找那个删除
    int remove(T x) { return remove(this->m_root, x); }


private:
    enum { LL, RR, LR, RL };
    //指的是形状而非旋转方向
    BPtr LLrotate(BPtr &t);
    BPtr RRrotate(BPtr &t);
    BPtr LRrotate(BPtr &t);
    BPtr RLrotate(BPtr &t);

    int getHeight(const BPtr &p);
    void updateHeight(const BPtr &p);
    void adjustTree(BPtr &p);
    bool isBalanceTree(const BPtr &p);
    int getBalanceFactor(const BPtr &p);
    int get1thUnbalanceFather(BPtr p);
    int getRotateType(const BPtr &p);
};

template 
int AVLTree::getHeight(const BPtr &root)
{//叶子的高度是零,空指针是-1
    if (root == nullptr)
        return -1;
    else
        return root->height;
}

template
inline void AVLTree::updateHeight(const BPtr &p)
{
    p->height= max(getHeight(p->lChild), getHeight(p->rChild)) + 1;
}

template
inline void AVLTree::adjustTree(BPtr & father)
{
    //this->m_root->fPtr = nullptr;//旋转多次后,确保根的爸爸是空

    BPtr up = father->fPtr;//头上的部分,先保存一波
    
    bool isRoot = false;
    bool is_r_son;
    if (up == nullptr) {
        up = this->m_root;
        isRoot = true;
    }

    if (!isRoot) {
        is_r_son = father == up->rChild;
    }

    int oldH = father->height;
    if (get1thUnbalanceFather(father) == FAIL) {
        return;//不用调整
    }
    else {
        int type = getRotateType(father);
        switch (type)
        {
        case LL:
            father = LLrotate(father);
            break;
        case RR:
            father = RRrotate(father);
            break;
        case LR:
            father = LRrotate(father);
            break;
        case RL:
            father = RLrotate(father);
            break;
        default:
            break;
        }

    }
    //收尾工作,把头接上
    if (isRoot) {
        this->m_root = father;
        return;
    }
    else {
        //不是头节点,在中间
        if (is_r_son) {
            up->rChild = father;
        }
        else {
            up->lChild = father;
        }
    }
    //是否需要继续调整
    if (oldH != father->height) adjustTree(father->fPtr);

}

template
inline bool AVLTree::isBalanceTree(const BPtr &p)
{
    return abs(getBalanceFactor(p)) <= 1;
}

template
inline int AVLTree::getBalanceFactor(const BPtr & p)
{
    if (p == nullptr) {
        error("pointer not null, if you want BalanceFactor.");
        return ERROR;
    }
    return getHeight(p->lChild)-getHeight(p->rChild);
}

template
inline int AVLTree::get1thUnbalanceFather(BPtr p)
{//向上查找第一个不平衡的祖先,OK表示存在不平衡
    while (p) {
        if (!isBalanceTree(p)) break;
        p = p->fPtr;
    }
    if (p == nullptr) return FAIL;
    return OK;
}

template
inline int AVLTree::getRotateType(const BPtr & p)
{//调用的前提是p节点不平衡,即平衡因子是2或-2
    int rootBF = getBalanceFactor(p);

    int rightBF=(p->rChild) ? getBalanceFactor(p->rChild):5;
    int leftBF = (p->lChild) ? getBalanceFactor(p->lChild):5;

    if (rootBF > 0 && leftBF<2) {//2
        if (leftBF >= 0) {//1,0
            return LL;
        }
        else return LR;
    }
    else {//-2
        if (rightBF > 2) return ERROR;
        if (rightBF >= 0) {//1,0
            return RL;
        }
        else {
            return RR;
        }
    }

    return ERROR;
}


template
inline AVLTree::AVLTree(vector& v)
{
    this->m_root = newNode(v[0]);
    int n = v.size();
    for (int i = 1; i < n; ++i) {
        insert(this->m_root,v[i]);
    }
}

template
inline void AVLTree::insert(BPtr & root, T x, BPtr fptr)
{
    if (root == nullptr) {
        root = newNode(fptr,x);
        return;
    }

    if (x < root->val) {
        insert(root->lChild, x,root); updateHeight(root);
        
        if (!isBalanceTree(root)) {
            if (x < root->lChild->val) {
                root = LLrotate(root);
            }
            else {
                root = LRrotate(root);
            }
        }
    }
    else if (x > root->val) {
        insert(root->rChild, x,root);
        updateHeight(root);

        if (!isBalanceTree(root)) {
            if (x > root->rChild->val) {
                root = RRrotate(root);
            }else{
                root = RLrotate(root);
            }
        }
    }
    else {
        ;//数据重复
    }
    
}

template
inline int AVLTree::remove(BPtr & root, T x)
{
    BPtr fptr = nullptr;
    BPtr ptr = nullptr;
    if (this->find(root,x, ptr, fptr) == FAIL) return OK;

    bool is_r_son = fptr->rChild == ptr;

    //x is leaf
    if (isLeaf(ptr)) {
        free(ptr);
        ptr = nullptr;
        if (is_r_son) {
            fptr->rChild = nullptr;
        }
        else fptr->lChild = nullptr;
        adjustTree(fptr);
    }
    else if (ptr->lChild && ptr->rChild==nullptr) {//只有左孩子
        if (is_r_son) {
            fptr->rChild = ptr->lChild;
        }
        else fptr->lChild = ptr->lChild;
        free(ptr);
        ptr = nullptr;
        adjustTree(fptr);
    }
    else if (ptr->rChild && ptr->lChild == nullptr) {//只有右孩子
        if (is_r_son) {
            fptr->rChild = ptr->rChild;
        }
        else fptr->lChild = ptr->rChild;
        free(ptr);
        ptr = nullptr;
        adjustTree(fptr);
    }
    else{
        ptr->val = this->getMax(ptr->lChild);
        if (ptr->val == ptr->lChild->val) {//刚好就是左孩子
            BPtr t = ptr->lChild;
            ptr->lChild = t->lChild;
            free(t);
            t = nullptr;
            //这里一定平衡么?
        }else remove(ptr->lChild, ptr->val);
    }

    return OK;
}

/*单旋转
左左插入导致的不平衡,这里是右旋
        top
        /
       core
      /       \ 
    lchild  r
*/
template 
BPtr  AVLTree::LLrotate(BPtr &top)
{

    BPtr core = top->lChild;
    BPtr temp = core->rChild;

    //一旋二挤
    core->rChild = top;
    //三连
    top->lChild = temp;
    updateHeight(top);
    //调整父指针
    core->fPtr = top->fPtr;
    top->fPtr = core;

    updateHeight(core);
    return core;
}

/*单旋转
右右插入导致的不平衡,这里是左旋
    top
      \
      core
     /    \
    l   rchild
*/
template 
BPtr  AVLTree::RRrotate(BPtr &top)
{
    BPtr core = top->rChild;
    BPtr temp = core->lChild;

    //一旋二挤
    core->lChild = top;
    //三连
    top->rChild = temp;
    updateHeight(top);
    
    //调整父指针
    core->fPtr = top->fPtr;
    top->fPtr = core;

    updateHeight(core);
    int b=core->height;
    int a=core->val;
    return core;
}


//插入点位于t的左儿子的右子树
template 
BPtr  AVLTree::LRrotate(BPtr &top)
{
    //旋转后需要接上
    top->lChild=RRrotate(top->lChild);
    return LLrotate(top);
}

//插入点位于t的右儿子的左子树
template 
BPtr  AVLTree::RLrotate(BPtr &top)
{
    top->rChild=LLrotate(top->rChild);
    return RRrotate(top);
}

//6,11,5,12,4,1,14,17,2,3
void test_avltree() {
    vector a = { 6,11,5,12,4,1,14,17,2,3 };
    AVLTree Sbt(a);
    Sbt.show();
    Sbt.remove(6);
    Sbt.show();
    Sbt.remove(11);
    Sbt.show();
    Sbt.remove(14);
    Sbt.show();
}
  • 索引二叉搜索树
#pragma once
#include"BSTree.h"


template
class idxBTree:public BSTree
{
public:
    idxBTree(){
        this->m_root = newNode(-1);
    }
    idxBTree(const vector &arr);

    void insert(const T target);
    void erase(const T target);

    T getKth(int nth);//升序的第K个,下标为K-1

private:
    int TreeSize(BPtr root);
    void insert(BPtr& root, const T target);
    T getKth(BPtr root, int nth);
    void erase(BPtr root,const T target);
};

template
inline idxBTree::idxBTree(const vector &arr)
{
    int size = arr.size();
    for (int i = 0; i < size; i++)
    {
        insert(arr[i]);
    }
}

template
inline void idxBTree::insert(const T target)
{
    if (this->find(target) == FAIL) {
        insert(this->m_root, target);
    }
}

template
inline void idxBTree::erase(const T target)
{
    if (this->find(target) == FAIL) return;
    if (isLeaf(this->m_root)) {
        freeNode(this->m_root);
        return;
    }
    erase(this->m_root, target);
}

template
inline void idxBTree::erase(BPtr root,const T target)
{//函数外保证一定存在target,且不是叶子节点
    
    if (!root) return;

    BPtr ptr = root;
    BPtr father = ptr;

    //修改root 到 target 之间的leftsize
    while (ptr) {

        T data = ptr->val;
        
        if (data == target) break;
        father = ptr;//注意到此时记录父亲才是有意义的

        if (data < target) {
            ptr = ptr->rChild;
        }
        else{
            ptr->leftSize--;
            ptr = ptr->lChild;
        }
    }

    /*
    while (ptr) {
        T data = ptr->val;
        
        if (data < target) {
            father = ptr;
            ptr = ptr->rChild;
        }
        else if(data>target) {
            father = ptr;
            ptr->leftSize--;
            ptr = ptr->lChild;
        }
        else {
            break;
        }
    }
    
    
    
    
    
    */
    if (!ptr) return;
    BPtr lson = ptr->lChild;
    BPtr rson = ptr->rChild;
    if (lson) {//取前一个值替代
        ptr->leftSize--;
        T pre = this->getMax(lson);
        ptr->val = pre;

        if (isLeaf(lson)) {
            ptr->lChild = nullptr;
            freeNode(lson);
        }else erase(ptr->lChild, pre);
    }
    else if(rson) {//取后一个值替代
        T next = this->getMin(rson);
        ptr->val = next;
        if (isLeaf(rson)) {
            ptr->rChild = nullptr;
            freeNode(rson);
        }
        else erase(ptr->rChild, next);
    }
    else {
        if (father->lChild == ptr) {
            father->lChild = nullptr;
        }
        else {
            father->rChild = nullptr;
        }
        delete ptr;
        ptr = nullptr;
        return;
    }
}


template
inline T idxBTree::getKth(int nth)
{
    //第几个从一开始,序号从零开始
    int idx = nth - 1;
    if (idx<0 || this->m_root==nullptr || idx > TreeSize(this->m_root) - 1) {
        error("tree not null and  maxSize > nth > 0.");
        return T(-1);
    }

    return getKth(this->m_root, idx);
}

template
inline int idxBTree::TreeSize(BPtr root)
{
    if (root == nullptr) return 0;

    return TreeSize(root->rChild) + root->leftSize + 1;
}

template
inline void idxBTree::insert(BPtr& root, const T target)
{//重复在函数外已经检查
    if (root == nullptr) {
        root = newNode(target);
        return;//care
    }

    if (target < root->val) {//插入左树
        root->leftSize++;
        insert(root->lChild, target);
    }
    else {
        insert(root->rChild, target);
    }
}

template
inline T idxBTree::getKth(BPtr root, int idx)
{//函数外已经检查nth的合法性
    int lsize = root->leftSize;
    int val = 0;
    if (idx ==    lsize ) return root->val;

    if (idx < lsize) {
        val=getKth(root->lChild, idx);
    }
    else {
        val=getKth(root->rChild, idx - 1 - lsize);
    }

    return val;
}


void test_indexTree() {
    vector arr = {
        //20,15,25,12,18,30,22,19 
        30,12,50,14,40,60,13,15,35,38,18,16
    };

    idxBTree it(arr);
    it.show();
    /*test getKth()*/
    //cout << "5th :" << it.getKth(5)<
  • main.cpp
#include"idxBSTree.h"


int main() {
    //test_avltree();
    //test_bstree();
    test_indexTree();
    system("pause");
    return 0;
}

你可能感兴趣的:(c++,算法)