C 实现二叉查找树

BSTree.h

/** * 二叉查找树(英语:Binary Search Tree),也称为二叉搜索树、有序二叉树(ordered binary tree)或排序二叉树(sorted binary tree) * 在二叉查找树中: * (01) 任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值; * (02) 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值; * (03) 任意节点的左、右子树也分别为二叉查找树。 * (04) 没有键值相等的节点(no duplicate nodes)。 */
#pragma once

typedef int Type;

typedef struct BSTreeNode
{
    Type key;
    struct BSTreeNode *left;
    struct BSTreeNode *right;
    struct BSTreeNode *parent;
}Node, *BSTree;


// 前序遍历二叉树(递归) 根->左->右
void PreOrder_BSTree(BSTree root);
// 中序遍历二叉树(递归) 左->根->右
void InOrder_BSTree(BSTree root);
// 后序遍历二叉树(递归) 左->右->根
void PostOrder_BSTree(BSTree root);

// 递归查找二叉树中键值为key的节点
Node* BSTree_Search(BSTree root, Type key);
// 非递归查找二叉树中键值为key的节点
Node* BSTree_Search_Non_Recursion(BSTree root, Type key);

// 查找值最大节点 
Node* BSTree_Maximum(BSTree root);
// 查找值最小节点
Node* BSTree_Minimum(BSTree root);

// 找结点(node)的后继结点。即,查找"二叉树中数据值大于该结点"的"最小结点"。
Node* BSTree_Successor(Node *node);
// 找结点(node)的前驱结点。即,查找"二叉树中数据值小于该结点"的"最大结点"。
Node* BSTree_Predecessor(Node *node);

// 将数据插入二叉查找树,并返回根节点
Node* Insert_BSTree(BSTree root, Type key);
// 删除值为key的节点,并返回根节点
Node *Delete_BSTree(BSTree root, Type key);

// 销毁二叉树
void Destory_BSTree(BSTree root);
// 打印二叉树
void Print_BSTree(BSTree node, Type key, int direction);

BSTree.c

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

// 处理二叉树节点
static void ProcessCurrNode(BSTree root)
{
    printf("%d ", root->key);
}

// 前序遍历二叉树(递归) 根->左->右
void PreOrder_BSTree(BSTree root)
{
    if (root != NULL)
    {
        // Do Something with root
        ProcessCurrNode(root);

        PreOrder_BSTree(root->left);
        PreOrder_BSTree(root->right);
    }
}

// 中序遍历二叉树(递归) 左->根->右
void InOrder_BSTree(BSTree root)
{
    if (root != NULL)
    {
        InOrder_BSTree(root->left);

        // Do Something with root
        ProcessCurrNode(root);

        InOrder_BSTree(root->right);
    }
}

// 后序遍历二叉树(递归) 左->右->根
void PostOrder_BSTree(BSTree root)
{
    if (root != NULL)
    {
        PostOrder_BSTree(root->left);
        PostOrder_BSTree(root->right);

        // Do Something with root
        ProcessCurrNode(root);
    }
}

// 递归查找二叉树中键值为key的节点
Node* BSTree_Search(BSTree root, Type key)
{
    if (root == NULL || root->key == key)
        return root;

    if (key < root->key)
        return BSTree_Search(root->left, key);
    else
        return BSTree_Search(root->right, key);
}

// 非递归查找二叉树中键值为key的节点
Node* BSTree_Search_Non_Recursion(BSTree root, Type key)
{
    while (root != NULL && root->key != key)
    {
        if (key < root->key)
            root = root->left;
        else
            root = root->right;
    }

    return root;
}

// 查找值最大节点 
Node* BSTree_Maximum(BSTree root)
{
    if (root == NULL)
        return NULL;

    while (root->right != NULL)
        root = root->right;

    return root;
}

// 查找值最小节点
Node* BSTree_Minimum(BSTree root)
{
    if (root == NULL)
        return NULL;

    while (root->left != NULL)
        root = root->left;

    return root;
}

// 找结点(node)的后继结点。即,查找"二叉树中数据值大于该结点"的"最小结点"。
Node* BSTree_Successor(Node *node)
{
    // 如果node存在右孩子,则后继节点为右孩子中的最小节点。
    if (node->right != NULL)
        return BSTree_Minimum(node->right);

    // 如果node不存在右孩子。则有两种情况: 
    // (01) node是一个左孩子,则node的后继节点为它的父节点;
    // (02) node是一个右孩子,则查找"node的最低的父结点,并且该父结点要具有左孩子",找到的这个"最低的父结点"就是"node的后继结点"。
    Node *p = node->parent;
    while (p != NULL && node == p->right)
    {
        node = p;
        p = p->parent;
    }
    return p;
}

// 找结点(node)的前驱结点。即,查找"二叉树中数据值小于该结点"的"最大结点"。
Node* BSTree_Predecessor(Node *node)
{
    // 如果node存在左孩子,则前驱节点为左孩子中的最大节点
    if (node->left != NULL)
        return BSTree_Maximum(node->left);

    // 如果node不存在左孩子,则有两种情况:
    // (01) node是一个右孩子,则node的前驱节点是的它的父节点;
    // (02) node是一个左孩子,则查找"node的最低的父结点,并且该父结点要具有右孩子",找到的这个"最低的父结点"就是"node的前驱结点"。

    Node *p = node->parent;
    while (p != NULL && node == p->left)
    {
        node = p;
        p = p->parent;
    }

    return p;
}

