二插排序树

二分查找只适用于静态查找,不适合改变查找表。当然他们的时间复杂度都是logn
头文件

#ifndef _BSTREE_H_  
#define _BSTREE_H_  



typedef void BSTree;//数据封装  

typedef void BSKey;  

/********************** 
结点指针域定义 
**********************/  
typedef struct _tag_BSTreeNode BSTreeNode;  
struct _tag_BSTreeNode{  
    BSKey* key;  
    BSTreeNode* left;  
    BSTreeNode* right;  
};  

/********************** 
结点指针域定义 
**********************/  



typedef void (BSTree_Printf)(BSTreeNode*);//定义函数指针类型  

typedef int (BSTree_Compare)(BSKey* key1, BSKey* key2);  


BSTree* BSTree_Create();  

void BSTree_Destroy(BSTree* tree);  

void BSTree_Clear(BSTree* tree);  

int BSTree_Insert(BSTree* tree, BSTreeNode* node, BSTree_Compare* pFunc);//count代表要转几次弯,flag指明原来的子                                                                              //树是作为新节点的左孩子还是右孩子  

BSTreeNode* BSTree_Delete(BSTree* tree, BSKey* key,BSTree_Compare* pFunc);  

BSTreeNode* BSTree_Get(BSTree* tree, BSKey* key, BSTree_Compare* pFunc);  

BSTreeNode* BSTree_Root(BSTree* tree);  

int BSTree_Height(BSTree* tree);  

int BSTree_Count(BSTree* tree);  

int BSTree_Degree(BSTree* tree);  

void BSTree_Display(BSTree* tree, BSTree_Printf* pFunc, int gap, char div);  

#endif  

实现文件

#include <stdio.h>  
#include <malloc.h>  
#include "BSTree.h"  


/********************** 
头节点结构体定义 
**********************/  
typedef struct _tag_BSTree TBSTree;  
struct _tag_BSTree{  
    int count;//树的节点数  
    BSTreeNode* root;//指向根节点的指针  
};  


static void recursive_display(BSTreeNode* node, BSTree_Printf* pFunc, int format, int gap, char div){  
    int i = 0;  
    if ((node != NULL) && (pFunc != NULL)){//合法性检测  
        for (i = 0; i < format; i++){//打印缩进字符  
            printf("%c", div);  
        }  
        pFunc(node);//调用用户函数打印实际数据  

        printf("\n");  

        if ((node->left != NULL) || (node->right != NULL)){//如果两个同时为空即到达叶节点,退出递归,否则就打印  
            recursive_display(node->left, pFunc, format + gap, gap, div);  
            recursive_display(node->right, pFunc, format + gap, gap, div);  
        }  
    }  
    else{//如果为空,即只有一个子节点,则另一个只打印缩进字符  
        for (i = 0; i < format; i++){  
            printf("%c", div);  
        }  
        printf("\n");  
    }  
}  


static int recursive_count(BSTreeNode* root) // O(n)递归求节点数  
{  
    int ret = 0;  

    if (root != NULL)  
    {  
        ret = recursive_count(root->left) + 1 + recursive_count(root->right);//左子树 + 右子树 +根节点  
    }  

    return ret;  
}  

static int recursive_height(BSTreeNode* node)  
{  
    int ret = 0;  
    if (node != NULL){  
        int L_Height = recursive_height(node->left);  
        int R_Height = recursive_height(node->right);  

        ret = ((L_Height > R_Height) ? L_Height : R_Height) + 1;//不要忘了加上根节点  
    }  
    return ret;  
}  


static int recursive_degree(BSTreeNode* node)  
{  
    int ret = 0;  
    if (node != NULL){  
        if (node->left != NULL){  
            ret++;  
        }  
        if (node->right != NULL){  
            ret++;  
        }  
        if (ret == 1){  
            int ld = recursive_degree(node->left);  
            int rd = recursive_degree(node->right);  

            if (ret < ld){  
                ret = ld;  
            }  

            if (ret < rd){  
                ret = rd;  
            }  

        }  
    }  
    return ret;  
}  


static int recursive_insert(BSTreeNode* root,BSTreeNode* node,BSTree_Compare* compare)  
{  
    int ret = 1;  

    ret = (root != NULL) && (node != NULL) && (compare != NULL);  

    if (ret){  
        int r = compare(node->key,root->key);  

        if (0 == r){//如果已经有了这个节点,返回0,表示不插入新节点  
            ret = 0;  
        }  
        else if (r < 0){//比当前节点小,且其左孩子不为空,则递归查找当前节点的左孩子及其所有左子树  
            if (root->left != NULL){  
                ret = recursive_insert(root->left, node, compare);  
            }  
            else{//否则直接当作当前节点的左孩子  
                root->left = node;  
            }  
        }  
        else if (r > 0){//比当前节点大,且其右孩子不为空,则递归查找当前节点的右孩子及其所有右子树  
            if (root->right != NULL){  
                ret = recursive_insert(root->right, node, compare);  
            }  
            else{//否则直接当作当前节点的右孩子  
                root->right = node;  
            }  
        }  
    }  

    return ret;  
}  


