数据结构-二叉排序树

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zwx19921215/article/details/83307021

二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;
(3)左、右子树也分别为二叉排序树;

根据二叉树的定义,左子树节点值<根节点值<右子树节点值。所以对二叉排序树进行中序遍历,可以得到一个递增的有序序列。
如图,中序遍历的结果为:123468

二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;
(3)左、右子树也分别为二叉排序树;

根据二叉树的定义,左子树节点值<根节点值<右子树节点值。所以对二叉排序树进行中序遍历,可以得到一个递增的有序序列。
如图,中序遍历的结果为:123468
二叉排序树的查找:
二叉排序树的查找是从根节点开始,沿着某一个分支逐层向下进行比较的过程。若二叉排序树非空,将给定值与根节点的关键字比较,若相等,则查找成功;
若不等,则当根节点的关键字大于给定关键字值时,在根节点的左子树查找,否则在跟几点的右子树中查找。依次递归查找。
如上图,比如查找值为4的节点,则先与根节点6比较,因为4小于6,所以在根节点的左子树中继续查找,又因为4大于2,所以在节点2的右子树中查找,直至查找成功。
二叉排序树的插入:
插入节点的过程:若原二叉排序树为空,则直接插入节点;否则,若关键字k小于根节点的关键字,则插入到
左子树中,若关键字k大于根节点的关键字,则插入到右子树中。

//
// Created by Administrator on 2018/6/7.
//
/**
 * 二叉排序树
 */

#include "stdio.h"
#include "stdlib.h"
#include "string.h"

/**
 * 定义一棵二叉排序树
 */
#define ElementType char
typedef struct {
    ElementType data;
    struct BitSTNode *lchild, *rchild;
} BitSTNode, *BitSTree;

/**
 * 先序遍历创建一棵二叉树排序树
 * @param tree
 * @return
 */
BitSTree createTree(BitSTree tree) {
    ElementType c;
    scanf("%c", &c);
    if (c == '#') {
        return -1;
    } else {
        tree = (BitSTree) malloc(sizeof(BitSTNode));
        tree->data = c;
        tree->lchild = createTree(tree->lchild);
        tree->rchild = createTree(tree->rchild);
    }
    return tree;
}

/**
 * 在二叉排序树中插入一个关键字为k的节点
 * @param tree 二叉排序树
 * @param k 需要拆入的节点元素
 * @return
 */
BitSTree insert(BitSTree tree, ElementType k) {
    if (tree == NULL) {
        //原树节点为空,将新节点插入其中
        tree = (BitSTree) malloc(sizeof(BitSTNode));
        tree->data = k;
        tree->lchild = tree->rchild = NULL;
        printf("节点%c插入成功~\n", k);
        return tree;
    } else if (k == tree->data) {
        //原树中已存在节点k,舍弃
        printf("原树中已存在节点k\n");
        return tree;
    } else if (k > tree->data) {
        //节点k的值小于树中此节点的值即k应该插入到右子树
        tree->rchild = insert(tree->rchild, k);
    } else {
        //节点k的值大于树中此节点的值即k应该插入到左子树
        tree->lchild = insert(tree->lchild, k);
    }
    return tree;
}

/**
 * 创建一棵二叉排序树
 * @param tree
 * @param str
 * @param n
 */
BitSTree createBSortTree(BitSTree *tree, ElementType str[], int n) {
    //用关键字数组str[]建立一个二叉排序树
    tree = NULL;
    for (int i = 0; i < n; i++) {
        tree = insert(tree, str[i]);
    }
    return tree;
}

/**
 * 二叉排序树非递归查找
 * @param T 树
 * @param key 需要查找的value
 * @return
 */
BitSTree search(BitSTree T, ElementType key) {
    while (T && T->data != key) {
        if (key < T->data) {
            T = T->lchild;
        } else {
            T = T->rchild;
        }
    }
    return T;
}

/**
 * 二叉排序树递归查找
 * @param T
 * @param key
 */
void recuSearch(BitSTree T, ElementType key) {
    if (T) {
        if (key == T->data) {
            printf("二叉树tree中已找到%c的位置\n", T->data);
            return;
        }
        if (key < T->data) {
            recuSearch(T->lchild, key);
        } else {
            recuSearch(T->rchild, key);
        }
    } else {
        printf("二叉树tree中未找到%c的位置\n", key);
    }
}

int main() {
    BitSTree tree;
    //加个'\0'表示结尾,否则长度并不是实际长度
    char str[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', '\0'};
    int len = strlen(str);
    tree = createBSortTree(tree, str, len);
//    tree = createTree(tree);
    char D = 'D';
    char M = 'M';
    printf("二叉排序树非递归查找:\n");
    BitSTree locTree = search(tree, 'D');
    if (locTree) {
        printf("二叉树tree中已找到%c的位置\n", locTree->data);
    } else {
        printf("二叉树tree中未找到%c的位置\n", D);
    }
    locTree = search(tree, 'M');
    if (locTree) {
        printf("二叉树tree中已找到%c的位置\n", locTree->data);
    } else {
        printf("二叉树tree中未找到%c的位置\n", M);
    }
    printf("二叉排序树递归查找:\n");
    recuSearch(tree, D);
    recuSearch(tree, M);
}

猜你喜欢

转载自blog.csdn.net/zwx19921215/article/details/83307021