// 创建树节点
static Node* Create_BSTree_Node(Type key, Node *parent, Node *left, Node* right)
{
    Node *p = (Node*)malloc(sizeof(Node));
    if (p == NULL)
        return NULL;

    p->key = key;
    p->parent = parent;
    p->left = left;
    p->right = right;

    return p;
}

/** * 内部函数: * * 二叉树中插入节点 * * 参数: * root 根节点 * node 要插入的节点 * 返回值: * 根节点 */
static Node* BSTree_Insert(BSTree root, Node *insnode)
{
    Node *p = NULL;
    Node *tmp = root;

    while (tmp != NULL)
    {
        p = tmp;
        if (insnode->key < p->key)
            tmp = p->left;
        else
            tmp = p->right;
    }

    insnode->parent = p;

    // p为NULL,则root为NULL
    if (p == NULL)
        root = insnode;
    else if (insnode->key < p->key)
        p->left = insnode;
    else
        p->right = insnode;

    return root;
}

/** * 对外接口 * * 新建节点,并将其二叉树中插入节点 * * 参数: * root 根节点 * key 要插入的值 * 返回值: * 根节点 */
Node* Insert_BSTree(BSTree root, Type key)
{
    //新建节点
    Node* node = Create_BSTree_Node(key, NULL, NULL, NULL);
    if (node == NULL)
        return root;

    return BSTree_Insert(root, node);
}

/** * 内部函数: * * 二叉树中删除节点 * * 参数: * root 根节点 * node 要删除的节点 * 返回值: * 根节点 */
static Node* BSTree_Delete(BSTree root, Node *delnode)
{
    Node *p = NULL;
    Node *c = NULL;

    if (delnode->left == NULL || delnode->right == NULL)
        p = delnode;
    else
        p = BSTree_Successor(delnode);      //选择后继节点与当前节点的值互换,删除后继节点

    if (p->left != NULL)
        c = p->left;
    else
        c = p->right;

    if (c != NULL)
        c->parent = p->parent;

    if (p->parent == NULL)
        root = c;
    else if (p == p->parent->left)
        p->parent->left = c;
    else
        p->parent->right = c;

    if (p != delnode)
        delnode->key = p->key;

    if (p != NULL)
        free(p);
    p = NULL;

    return root;
}


/** * 对外接口 * * 删除节点,并返回根节点 * * 参数: * root 根节点 * key 删除的值 * 返回值: * 根节点 */
Node *Delete_BSTree(BSTree root, Type key)
{
    Node *delnode = BSTree_Search(root, key);

    if (delnode != NULL)
        root = BSTree_Delete(root, delnode);

    return root;
}

// 销毁二叉树
void Destory_BSTree(BSTree root)
{
    if (root == NULL)
        return;

    if (root->left != NULL)
        Destory_BSTree(root->left);
    if (root->right != NULL)
        Destory_BSTree(root->right);

    free(root);
}

/** * * 打印二叉树 * * 参数: * root : 二叉树节点 * key : 节点的值 * direction : 0 根节点 * -1 左孩子 * 1 右孩子 */
void Print_BSTree(BSTree node, Type key, int direction)
{
    if (node != NULL)
    {
        if (direction == 0)
            printf("%d is root\n", key);
        else
            printf("%d is %d`s %s child\n", node->key, key, direction == -1 ? "left" : "right");

        Print_BSTree(node->left, node->key, -1);
        Print_BSTree(node->right, node->key, 1);
    }
}

BSTree_Test.c

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

static int arr[] = { 1,5,4,3,2,6 };
#define TBL_SIZE(a) ( (sizeof(a)) / (sizeof(a[0])) )

void main()
{
    int i, ilen;
    BSTree root = NULL;

    printf("== 依次添加: ");
    ilen = TBL_SIZE(arr);
    for (i = 0; i < ilen; i++)
    {
        printf("%d ", arr[i]);
        root = Insert_BSTree(root, arr[i]);
    }
    printf("\n");

    printf("\n== 前序遍历: ");
    PreOrder_BSTree(root);

    printf("\n== 中序遍历: ");
    InOrder_BSTree(root);

    printf("\n== 后续遍历: ");
    PostOrder_BSTree(root);

    printf("\n\n");

    printf("== 最小值: %d\n", BSTree_Minimum(root)->key); printf("== 最大值: %d\n", BSTree_Maximum(root)->key); printf("== 树的详细信息: \n"); Print_BSTree(root, root->key, 0); printf("\n== 删除节点: %d", arr[3]); root = Delete_BSTree(root, arr[3]); printf("\n== 中序遍历: "); InOrder_BSTree(root); Destory_BSTree(root); printf("\n\n"); system("pause"); }

测试结果

《C 实现二叉查找树》

参考:http://wangkuiwu.github.io/2013/02/01/bstree-c/

    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/fuemocheng/article/details/82694786
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