二叉查找树 ADT

二叉树是每个节点最多有两个子树的数结构,即左子树、右子树。二叉树的第i层至多有2^(i-1)个节点,深度为k的二叉树至多有(2^k) - 1个节点。

二叉查找树:对于树中的每个节点X,他的左子树中所有关键字值小于X的关键字值,而它的右子树中所有关键字值大于X的关键字值。

二叉搜索树可以方便的实现搜索算法。在搜索元素x的时候,我们可以将x和根节点比较:

  1. 如果x等于根节点,那么找到x,停止搜索 (终止条件)

  2. 如果x小于根节点,那么搜索左子树

  3. 如果x大于根节点,那么搜索右子树

二叉搜索树所需要进行的操作次数最多与树的深度相等。n个节点的二叉搜索树的深度最多为n,最少为log(n)。

二叉树的基本操作:

/*二叉树的一些基本操作*/

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

typedef struct node *position;
typedef int ElementType;

struct node     //定义树节点
{
    position parent;
    ElementType element;
    position lchild;
    position rchild;
};

typedef struct node *TREE;

void print_sorted_tree(TREE);  //打印树
position find_min(TREE);  //寻找最小元素
position find_max(TREE);  //寻找最大元素
position fina_value(TREE, ElementType);  //寻找指定元素
position insert_value(TREE, ElementType);  //插入一个指定元素
ElementType delete_node(position);  //删除节点

static int is_root(position); //判断是否是根节点
static int is_leaf(position);  //判断是否是树叶
static ElementType delete_leaf(position); //删除叶节点
static void insert_node_to_nonempty_tree(TREE, position); //插入节点

int main()
{
    TREE tree;
    position np;
    ElementType element;
    tree = NULL;
    int a[] = {18, 5, 2, 8, 81, 101};
    for(int i = 0; i < 6; i++)
        tree = insert_value(tree, a[i]);
    printf("Original tree: \n");
    print_sorted_tree(tree);

    np = fina_value(tree, 81);
    if (np != NULL)
    {
        delete_node(np);
        printf("\nAfter deletion:\n");
        print_sorted_tree(tree);
    }


    system("pause");
    return 0;
}


void print_sorted_tree(TREE tr)
{
    if(tr == NULL)
        return;
    print_sorted_tree(tr->lchild);
    printf("%d \n", tr->element);
    print_sorted_tree(tr->rchild);
}

position find_min(TREE tr)
{
    position np;
    np = tr;
    if( np == NULL)
        return NULL;
    while (np ->lchild != NULL)
    {
        np = np->lchild;
    }
    return np;
}

position find_max(TREE tr)
{
    position np;
    np = tr;
    if(np == NULL)
        return NULL;
    while(np->rchild != NULL)
        np = np->rchild;
    return np;
}


position fina_value(TREE tr, ElementType value)
{
    if(tr == NULL)
        return NULL;
    if ( tr->element == value)
    {
        return tr;
    }
    else if(value < tr->element)
        return fina_value(tr->lchild, value);
    else 
        return fina_value(tr->rchild, value);
}

ElementType delete_node(position np)
{
    position replace;
    ElementType element;
    if(is_leaf(np))
        return delete_leaf(np);
    else
    {
        replace = (np->lchild!= NULL)? find_max(np->lchild) : find_min(np->rchild);
        element = np->element;
        np->element = delete_node(replace);
        return element;
    }
}

position insert_value(TREE tr, ElementType value)
{
    position np;
    np = (position) malloc(sizeof (struct node));
    np->element = value;
    np->parent = NULL;
    np->rchild = NULL;
    np->lchild = NULL;

    if(tr == NULL) 
        tr = np;
    else 
        insert_node_to_nonempty_tree(tr, np);
    return tr;
}

static int is_root(position np)
{
    return (np->parent == NULL);
}

static int is_leaf(position np)
{
    return (np->lchild == NULL && np->rchild == NULL);
}

static ElementType delete_leaf(position np)
{
    ElementType element;
    position parent;
    element = np->element;
    parent = np->parent;
    if (!is_root(np))
    {
        if(parent->lchild == np)
            parent->lchild =NULL;
        else 
            parent->rchild = NULL;

    }

    free(np);
    return element;
}

static void insert_node_to_nonempty_tree(TREE tr, position np)
{
    if ( np->element <= tr->element)
    {
        if (tr->lchild == NULL)
        {
            tr->lchild = np;
            np->parent = tr;
            return;
        }
        else insert_node_to_nonempty_tree(tr->lchild, np);
    }
    else if (np->element > tr->element)
    {
        if (tr->rchild == NULL)
        {
            tr->rchild = np;
            np->parent = tr;
            return;
        }
        else 
            insert_node_to_nonempty_tree(tr->rchild, np);
    }

}

这里写图片描述

参考:树及二叉树
二叉树维基百科

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值