c语言实现 排序二叉树(码了小半天,中午吃了个火锅,晚上骑了趟太湖,居然一次调通了= =)

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


typedef struct node{
struct node *parent;
struct node *left_child;
struct node *right_child;
int data;
}NODE;//节点结构体,也是一片树叶


NODE *result;//全局变量,用于查找树中的某个数据时保存此节点

NODE *make_node(NODE *parent,NODE *left_child,NODE *right_child,int data)//创造一个节点,创造一片叶子
{
    NODE *new_node = (NODE *)malloc(sizeof(NODE));
    new_node->parent = parent;
    new_node->left_child = left_child;
    new_node->right_child = right_child;
    new_node->data = data;
    return new_node;
};


NODE *plant_tree(NODE *root,int data)//种植一棵树
{
  root->data = data;
  return root;
}


void grow_leaf(NODE *root,int data)//生长一片叶子,即存入一个数据
{
    if(root->data > data)//数据小于节点数据,放入左子树
    {   
        if(root->left_child == NULL)
           root->left_child = make_node(root,NULL,NULL,data);
        else
            grow_leaf(root->left_child,data);//递归调用
    }
    else
    {   
        if(root->right_child == NULL)
           root->right_child = make_node(root,NULL,NULL,data);
        else
            grow_leaf(root->right_child,data);
    }
}


void pre_order_travel(NODE *root)//前序遍历,即MLR
{
    if(root)
    {
    printf("data = %d\n",root->data);
    pre_order_travel(root->left_child);
    pre_order_travel(root->right_child);
    }
}

void mid_order_travel(NODE *root)//中序遍历,即LMR,这个可以实现从小到大排序
{
    if(root)
    {
    mid_order_travel(root->left_child);
    printf("data = %d\n",root->data);
    mid_order_travel(root->right_child);
    }
}


void empty_last_result()//清空全局变量里面存的结果,便于下次查找
{
    result = NULL;
}


NODE *search_tree(NODE *root,int data)//从树里查找一个数据,返回这个节点,如果要删除,便于删除
{
    empty_last_result();
    search(root,data);
    return result;
}


void search(NODE *root,int data)//递归查询
{
    if(root)
    {
        if(data == root->data)
            {
                printf("data found in one_leaf\n");
                result = root;
            }
        search(root->left_child,data);
        search(root->right_child,data);
    }
}
NODE * find_most_right(NODE *leaf)//寻找最右节点,便于删除时用,在剪叶子时候用
{  
    NODE *most_right;
    if(leaf->right_child==NULL)
       return leaf;
    most_right=find_most_right(leaf->right_child);
    return most_right;
}

void cut_leaf(NODE *root,int data)//修剪枝桠,即删除一个数据,要对树做相应处理,有点麻烦,算法看百度百科

    NODE *one_leaf,*temp_leaf;
    if(one_leaf=search_tree(root,data))
    {
       if(one_leaf->left_child == NULL && one_leaf->right_child == NULL)
        {
            if(one_leaf==one_leaf->parent->left_child)
                    one_leaf->parent->left_child = NULL;
            else
                one_leaf->parent->right_child = NULL;
        }
        else if(one_leaf->left_child == NULL || one_leaf->right_child  == NULL)
        {
            if(one_leaf->left_child == NULL)
                {
                    if(one_leaf==one_leaf->parent->left_child)
                        one_leaf->parent->left_child = one_leaf->right_child;
                    else
                        one_leaf->parent->right_child = one_leaf->right_child;
                }
            else
                {
                    if(one_leaf==one_leaf->parent->left_child)
                        one_leaf->parent->left_child = one_leaf->left_child;
                    else
                        one_leaf->parent->right_child = one_leaf->left_child;
                }
       
       
        }
        else
        {
            if(one_leaf==one_leaf->parent->left_child)
                one_leaf->parent->left_child = one_leaf->left_child;
            else
                one_leaf->parent->right_child = one_leaf->left_child;
            temp_leaf = find_most_right(one_leaf->left_child);
            temp_leaf->right_child = one_leaf->right_child;
        }
        free(one_leaf);
    }

    else
        printf("no such leaf in this tree");
}

 

int main(void)//来,测试一下,x86的gcc通过
{
    NODE *root,*one_leaf;
    root = make_node(NULL,NULL,NULL,0);
    plant_tree(root,5);
    grow_leaf(root,1);
    grow_leaf(root,2);
    grow_leaf(root,7);
    grow_leaf(root,8);
    pre_order_travel(root);
    one_leaf=search_tree(root,2);
    cut_leaf(root,7);
    pre_order_travel(root);
    mid_order_travel(root);

   return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值