1. 结点结构

typedef struct BSTBitNode {
    int data;
    struct BSTBitNode *lchild,*rchild;
}BSTBitNode,*BSTBitTree;

2.  插入结点

static BSTBitNode * make_node(int key)
{
    BSTBitNode *p = (BSTBitNode *)malloc(sizeof(BSTBitNode));
    if(p == nullptr) {
        return nullptr;
    }
    p->data = key;
    p->lchild = p->rchild = nullptr;
    return p;
}

BSTBitNode *insertBST(BSTBitTree *proot,int key)
{
    BSTBitNode *pkey,*child,*parent;
    if(searchBST(*proot,key) != nullptr) {
        return nullptr;
    }

    pkey = make_node(key);

    if(*proot == nullptr) {
        *proot = pkey;
        return *proot;
    }
    parent = *proot;
    child = *proot;
    do{
        parent = child;
        if(key<parent->data) {
            child = parent->lchild;
        }
        else {
            child = parent->rchild;
        }
    }while(child != nullptr);
    if(key<parent->data) {
        parent->lchild = pkey;
    }
    else {
        parent->rchild = pkey;
    }
    return pkey;
}

  递归形式的插入结点:

BSTBitNode *insertBST_v2(BSTBitTree *proot,int key)
{
//    if(proot == nullptr) {
//        return nullptr;
//    }  //暂不考虑
    if(*proot == nullptr) {
        //说明当前还是空树
        *proot = make_node(key);
    }
    else if(key<(*proot)->data) {
        (*proot)->lchild = insertBST_v2(&((*proot)->lchild),key);
    }
    else if(key>(*proot)->data) {
        (*proot)->rchild = insertBST_v2(&((*proot)->rchild),key);
    }

    return (*proot);

}

3. 查找

(1)查找某结点:

BSTBitNode *searchBST(const BSTBitTree root,int key)
{
    if(root == nullptr) {
        return nullptr;
    }
    if(key<root->data) {
        return searchBST(root->lchild,key);
    }
    else if(key>root->data) {
        return searchBST(root->rchild,key);
    }
    else {
        return root;
    }
    // return nullptr; //这行没必要,对不在树中的元素进行查找,最后一次的递归调用会传nullptr进去,最后返回值也是nullptr
}

(2)

  查找最小、最大(参数是树的root时,最小结点就是中序遍历的第一个结点,最大结点就是中序遍历的最后一个结点):

BSTBitNode *findBSTMin(BSTBitTree root)  //以当前结点为根子树的最左边的结点
{
    if(root == nullptr) {
        return nullptr;
    }
    else if(root->lchild == nullptr) {   //换成rchild就是找最大值
        return root;
    }
    else {
        return findBSTMin(root->lchild);   //这里也要换成rchild
    }
}
BSTBitNode *findBSTMax (BSTBitTree root)
{
    if(root != nullptr) {
        while(root->rchild != nullptr) {
            root = root->rchild;
        }
    }
    return root;
}

(3)查找中序遍历时某结点的前驱、后继

  前驱:该结点左子树的最大结点(最大结点即最右边的结点,必然是叶子结点)---------该结点左子树的最右边结点

findBSTMax(node->lchild);

  后继:该结点右子树的最小结点(最小结点即最左边的结点,必然是叶子结点)---------该结点右子树的最左边结点

findBSTMin(node->rchild); 

4. 删除结点

4.1

  删除的策略:要删除的结点是如下:

  (1)结点为叶子结点:删除当前结点,并修改其父结点的指针

  (2)只有单个子结点:①只有左子,则要删除结点的父结点指向该左子 ②只有右子,类似

  (3)要删除有两个子结点的结点:用该结点的前驱或后继的内容代替该结点,再将那个前驱或后继从它们的位置上删掉

