C语言 二叉搜索树

二叉搜索树简介

二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。

简而言之, 二叉树的左子树总是比右字数小。

二叉搜索树的模拟过程可以看链接:BST

重要:在之后的关于树的算法中,我们构建的树将使用链表,而不是使用数组。所以为了实现代码,你需要先了解结构体和指针的一些内容。

实现过程

为了比较容易地理解插入排序,我们可以列出一组数据,比如:
1,5,4,3,7

这里写图片描述

个人分析

可以发现我们取出一个数后,再进行节点值的比较,如果比节点小,则这个数在值的左子树,这时候,我们在进入左子树,很显然我们相当于又是取出一个数与一个节点比较,只不过这个时候,节点变成了之前节点的左子树,所以我们可以用递归的方法构建出二叉树。

实现过程

1 首先我们需要构建一个节点的结构体

typedef struct Bi{
    int val;
    int pos;
    int height;

    struct Bi *left_child;
    struct Bi *right_child;
} Btree, *BtreePtr;

2 然后就是构建二叉树, 首先遍历每个节点放入结构体中,再将结构体插入到主结构体中


    BtreePtr b = (BtreePtr)malloc(sizeof(Btree));;
    memset(b, 0, sizeof(Btree));  //将结构体中的指针初始化
    for (int i = 0; i < length; i++) {
        BtreePtr p = (BtreePtr)malloc(sizeof(Btree));
        memset(p, 0, sizeof(Btree));
        p->val = a[i];
        p->pos = i;
        p->height = 1;

        insertTree(b, p);  //构建二叉树
    }

接下来就是插入二叉树了,这里是重点。

void insertTree(BtreePtr a, BtreePtr b) {
    //new value in b
    if ( a->height == 0) {
        *a = *b;  //不能用a = b
        free(b);
    }
    else {
        if (a->val < b->val) {
            if (a->right_child != NULL) {
                insertTree(a->right_child, b);
            }
            else {
                a->right_child = b;  //不能用 *(a-> right_child) = *b
            }
        }
        else {
            if (a->left_child != NULL) {
                insertTree(a->left_child, b);
            }
            else { 
                a->left_child = b; //不能用 *(a-> left_child) = *b
            }
        }
    }

    //节点高度
    if (a->left_child != NULL) {
        if (a->left_child->height == a->height) {
            (a->height)++;
        }
    }
    if (a->right_child != NULL) {
        if (a->right_child->height == a->height) {
            (a->height)++;
        }
    }
}

3 最后,是在二叉树中搜索,这里很简单,就不提示了。

完整代码:

#include <stdio.h>
#include <malloc.h>
#include <memory.h>

typedef struct Bi{
    int val;
    int pos;
    int height;

    struct Bi *left_child;
    struct Bi *right_child;
} Btree, *BtreePtr;

void insertTree(BtreePtr a, BtreePtr b) {
    //new value in b
    if ( a->height == 0) {
        *a = *b;  //不能用a = b, 这一步相当于将b中的所有数据都copy到a
        free(b); //之后b不需要了 ,所以需要释放b
    }
    else {
        if (a->val < b->val) {
            if (a->right_child != NULL) {
                insertTree(a->right_child, b);
            }
            else {
                a->right_child = b;  //不能用 *(a-> right_child) = *b
            }
        }
        else {
            if (a->left_child != NULL) {
                insertTree(a->left_child, b);
            }
            else { 
                a->left_child = b; //不能用 *(a-> left_child) = *b
            }
        }
    }

    if (a->left_child != NULL) {
        if (a->left_child->height == a->height) {
            (a->height)++;
        }
    }
    if (a->right_child != NULL) {
        if (a->right_child->height == a->height) {
            (a->height)++;
        }
    }
}

int midSearch(const BtreePtr a, const int key) {
    if (a != NULL) {
        if (key > a->val) {
            return midSearch(a->right_child, key);
        }
        else if(key < a->val) {
            return midSearch(a->left_child, key);
        }
        else {
            return a->pos;
        }
    }
    else {
        return -1;
    }
}

void freeTree(BtreePtr b) {
    if (b->right_child !=NULL) {
        freeTree(b->right_child);
    }
    if (b->left_child != NULL) {
        freeTree(b->left_child);
    }
}

int binaryTreeSearch(const int *a, const int length, const int key) {
    BtreePtr b = (BtreePtr)malloc(sizeof(Btree));;
    memset(b, 0, sizeof(Btree));  //将结构体中的指针初始化
    for (int i = 0; i < length; i++) {
        BtreePtr p = (BtreePtr)malloc(sizeof(Btree));
        memset(p, 0, sizeof(Btree));
        p->val = a[i];
        p->pos = i;
        p->height = 1;

        insertTree(b, p);  //构建二叉树
    }
    int pos = midSearch(b, key);
    freeTree(b); //不能直接使用free(b)
    return pos;
}


void main() {
    const int length = 5;
    int my_array[5] = { 1 ,7, 6, 8, 0 };

    printf("%d \n", binaryTreeSearch(my_array, length, 6));
}

猜你喜欢

转载自blog.csdn.net/fpk2014/article/details/80466569
今日推荐