二叉树

二叉树**

二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒

这里写图片描述

因为有左右之分, 所以在创建链表的时候, 应该创建两个分支, 左分支和右分支

struct Node;
typedef struct Node *T;

struct Node
{
    int num;
    T Left;
    T High;
};

在创建链表,应该对其初始化, 注意, 左右分支都应该初始为 NULL

//链表初始化
void Creat(T &node, int inset)
{
    if (node == NULL)
    {
        node = (T)malloc(sizeof(struct Node));
        if (node == NULL)
            exit(0);
        node->num = inset;
        node->Left = node->High = NULL;
    }
}

插入数据, 使用递归, 将大于节点的放在节点右侧, 小于放在左侧,

//直到递归的一端为NULL, 才进入Create 进行初始化赋值
T Insert(T node, int insert)
{
    if (node == NULL)
        Create(node, insert);
    else
        if (node->num > insert)
            node->Left = Insert(node->Left, insert);
        else if (node->num < insert)
            node->High = Insert(node->High, insert);

    return node;
}

因为一直将小于节点的数放在左侧, 大于的放在右侧, 所以最小的一定在节点左侧, 最大一定在节点右侧

//查找最小值
T FindMin(T node)
{
    if (node == NULL)
        exit(0);

    while (node->Left != NULL)
        node = node->Left;

    return node;
}

//查找最大值
T FindMax(T node)
{
    if (node == NULL)
        exit(0);

    while (node->High != NULL)
        node = node->High;

    return node;
}

查找二叉树的数, 根据与节点的大小来进行左或右的选择, 与插入类似的方法

T Find(T node, int find)
{
    if (node == NULL)
        exit(0);

    else
        if (node->num > find)
            Find(node->Left, find);
        else if (node->num < find)
            Find(node->High, find);
        else
            return node;
}

这里写图片描述

删除二叉树中的数相对来说要麻烦一点, 有两种可能,
第一种 : 当删除叶, 只需要把叶赋值为NULL, 即删除
第二种 : 当删除节点, 如, 删除6, 需要保证二叉树的特性不变, 即右边大于节点, 左边小于节点, 就需要找到这样能保证特性不变的数来代替删除的节点, 很容易的在图中能找到, 就是8, 所以只需要用8代替6就行了, 要找到8就需要找到6节点右边的最小数, 就可用Fin_Min(node->Right)即可找到

//删除二叉树中的一个数
T Dele(T node, int dele)
{
    T temp = NULL;

    if (node == NULL)
        exit(0);

    else
        if (node->num > dele)
            node->Left = Dele(node->Left, dele);
        else if (node->num < dele)
            node->High = Dele(node->High, dele);
        //第二种
        else if (node->High && node->Left)
        {
            //temp就是节点右边最小的值
            temp = FindMin(node->High);
            node->num = temp->num;
            //找到之后我们应该删除代替的8, 因为8已经变成节点了
            Dele(node->High, temp->num);
        }
        //第一种
        else
        {
            if (node->High != NULL)
                node = node->Left;
            else
                node = node->High;

            free(temp);
        }
    return node;
}

二叉树的遍历有三种:
1. 前序遍历
2. 中序遍历
3. 后序遍历

前序遍历

int Print(T node)
{
    if (node != NULL)
    {
        printf("%d ", node->num);
        Print(node->Left);
        Print(node->High);
    }
    return 0;
}

中序遍历

int Print(T node)
{
    if (node != NULL)
    {
        Print(node->Left);
        printf("%d ", node->num);
        Print(node->High);
    }
    return 0;
}

后序遍历

int Print(T node)
{
    if (node != NULL)
    {
        Print(node->Left);
        Print(node->High);
        printf("%d ", node->num);
    }
    return 0;
}

源代码

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

struct Node;
typedef struct Node *T;
const int N = 9;

struct Node
{
    int num;
    T Left;
    T High;
};

//链表初始化
void Create(T &node, int inset)
{
    if (node == NULL)
    {
        node = (T)malloc(sizeof(struct Node));
        if (node == NULL)
            exit(0);
        node->num = inset;
        node->Left = node->High = NULL;
    }
}

//插入数据, 使用递归, 将大于节点的放在节点右侧, 小于放在左侧,
//直到递归的一端为NULL, 才进入Create 进行初始化赋值
T Insert(T node, int insert)
{
    if (node == NULL)
        Create(node, insert);
    else
        if (node->num > insert)
            node->Left = Insert(node->Left, insert);
        else if (node->num < insert)
            node->High = Insert(node->High, insert);

    return node;
}

//查找最小值
T FindMin(T node)
{
    if (node == NULL)
        exit(0);

    while (node->Left != NULL)
        node = node->Left;

    return node;
}

//查找最大值
T FindMax(T node)
{
    if (node == NULL)
        exit(0);

    while (node->High != NULL)
        node = node->High;

    return node;
}

//查找某一个数
T Find(T node, int find)
{
    if (node == NULL)
        exit(0);

    else
        if (node->num > find)
            Find(node->Left, find);
        else if (node->num < find)
            Find(node->High, find);
        else
            return node;
}


//删除二叉树中的一个数
T Dele(T node, int dele)
{
    T temp = NULL;

    if (node == NULL)
        exit(0);

    else
        if (node->num > dele)
            node->Left = Dele(node->Left, dele);
        else if (node->num < dele)
            node->High = Dele(node->High, dele);
        else if (node->High && node->Left)
        {
            temp = FindMin(node->High);
            node->num = temp->num;
            Dele(node->High, temp->num);
        }
        else
        {
            if (node->High != NULL)
                node = node->Left;
            else
                node = node->High;

            free(temp);
        }
    return node;
}

int Print(T node)
{
    if (node != NULL)
    {
        printf("%d ", node->num);
        Print(node->Left);
        Print(node->High);
    }
    return 0;
}


int main()
{
    int a[N] = { 4,2,5,1,7,6,9,8, 3 };
    T node = NULL;
    for (int i = 0; i < N; i++)
        node = Insert(node, a[i]);

    T temp = Find(node, 2);
    printf("%d\n", temp->num);

    temp = node;
    Dele(temp, 7);

    Print(node);

    system("pause");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值