BSTBitNode *deleteNode_v2(BSTBitTree root,int key)
{
    BSTBitNode *tmp = nullptr;
    if(root == nullptr) {
        cout<<"Element:"<<key<<" not found."<<endl;
    }
    else if(key<root->data) {
        root->lchild = deleteNode_v2(root->lchild,key);
    }
    else if(key>root->data) {
        root->rchild = deleteNode_v2(root->rchild,key);
    }
    else {
        if(root->lchild && root->rchild) {
            tmp = findBSTMin(root->rchild); //找到要删除结点的后继
            root->data = tmp->data;
            root->rchild = deleteNode_v2(root->rchild,root->data);

//            tmp = findBSTMax(root->lchild);//找到要删除结点的前驱
//            root->data = tmp->data;
//            root->lchild = deleteNode_v2(root->lchild,key);
            //以上用结点前驱或后继数据代替当前结点数据都可以
        }
        else {
            //要删除结点只有单个孩子结点或没有孩子结点的情况
            tmp = root;
            if(root->lchild == nullptr) {
                root = root->rchild;
            }
            else if(root->rchild == nullptr) {
                root = root->lchild;
            }
            free(tmp);
        }
    }
    return root;
}

//以下的是通用的代码

  

5. 删除整个树

static void freeBSTTree(BSTBitTree root) {
    if(root != nullptr) {
        freeBSTTree(root->lchild);
        freeBSTTree(root->rchild);
        free(root);
    }
}

void clearBSTTree(BSTBitTree *proot)
{
    freeBSTTree(*proot);
    *proot = nullptr;
}

6. 统计树中结点个数

  (1)如果二叉树为空,结点个数为0
  (2)如果二叉树不为空, 当前树结点个数=左子树结点个数+右子树结点个数+1

int getBitTreeNum(BSTBitTree root)
{
    if(root == nullptr) {
        return 0;
    }
    return getBitTreeNum(root->lchild)+getBitTreeNum(root->rchild)+1;
}

7. 计算树深度

  (1)如果二叉树为空,二叉树深度为0
  (2)如果二叉树不为空, 当前树深度=max(左子树深度,右子树深度)+1

int getBitTreeDepth(BSTBitTree root)
{
    if(root == nullptr) {
        return 0;
    }
    int leftDepth = getBitTreeDepth(root->lchild);
    int rightDepth = getBitTreeDepth(root->rchild);
    return leftDepth>rightDepth?(leftDepth+1):(rightDepth+1);
}

8. 中序遍历BST

void inOrderTravelBST(BSTBitTree root)
{
    if(root != nullptr) {
        inOrderTravelBST(root->lchild);
        std::cout<<root->data<<" ";
        inOrderTravelBST(root->rchild);
    }
}

9. 深度优先遍历、广度优先遍历

void DepthFirstSearch(BSTBitTree root)
{
    stack<BSTBitNode *> bstNodeStack;
//    queue<BSTBitNode *> res;

    bstNodeStack.push(root);
    while(!bstNodeStack.empty()) {
        BSTBitNode *node = bstNodeStack.top();
        cout<<node->data<<" ";
//        res.push(node);
        bstNodeStack.pop();
        if(node->rchild) {
            bstNodeStack.push(node->rchild);
        }
        if(node->lchild) {
            bstNodeStack.push(node->lchild);
        }
    }
    cout<<endl;
//    while(!res.empty()) {
//        BSTBitNode *node = res.front();
//        cout<<node->data<<" ";
//        res.pop();
//    }
//    cout<<endl;
}
void BreadthFirstSearch(BSTBitTree root)
{
    queue<BSTBitNode *> bstNodeQueue;
//    queue<BSTBitNode *> res;  //如果需要返回的话
    bstNodeQueue.push(root);
    while(!bstNodeQueue.empty()) {
        BSTBitNode *node = bstNodeQueue.front(); //取队列中第一个数据
        cout<<node->data<<" ";
//        res.push(node);
        bstNodeQueue.pop();

        if(node->lchild) {
            bstNodeQueue.push(node->lchild);
        }
        if(node->rchild) {
            bstNodeQueue.push(node->rchild);
        }
    }
    cout<<endl;
//    while(!res.empty()) {
//        BSTBitNode *node = res.front();
//        cout<<node->data<<" ";
//        res.pop();
//    }
//    cout<<endl;
}
02-14 03:34