因为痛,所以叫青春

我有一个梦想:穷屌丝变身富屌丝
二叉树查找、删除、遍历、销毁、结点的统计、深度计算、广度优先遍历、非递归先、中、后序遍历

二叉树结点的查找跟遍历是很容易实现的,但是要想实现二叉树结点的删除,确实是一项很费事的工作

下面我只介绍二叉树结点的删除。删除二叉树的结点,会遇到三种情况

被删除的结点没有子树。这种情况最容易操作,直接找到该结点,然后让它的父结点指向它的指针为空,然后释放该结点即可

被删除的结点只有一个子树。找到该结点,让其父结点指向它的子树,然后释放该结点

被删除的结点同时拥有左右子树。此处我拿顺序二叉树为例,找到该结点,然后找到该结点右子树的最左的子结点,让该子结点的父结点指向空,再让该结点的父结点指向该子结点,然后释放该结点(此处我提供一个小技巧,我们可以将该子结点复制给该结点,然后让该子结点的父结点指向空,然后释放该子结点)!如果该子结点还有右子树,那么直接将该子结点的父结点的左子树指向该子结点的右子树。

 

说的有点绕口,慢慢理解吧

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

//二叉树结点的结构体定义

typedef struct tree
{
    int num;
    struct tree *prve;//此处为前驱指针,该指针的目的是为了方便找到父结点
    struct tree *left;
    struct tree *right;
}Tree;

//初始化二叉树

void Init_Tree(Tree *Root)
{
    Root->prve = NULL;
    Root->left = NULL;
    Root->right = NULL;
}

//插入结点

void Insert_Node(Tree *Root, int key)
{
    if(Root->num >= key){
        if(Root->left == NULL){
            Tree *node = (Tree *)malloc(sizeof(Tree));
            node->prve = node->left = node->right = NULL;
            node->num = key;
            Root->left = node;
            node->prve = Root;
        }
        else Insert_Node(Root->left,key);
    }
    else{
        if(Root->right == NULL){
            Tree *node = (Tree *)malloc(sizeof(Tree));
            node->prve = node->left = node->right = NULL;
            node->num = key;
            Root->right = node;
            node->prve = Root;
        }
        else Insert_Node(Root->right,key);

    }
}

//查找结点

Tree *Search_Node(Tree *Root,int key)
{
    if(Root == NULL) return NULL;
    if(Root->num == key)
        return Root;
    else if(Search_Node(Root->left,key) != NULL)
        return Search_Node(Root->left,key);
    else if(Search_Node(Root->right,key) != NULL)
        return Search_Node(Root->right,key);
    else return NULL;
}

//查找结点版本2
Tree *Search_Node2(Tree *Root, int key)
{
    if(Root == NULL)return NULL;
    if(Root->num == key)
        return Root;
    if(Root->num > key) return Search_Node2(Root->left,key);
    else return Search_Node2(Root->right,key);
}


//删除结点

void Del_Node(Tree *Root)
{
    if(Root->left == NULL && Root->right == NULL)
    {
        if(Root->prve->left == Root)
            Root->prve->left = NULL;
        else Root->prve->right = NULL;
        free(Root);
    }
    else if(Root->left == NULL)
    {
        if(Root->prve->left == Root)
            Root->prve->left = Root->right;
        else Root->prve->right = Root->right;
        free(Root);
    }
    else if(Root->right == NULL)
    {
        if(Root->prve->left == Root)
            Root->prve->left = Root->left;
        else Root->prve->right = Root->left;
        free(Root);
    }
    else{
        Tree *temp = Root->right;
        while(temp->left){
            temp = temp->left;
        }
        if(temp->right == NULL){
            temp->prve->left = NULL;
            *Root = *temp;
            free(temp);
        }
        else {
            temp->prve->left = temp->right;
            *Root = *temp;
            free(temp);
        }
    }
}

//中序遍历二叉树

void Travel_Tree(Tree *Root)
{
    if(Root == NULL) return ;
    Travel_Tree(Root->left);
    printf("point:%d  \n ",Root->num);
    Travel_Tree(Root->right);
}

// 广度优先搜索

