【C--step by step⑩】二叉树

又是一颗二叉树。

更容易理解的,根据树id排序的一棵树;

不厌其烦的写出了树节点删除的部分。

参考:

Java数据结构和算法-Rebort Lafore

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

/**
 * 插入生成的顺序二叉树
 * 2019-09-25
 */
#define MAX_QUEUE_SIZE 50

typedef int ElementType;

typedef struct BTreeNode{
    ElementType data;
    struct BTreeNode *leftChild, *rightChild;
}BTreeNode, *BTree;

typedef struct {
    BTree queue[MAX_QUEUE_SIZE];
    int front;
    int rear;
}Queue,*QueuePtr;

typedef enum{
    false,
    true
}bool;

bool insert(BTree *T, ElementType e)
{
    BTree root;

    if(NULL == *T)
    {
        *T = (BTree)malloc(sizeof(BTreeNode));
        if(!*T)
        {
            printf("Memory allocated Failure!\n");
            exit(-1);
        }

        (*T)->data = e;
        (*T)->leftChild = NULL;
        (*T)->rightChild = NULL;

        root = (*T);
    }
    else
    {
        root = *T;
        BTree newNode = (BTree)malloc(sizeof(BTreeNode));
        if(!newNode)
        {
            printf("Memory allocated Failure!\n");
            exit(-1);
        }
        newNode->data = e;
        newNode->leftChild = NULL;
        newNode->rightChild = NULL;

        BTree current = root;
        BTree parent;
        while(true)
        {
            parent = current;
            if(e < current->data)
            {
                current = current->leftChild;
                if(NULL == current)
                {
                    parent->leftChild = newNode;
                    return true;
                }

            }
            else
            {
                current = current->rightChild;
                if(NULL == current)
                {
                    parent->rightChild = newNode;
                    return true;
                }
            }
        }
    }
    return true;
}

/**
 * 查找待删节点的后继节点
 * @param delNode
 * @return
 */
BTree getSuccessNode(BTree delNode)
{
    BTree parent = delNode;
    BTree successor = delNode;
    BTree current = delNode->rightChild;

    while(current != NULL)
    {
        parent = successor;
        successor = current;
        current = current->leftChild;
    }

    if(successor != delNode->rightChild)
    {
        parent->leftChild = successor->rightChild;
        successor->rightChild = delNode->rightChild;
    }

    return successor;

}

bool delete(BTree *T, ElementType key)
{
    if(NULL == *T)
    {
        printf("Tree is Empty!\n");
        exit(-1);
    }

    BTree root = (*T);
    BTree current = root;
    BTree parent = root;

    bool isLeftChild = true;

    //先查找Node
    while(current->data != key)
    {
        parent = current;
        if(key < current->data)
        {
            isLeftChild = true;
            current = current->leftChild;
        }
        else
        {
            isLeftChild =false;
            current = current->rightChild;
        }
        if(NULL == current)
        {
            printf("Not Found the node of value is: %d.\n", key);
            return false;
        }
    }

    /**
     * 删除节点 一共3种情况
     */
     //1.待删除节点没有子节点
     if(current->leftChild == NULL
                && current->rightChild == NULL)
     {
         if(current == root)
         {
             root = NULL;
         }
         else if(isLeftChild)
         {
             parent->leftChild = NULL;
         }
         else
         {
             parent->rightChild = NULL;
         }
     }
     else if(current->rightChild == NULL
                 && current->leftChild != NULL)
     {
         if(current == root)
         {
             root = current->leftChild;
         }else if(isLeftChild)
         {
             parent->leftChild = current->leftChild;
         }
         else
         {
             parent->rightChild = current->leftChild;
         }
     }
     else if(current->leftChild == NULL
                && current->rightChild != NULL)
     {
         if(current == root)
         {
            root = current->rightChild;
         }else if(isLeftChild)
         {
            parent->leftChild = current->rightChild;
         }
         else
         {
            parent->rightChild = current->rightChild;
         }
     }
     else    /*待删节点有两个子节点的情况*/
     {
         //找到待删节点的后继节点
//         BTree success = getSuccessNode(&current);

         BTree delNode = current;
         BTree successorParent;
         BTree successor;    //待删节点的后继节点

         current = delNode->rightChild;

         while(current != NULL)
         {
             successorParent = successor;
             successor = current;
             current = current->leftChild;
         }

         if(successor != delNode->rightChild)
         {
             successorParent->leftChild = successor->rightChild;
             successor->rightChild = delNode->rightChild;
         }

         if(current == root)
         {
             root = successor;
         }
         else if(isLeftChild)
         {
             parent->leftChild = successor;
         }
         else
         {
             parent->rightChild = successor;
         }
         successor->leftChild = delNode->leftChild;
     }


    return true;
}


void levelOrderTraverse(BTree T)
{
    if(NULL == T)
    {
        printf("Tree is Empty!\n");
        return;
    }

    QueuePtr Q = (QueuePtr)malloc(sizeof(Queue));
    if(!Q)
    {
        printf("Memory allocate to queue failed!\n");
        exit(-1);
    }

    BTree temp;

    //1.初始化,树根节点入队
    Q->front =0;
    Q->rear =0;
    Q->queue[Q->rear++] = T;

    //2.队列不为空
    while(Q->front != Q->rear)
    {
        temp = Q->queue[(Q->front++)%MAX_QUEUE_SIZE];
        printf("%d ", temp->data);
        if(temp->leftChild)
        {
            if((Q->rear+1)%MAX_QUEUE_SIZE == Q->rear)
            {
                printf("队列满!\n");
                exit(-1);
            }
            Q->queue[(Q->rear++)%MAX_QUEUE_SIZE] = temp->leftChild;
        }
        if(temp->rightChild)
        {
            if((Q->rear+1)%MAX_QUEUE_SIZE == Q->rear)
            {
                printf("队列满!\n");
                exit(-1);
            }
            Q->queue[(Q->rear++)%MAX_QUEUE_SIZE] = temp->rightChild;
        }
    }

}

bool find(BTree T, ElementType key)
{

    if(NULL == T)
    {
        printf("Tree is Empty!\n");
        return false;
    }
    BTree root = T;
    BTree current = root;

    while(current->data != key)
    {
        if(NULL == current)
        {
            printf("Not Found the Node of value:%d.\n", key);
            return false;
        }
        if(key < current->data)
        {
            current = current->leftChild;
        }
        else
        {
            current = current->rightChild;
        }
    }

    printf("the Node %d of address is %p !\n", key, current);

    return true;
}

void traverse(BTree T)
{
    levelOrderTraverse(T);
}

int main() {
    BTree T = NULL;
    printf("生成二叉树======\n");
    insert(&T, 50);
    insert(&T, 75);
    insert(&T, 62);
    insert(&T, 87);
    insert(&T, 77);
    insert(&T, 93);
    insert(&T, 79);

//    find(T, 30);
    printf("打印二叉树=====\n");
    traverse(T);

    printf("\n删除节点75=====\n");
    delete(&T, 75);

    printf("打印二叉树=====\n");
    traverse(T);
    printf("\ndone!\n");
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值