首页 新闻 会员 周边

关于C语言实现二叉排序树,删除后节点后,原来节点存在且出现垃圾数字的问题

0
悬赏园豆:100 [已关闭问题] 关闭于 2019-03-23 22:45
// 二叉搜索树,以特定的规则来进行构建
// 1,所有节点中,该节点的左子树中的节点的键值 =< 该节点,右子树中节点的键值 >= 该节点.
// 2,当进行一次中序遍历,则会得到升序排列

#include <stdio.h>
#include <stdlib.h>
struct Node{
    int key;
    Node *parent, *left, *right;
};

Node *root, *NIL;


void insert_node(int k){
    //插入节点,构建搜索树
    Node *z;
    z = (Node *)malloc(sizeof(Node));
    z -> key = k;
    z -> left = NIL;
    z -> right = NIL;
    Node *x = root;
    Node *y = NIL;

    while(x != NIL){             //寻找适当节点插入
        y = x;
        if(z->key < x->key){
            x = x -> left;
        }else{
            x = x -> right;
        }
    }

    z -> parent = y;
    if(y == NIL){   //如果是null则为头节点
        root = z;
    }else{
        if(z -> key < y -> key){
            y -> left = z;
        }else{
            y -> right = z;
        }
    }
}

Node* search_node(int k, Node *node)
{
    // 搜索指定元素
    while(node != NIL && node -> key != k){
        if(node -> key < k){
            node = node -> right;
        }else{
            node = node -> left;
        }
    }
    return node;
}

Node* treeMinimum(Node * node)
{
    while(node->left != NIL){
        node = node -> left;                   
    } 
    return node;
}

Node* get_next_node(Node *node)
{
    //获取中序遍历的下一个节点
    if(node -> right != NIL){
        // 如果该结点有右子节点,则找该右子节点最左侧的节点
        return treeMinimum(node -> right);
    }
    Node *y = node -> parent; //不存在右节点时,下一个节点就是,以左子节点身份出现的父节点
    while(y != NIL && y -> right == node){
        node = y;
        y = y -> parent;
    }
    return y;
}
void delete_node(Node *node)
{
    Node *y; //要删除的对象
    Node *x; //y的子节点

    //确定要删除的节点
    if(node -> right == NIL || node -> left == NIL){
        y = node;
    }else{
        y = get_next_node(node);
    }

    // 确定y的子节点
    if(y -> left != NIL){
        x = y -> left;
    }else{
        x = y -> right;
    }

    if(x != NIL){
        x -> parent = y -> parent;
    }

    if (y -> parent == NIL){
        root = x;
    }else{
        if(y == y -> parent -> left){
            y -> parent -> left = x;
        }else{
            y -> parent -> right = x;
        }
    }

    if(y != node){
        node -> key = y -> key;
    }
    free(y);
}

void norder_traversal(Node* node)
{
    // 中序遍历
    if(node == NIL){
        return;
    }
    norder_traversal(node -> left);
    printf("%d ", node -> key);
    norder_traversal(node -> right);
}

void preorder_traversal(Node* node)
{
    // 前序遍历
    if(node == NIL){
        return;
    }
    printf("%d ", node -> key);
    preorder_traversal(node -> left);
    preorder_traversal(node -> right);
}

void postorder_traversal(Node* node)
{
    // 后续遍历
    if(node == NIL){
        return;
    }
    postorder_traversal(node -> left);
    postorder_traversal(node -> right);
    printf("%d ", node -> key);
}



int main(int argc, char const *argv[])
{
    int n,element;
    scanf("%d", &n);
    for(int i = 0; i < n; i++){
        scanf("%d", &element);
        insert_node(element);
    }
    printf("前序遍历: ");
    preorder_traversal(root);
    printf("\n中序遍历:");
    norder_traversal(root);
    printf("\n后续遍历:");
    postorder_traversal(root);
    printf("\n");
    Node *node = search_node(22, root);
    printf("=======%d=========\n", node -> key);
    if(node != NIL){
        delete(node);
    }else{
        printf("no\n");
    }
    printf("删除节点后:\n前序遍历: ");
    preorder_traversal(root);
    printf("\n中序遍历:");
    norder_traversal(root);
    printf("\n后续遍历:");
    postorder_traversal(root);
    printf("\n");
    return 0;
}
/*
测试数据
7
22 20 15 21 50 49 51
*/
输出结果为:
7
22 20 15 21 50 49 51
前序遍历: 22 20 15 21 50 49 51 
中序遍历:15 20 21 22 49 50 51 
后续遍历:15 21 20 49 51 50 22 
=======22=========
删除节点后:
前序遍历: 0 20 15 21 50 49 51 
中序遍历:15 20 21 0 49 50 51 
后续遍历:15 21 20 49 51 50 0 

为什么之前被删除的节点还存在,并且是0,很奇怪的是,在其他的机子上是垃圾数字。。。。

c
没尾巴的刺刺鱼的主页 没尾巴的刺刺鱼 | 菜鸟二级 | 园豆:204
提问于:2019-03-23 22:32
< >
分享
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册