void Level_Tree(Tree *Root)
{
    Tree *flag[100];
    int top = 0, down = 0;
    flag[top++] = Root;
    while(top-down)
    {
        printf("point: %d\n",flag[down++]->num);
        if(flag[down-1]->left)
            flag[top++] = flag[down-1]->left;
        if(flag[down-1]->right)
            flag[top++] = flag[down-1]->right;
    }
}

//非递归先序遍历二叉树

void First_Tree(Tree *Root)
{
    Tree *flag[100], *temp;
    int top = 0;
    flag[top++] = Root;
    while(top)
    {
        temp = flag[top-1];
        printf("point: %d\n",flag[--top]->num);
        if(temp->right) flag[top++] = temp->right;
        if(temp->left) flag[top++] = temp->left;
    }
}

//非递归中序遍历二叉树

void Mid_Tree(Tree *Root)
{
    Tree *flag[100], *temp;
    int top = 0;
    temp = Root;
    while(top || temp)
    {
        if(temp){
            flag[top++] = temp;
            temp = temp->left;
        }else {
            temp = flag[--top];
            printf("point: %d\n",temp->num);
            temp = temp->right;
        }
    }
}

//非递归后序遍历二叉树

void Last_Tree(Tree *Root)
{
    Tree *flag[100], *p, *q;
    int top = 0;
    p = Root->left; q = NULL;
    flag[top++] = Root;
    while(top)
    {
        if(p){
            flag[top++] = p;
            p = p->left;
        } else{
            p = flag[top-1];
            if(p->right == NULL || p->right == q){
                printf("point: %d\n",p->num);
                top--;
                q = p;
                p = NULL;
            } else p = p->right;
        }
    }
}

//销毁二叉树

void Destory_Tree(Tree *Root)
{
    if(Root == NULL) return;

    Destory_Tree(Root->right);
    Destory_Tree(Root->left);

    printf("%d over!\n", Root->num);
    free(Root);
    return ;
}

//求树的深度

int Deep_Tree(Tree *Root)
{
    if(Root == NULL) return 0;
    
    return 1+(Deep_Tree(Root->left) > Deep_Tree(Root->right)?Deep_Tree(Root->left):Deep_Tree(Root->right));
}

//统计结点

int Count_Tree(Tree *Root)
{
    if(Root == NULL) return 0;
    return (1 + Deep_Tree(Root->left) + Deep_Tree(Root->right));
}

//删除的结点为根结点

void Del_Root(Tree *Root)
{
    if(Root->left == NULL && Root->right == NULL) Root = NULL;
    else if(Root->left == NULL) *Root = *(Root->right);
    else if(Root->right == NULL) *Root = *(Root->left);
    else{
        Tree *p = Root->right;
        while(p->left) p = p->left;
            if(p->prve == Root){
                Tree *q = Root->left;
                *Root = *p;
                free(p);
                Root->left = q;
            }
            else{
                Tree *q1, *q2;
                q1 = Root->left;
                q2 = Root->right;
                *Root = *p;
                if(p->right)
                p->prve = p->right;
                else p->prve = NULL;
                free(p);
                Root->left = q1;
                Root->right = q2;
            }
    }
}
int main()
{
    int i, key;
    Tree *Root, *temp;
    Root = (Tree *)malloc(sizeof(Tree));
    Init_Tree(Root);

    scanf("%d",&Root->num);

    for(i = 1;i < 10; i++)
    {
        scanf("%d",&key);
        Insert_Node(Root,key);
    }

    Travel_Tree(Root);

//    printf("\n深度为:%d\n总结点数:%d\n",Deep_Tree(Root),Count_Tree(Root));

    printf("请输入您要删除的结点:\n");
    scanf("%d",&key);
    temp = Search_Node(Root,key);
    if(temp != Root) Del_Node(temp);
    else Del_Root(Root); 

//    Level_Tree(Root);

    Travel_Tree(Root);
    printf("\n");
/*
    First_Tree(Root);

    Mid_Tree(Root);

    Last_Tree(Root);

    Destory_Tree(Root);
*/
    return 0;
}
View Code

 

posted on 2014-07-25 09:22  Nice!  阅读(1809)  评论(0编辑  收藏  举报