static BSTreeNode* recursive_get(BSTreeNode* root, BSKey* key, BSTree_Compare* compare)  
{  
    BSTreeNode* ret = NULL;  

    if (root != NULL){  


        int r = compare(key, root->key);  

        if (0 == r){//关键字和当前节点的匹配则将当前节点返回  
            ret = root;  
        }  
        else if (r < 0){//比当前节点小,往左子树递归寻找  
            ret = recursive_get(root->left,key,compare);  
        }  
        else if (r > 0){//比当前节点大,往右子树递归寻找  
            ret = recursive_get(root->right, key, compare);  
        }  
    }  

    return ret;  
}  
static BSTreeNode* delete_node(BSTreeNode** root){  
    BSTreeNode* ret = *root;//记录要删除的节点并返回  

    if ((*root)->right == NULL){//如果右孩子为空则将左孩子提上来  
        (*root) = (*root)->left;  
    }  
    else if ((*root)->left == NULL){//如果左孩子为空则将右孩子提上来  
        (*root) = (*root)->right;  
    }  
    else{//有两个不为空的孩子  
        BSTreeNode* g = *root;//因为root是二级指针  
        BSTreeNode* c = (*root)->left;//记录要删除节点的左孩子  

        while (c->right != NULL){//一般情况是先查看要删除节点的左孩子,再递归的查看其左孩子的右子树,直到遇到叶节点  
            g = c;  
            c = c->right;//不断查找下一个右孩子  
        }  

        if (g != *root){//如果经过了一个及以上的右孩子且最先经过一个左孩子,却又可能最后一个右孩子有一个左孩子,则最                                                             //后要将他的左孩子变为上一个节点的右孩子  
            g->right = c->left;  
        }  
        else{//如果一次右孩子都没有经历过,即没有经过while循环,则直接将当前节点的左孩子提上来使得树连贯起来不间断  
            g->left = c->left;  
        }  

        c->left = (*root)->left;//将c指向的节点直接替代要删除的节点,三个步骤都不能缺少  
        c->right = (*root)->right;  
        *root = c;  
    }  

    return ret;  
}  

static BSTreeNode* recursive_delete(BSTreeNode** root, BSKey* key, BSTree_Compare* compare)  
{  
    BSTreeNode* ret = NULL;  

    if ((root != NULL) && (*root != NULL)){  
        int r = compare(key,(*root)->key);  

        if (0 == r){  
            ret = delete_node(root);  
        }  
        else if(r < 0){  
            ret = recursive_delete(&((*root)->left),key,compare);  
        }  
        else if (r > 0){  
            ret = recursive_delete(&((*root)->right), key, compare);  
        }  
    }  

    return ret;  
}  

BSTree* BSTree_Create()//和单链表类似,先申请堆空间,再合法性检测以及初始化  
{  
    TBSTree* ret = (TBSTree*)malloc(sizeof(TBSTree));  
    if (ret != NULL){  
        ret->count = 0;  
        ret->root = NULL;  
    }  
    return ret;  
}  

void BSTree_Destroy(BSTree* tree)//二叉树的销毁可以直接用free  
{  
    free(tree);  
}  

void BSTree_Clear(BSTree* tree)//要记住合法性检测  
{  
    TBSTree* btree = (TBSTree*)tree;  
    if (btree != NULL){  
        btree->count = 0;  
        btree->root = NULL;  
    }  
}  

int BSTree_Insert(BSTree* tree, BSTreeNode* node, BSTree_Compare* pFunc)  
{  
    TBSTree* btree = (BSTree*)tree;  
    int ret = (btree != NULL) && (node != NULL) && (pFunc != NULL);//合法性判断  

    if (ret){  

        node->left = NULL;//记得使用之前给所有指针变量赋值  
        node->right = NULL;  

        if (btree->root == NULL){//如果树原来为空则插入的是根节点  
            btree->root = node;  
        }  
        else{//否则递归的找到叶节点再插入  
            ret = recursive_insert(btree->root,node,pFunc);  
        }  

        if (ret){//有可能树里面已经有了要插入的节点,此时将不会插入新节点,所以节点数不一定增加  
            btree->count++;  
        }  

    }  
    return ret;  
}  

