二叉搜索树学习——————之一

     二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。也就是说对于任意一个节点x,其左子树中的关键字均不大于x.key,其右子树均不小于x.key。概念性的东西就不多说了,,下面直接用C语言实现,,用注释说明问题会更清晰一些

捕获

二叉查找树主要定义了如下操作:

typedef struct TreeNode{    //二叉搜索树的节点信息
    int data;
    struct TreeNode* pRight;
    struct TreeNode* pLeft;
    struct TreeNode* pFather;
}TreeNode;
TreeNode* Tree = NULL;
//使用指定的整形数组,构造二叉搜索树
TreeNode* constructTree(int arr[] , int len);

//使用一个整型值初始化一个节点
TreeNode* constructNode(int num);


//搜索二叉搜索树
TreeNode* search(TreeNode* tree, int num);

//在树中查找最小的元素
TreeNode* minNum(TreeNode* tree);

//在树种查找最大的元素
TreeNode* maxNum(TreeNode* tree);

//中序遍历输出树并输出相关信息
void traverse(TreeNode* tree);


//处理节点
void handleNode(TreeNode* node);
//插入节点
bool insert(TreeNode* tree, int num);

//删除节点信息
TreeNode* deleteNode(TreeNode* tree, int num);

TreeNode* transplant(TreeNode* u, TreeNode* v);

//寻找给定节点的前驱
TreeNode* successor(TreeNode* tree, int num);

  我是将上面的的搜索二叉树的操作方法定义在binarySearchTree.h中,然后在binarySearchTree.cpp中实现的,下面是具体的实现代码:

#include<iostream>
#include"binarySearchTree.h"
#include<stdlib.h>
#include<time.h>


using namespace std;




//使用指定的整形数组,构造二叉搜索树
TreeNode* constructTree(int arr[] , int len){
    int index = rand() % len;
    TreeNode* pHead = constructNode(arr[1]);
    for (int i = 0; i < len; i++){
        insert(pHead, arr[i]);
    }
    return pHead;
}




//使用一个整型值初始化一个节点
TreeNode* constructNode(int num){
    TreeNode* pNode = new TreeNode();
    pNode->data = num;
    pNode->pFather = NULL;
    pNode->pLeft = NULL;
    pNode->pRight = NULL;
    return pNode;
}





//插入节点
bool insert(TreeNode* tree, int num){
    TreeNode* pNode = constructNode(num);
    TreeNode* pTemp = tree;
    TreeNode* p = NULL;
    while (pTemp != NULL){
        p = pTemp;    //指向当前节点的父节点
        if (num > pTemp->data){    //num值比当前节点大就向右移动指正,否则就像左移动指针
            pTemp = pTemp->pRight;
        }
        else{
            pTemp = pTemp->pLeft;
        }
    }
    if (p == NULL){        //空树,,无法插入节点
        return false;
    }
    pNode->pFather = p;
    if (pNode->data > p->data){
        p->pRight = pNode;
    }
    else{
        p->pLeft = pNode;
    }
    return true;

}


//中序遍历输出树并输出相关信息
void traverse(TreeNode* tree){
    if (tree == NULL){
        return;
    }
    traverse(tree->pLeft);
    handleNode(tree);
    traverse(tree->pRight);
}


void freeTree(TreeNode* tree){
    if (tree == NULL){
        return;
    }
    traverse(tree->pLeft);
    traverse(tree->pRight);
    free(tree);
}


//处理节点
void handleNode(TreeNode* node){

    cout << node->data << "  ";
}


//在树中查找最小的元素
TreeNode* minNum(TreeNode* tree){
    if (tree == NULL){
        return NULL;
    }
    while (tree->pLeft != NULL){
        tree = tree->pLeft;
    }

    return tree;
}



//在树种查找最大的元素
TreeNode* maxNum(TreeNode* tree){
    if (tree == NULL){
        return NULL;
    }
    while (tree->pRight != NULL){
        tree = tree->pRight;
    }
    return tree;
}

//搜索二叉搜索树
TreeNode* search(TreeNode* tree, int num){
    while (tree != NULL){
        if (tree->data == num){
            break;
        }
        if (num > tree->data){
            tree = tree->pRight;
        }
        else{
            tree = tree->pLeft;
        }
    }

    return tree;
}



//寻找给定节点的前驱
TreeNode* successor(TreeNode* tree, int num){
    TreeNode* pNode = search(tree, num);
    if (pNode->pRight != NULL){
        return minNum(pNode->pRight);
    }
    TreeNode* p = pNode->pFather;
    while (p != NULL && p->pRight == pNode){
        pNode = p;
        p = p->pFather;
    }
    return p;
}




//删除节点信息
TreeNode* deleteNode(TreeNode* tree, int num){
    TreeNode* pNode = search(tree, num);
    if (pNode == NULL){
        return NULL;
    }
    if (pNode->pLeft == NULL){    //左节点为空时就直接使用有节点替换需要删除的节点
        transplant(pNode, pNode->pRight);
    }
    else if (pNode->pRight == NULL){
        transplant(pNode, pNode->pLeft);
    }
    else{
        TreeNode* v = minNum(pNode->pRight);
        if (v->pFather != pNode){
            transplant(v, v->pRight);
            v->pRight = pNode->pRight;
            v->pRight->pFather = v;
        }
        transplant(pNode, v);
        v->pLeft = pNode->pLeft;
        v->pLeft->pFather = v;
    }
    return pNode;
}

TreeNode* transplant(TreeNode* u, TreeNode* v){
    if (u->pFather == NULL){
        v->pFather = u->pFather;
        Tree = v;
        return u;
    }
    if (u == u->pFather->pLeft){
        u->pFather->pLeft = v;
    }
    else{
        u->pFather->pRight = v;
    }
    if (v != NULL){
        v->pFather = u->pFather;
    }
    return u;
}





int main(){
    cout << "==========  Binary Search Tree --- > Construct and Traverse=======\n";
    int arr[] = { 3, 4, 1, 2, 5, 10, 6, 9, 8 ,0};
    TreeNode* tree = constructTree(arr , 10);
    Tree = tree;
    traverse(tree);
    
    
    cout << "\n==========  Binary Search Tree --- > minNUm 、 maxNum、search、=======\n";
    cout << "minNum = " << minNum(tree)->data << "\n";
    cout << "maxNum = " << maxNum(tree)->data << "\n";
    cout << "search = " << search(tree, 5)->data << "\n";


    cout << "==========  Binary Search Tree --- > delete Num =======\n";
    for (int i = 0; i < 10; i++){
        TreeNode* node = deleteNode(Tree, arr[i]);
        cout << "delete num : " << node->data << "\n";
        free(node);
        if (i<9){
            traverse(Tree);
        }
    }


    //free(tree);
    getchar();
    return 0;
}
     以上代码实在VS2013上测试全部通过的,,,如果有bug,欢迎指正,感激不尽。。。。。
posted @ 2015-07-12 23:07  jiuguang  阅读(359)  评论(0编辑  收藏  举报