BSTreeNode* BSTree_Delete(BSTree* tree, BSKey* key, BSTree_Compare* pFunc)  
{  
    TBSTree* btree = (TBSTree*)tree;  

    BSTreeNode* ret = NULL;  

    if ((btree != NULL) && (key != NULL) && (pFunc != NULL)){//合法性判断  
        ret = recursive_delete(&btree->root,key,pFunc);  

        if (ret != NULL){//返回一个非空的值则表示删除成功,才可以将节点数减少  
            btree->count--;  
        }  
    }  

    return ret;  
}  
BSTreeNode* BSTree_Get(BSTree* tree, BSKey* key, BSTree_Compare* pFunc)  
{  
    TBSTree* btree = (BSTree*)tree;  
    BSTreeNode* ret = NULL;  

    if ((btree != NULL) && (key != NULL) && (pFunc != NULL)){//合法性判断  
        ret = recursive_get(btree->root,key,pFunc);  
    }  

    return ret;  
}  

BSTreeNode* BSTree_Root(BSTree* tree)  
{  
    TBSTree* btree = (TBSTree*)tree;  
    BSTreeNode* ret = NULL;  
    if (btree != NULL){  
        ret = btree->root;  
    }  
    return ret;  
}  

int BSTree_Height(BSTree* tree)  
{  
    TBSTree* btree = (TBSTree*)tree;  
    int ret = -1;  
    if (btree != NULL){  
        ret = recursive_height(btree->root);  
    }  
    return ret;  
}  

int BSTree_Count(BSTree* tree)  
{  
    TBSTree* btree = (TBSTree*)tree;  
    int ret = -1;  
    if (btree != NULL){  
        ret = btree->count;  
    }  
    return ret;  
}  

int BSTree_Degree(BSTree* tree)  
{  
    TBSTree* btree = (TBSTree*)tree;  
    int ret = -1;  
    if (btree != NULL){  
        ret = recursive_degree(btree->root);  
    }  
    return ret;  
}  



//传入的是tree,实际上操作的是node,且从root开始  
void BSTree_Display(BSTree* tree, BSTree_Printf* pFunc, int gap, char div)  
{  
    TBSTree* btree = (TBSTree*)tree;//先类型转换  
    if (btree != NULL){  
        recursive_display(btree->root, pFunc, 0, gap, div);  
    }  
}  

测试文件

#include <stdio.h>  
#include <stdlib.h>  
#include "BSTree.h"  

/* run this program using the console pauser or add your own getch, system("pause") or input loop */  

struct Node  
{  
    BSTreeNode header;  
    char v;  
};  

void printf_data(BSTreeNode* node)  
{  
    if (node != NULL)  
    {  
        printf("%c", ((struct Node*)node)->v);  
    }  
}  

int compare_key(BSKey* k1, BSKey* k2)  
{  
    return (int)k1 - (int)k2;  
}  

int main(int argc, char *argv[])  
{  
    BSTree* tree = BSTree_Create();  

    struct Node n1 = { { (BSKey*)1, NULL, NULL }, 'A' };  
    struct Node n2 = { { (BSKey*)2, NULL, NULL }, 'B' };  
    struct Node n3 = { { (BSKey*)3, NULL, NULL }, 'C' };  
    struct Node n4 = { { (BSKey*)4, NULL, NULL }, 'D' };  
    struct Node n5 = { { (BSKey*)5, NULL, NULL }, 'E' };  
    struct Node n6 = { { (BSKey*)6, NULL, NULL }, 'F' };  

    BSTree_Insert(tree, (BSTreeNode*)&n4, compare_key);  
    BSTree_Insert(tree, (BSTreeNode*)&n1, compare_key);  
    BSTree_Insert(tree, (BSTreeNode*)&n3, compare_key);  
    BSTree_Insert(tree, (BSTreeNode*)&n6, compare_key);  
    BSTree_Insert(tree, (BSTreeNode*)&n2, compare_key);  
    BSTree_Insert(tree, (BSTreeNode*)&n5, compare_key);  

    printf("Height: %d\n", BSTree_Height(tree));  
    printf("Degree: %d\n", BSTree_Degree(tree));  
    printf("Count: %d\n", BSTree_Count(tree));  
    printf("Search Key 5: %c\n", ((struct Node*)BSTree_Get(tree, (BSKey*)5, compare_key))->v);  
    printf("Full Tree: \n");  

    BSTree_Display(tree, printf_data, 4, '-');  

    BSTree_Delete(tree, (BSKey*)4, compare_key);  

    printf("After Delete Key 4: \n");  
    printf("Height: %d\n", BSTree_Height(tree));  
    printf("Degree: %d\n", BSTree_Degree(tree));  
    printf("Count: %d\n", BSTree_Count(tree));  
    printf("Full Tree: \n");  

    BSTree_Display(tree, printf_data, 4, '-');  

    BSTree_Clear(tree);  

    printf("After Clear: \n");  
    printf("Height: %d\n", BSTree_Height(tree));  
    printf("Degree: %d\n", BSTree_Degree(tree));  
    printf("Count: %d\n", BSTree_Count(tree));  

    BSTree_Display(tree, printf_data, 4, '-');  

    BSTree_Destroy(tree);  
    system("PAUSE");  
    return 0;  
}  

猜你喜欢

转载自blog.csdn.net/saizo123/article/details/77468133