二叉树的基本操作(增、删、改、查) C/C++

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MaxSize 1024

typedef int TElemType;

typedef struct BstNode
{
    TElemType data;//数据域
    BstNode *Left;//指针域
    BstNode *Right;

}BstNode;

/*创建节点*/
BstNode* CreatBstNode(TElemType data)
{
    BstNode* root = (BstNode *)malloc(sizeof(*root) );
    root->data  = data;
    root->Left  = NULL;
    root->Right = NULL;

    return root;
}

/*在以为root为根的平衡二叉树中插入一个值为x的结点*/
int AddBstNodeToTree(BstNode* root, const TElemType data)
{
    BstNode* p = root;
    BstNode* pnew = CreatBstNode(data);

    while (1)
    {
        if ((pnew->data) > (p->data))
        {
            if (NULL == p->Right)
            {
                p->Right = pnew;
                break;
            }
            p = p->Right;
        }
        else if ((pnew->data) < (p->data))
        {
            if (NULL == p->Left)
            {
                p->Left = pnew;
                break;
            }
            p = p->Left;
        }
        else
        {
            printf("Input Error!\n");
            free(pnew);
            return 1;
        }
    }

    return 0;
}

//找到父节点
BstNode* FindFather(BstNode* root, const TElemType key, int& pos)
{
    BstNode* p = root;
    BstNode* backfather = p;
    pos = 0;

    while (p)
    {
        if (key == p->data)
        {
            return backfather;
        }
        else if (key < p->data)
        {
            backfather = p;
            p = p->Left;
            pos = -1;
        }
        else if (p->data < key)
        {
            backfather = p;
            p = p->Right;
            pos = 1;
        }
    }

    return NULL;
}

/*删除节点*/
BstNode* DeleteBstNode(BstNode* &root, const TElemType key)
{
    int pos;
    BstNode *backfather;//父结点指针
    BstNode *ptr;//删除结点指针
    BstNode *next;//子结点指针
    BstNode **fap;//父节点指向删除节点的指针

    backfather = FindFather(root, key, pos);
    if (NULL == backfather)
    {
        return root;
    }


    switch (pos)
    {
        case -1:
        {
            ptr = backfather->Left;
            fap = &(backfather->Left);
            break;
        }
        case  1:
        {
            ptr = backfather->Right;
            fap = &(backfather->Right);
            break;
        }
        case  0:
        {
            ptr = backfather;
            fap = &(root);//不能用backfather,操作backfather不会作用到root
            break;
        }
    }

    //第一种情况,没有左子树
    if (NULL == ptr->Left)
    {
        //以当前节点的右子节点替换当前节点
        *fap = ptr->Right;

        free(ptr);
        ptr = NULL;
        return root;
    }
    //第二种情况,没有右子树
    if (NULL == ptr->Right)
    {
        //以当前节点的左子节点替换当前节点
        *fap = ptr->Left;

        free(ptr);
        ptr = NULL;
        return root;
    }
    //第三种情况,有左子树也有右子树
    backfather = ptr;  //父节点指向当前节点
    next = backfather->Left;   //设置子节点
    while (NULL != next->Right)//找到最接近ptr->data的节点
    {
        backfather = next;
        next = next->Right;
    }
    ptr->data = next->data;  //替换数据

    //此时 next->Right == NULL
    if (backfather->Left == next)
    {
        backfather->Left = next->Left;
    }
    else
    {
        backfather->Right = next->Right;//NULL
    }
    free(next);
    return root;

}

/*创建一个二叉排序树*/
BstNode* CreatBST(TElemType arr[], const int n)
{
    BstNode *root = NULL;//指向根结点

    for (int i=0; i<n; i++)
    {
        if (NULL == root)
        {
            root = CreatBstNode(arr[i]);
        }
        else
        {
            AddBstNodeToTree(root, arr[i]);
        }
    }

    return root;
}

/*查找二叉树中元素*/
BstNode* SearchBstNode(BstNode* T, const TElemType key)
{
    BstNode *p = T;
    if (NULL == p)
    {
        return NULL;
    }

    if (p->data == key)
    {
        p = T;
    }
    else if (p->data > key)
    {
        p = SearchBstNode(T->Left, key);
    }
    else
    {
        p = SearchBstNode(T->Right, key);
    }

    return p;
}

//获取树的深度
int GetDepth(BstNode* T)
{
    if (NULL == T)
    {
        return 0;//空树深度为0
    }

    int ld, rd;
    ld = 1 + GetDepth(T->Left );
    rd = 1 + GetDepth(T->Right);

    return (ld > rd) ? ld : rd;
}

//按树状打印二叉树
void DrawByTree(BstNode *T, int depth)
{
    if (NULL == T)
    {
        return ;
    }

    DrawByTree(T->Right, depth+1);//打印右子树,并将层次加1

    for (int i = 0; i < depth; i++)//按照递归的层次打印空格
    {
        printf("   ");
    }

    printf("%d\n", T->data);//输出根结点

    DrawByTree(T->Left, depth+1);//打印左子树,并将层次加1
}

//按层次输出二叉树的结点
void DrawByLevel(BstNode *T)
{
    if (NULL == T)
    {
        return ;
    }

    BstNode *queue[MaxSize];
    BstNode *p;
    int front = -1, rear = -1;

    rear++;
    queue[rear] = T;

    while (front != rear)
    {
        front = (front + 1) % MaxSize;
        p = queue[front];
        printf("%d ", p->data);

        if (p->Left)
        {
            rear = (rear + 1) % MaxSize;
            queue[rear] = p->Left;
        }
        if (p->Right)
        {
            rear = (rear + 1) % MaxSize;
            queue[rear] = p->Right;
        }
    }
}

/*用递归的方式,实现二叉树的先序遍历*/
void pre_order(BstNode *T)
{
    if(NULL == T)
    {
        return ;
    }

    /*step 1:访问根*/
    printf("%d ",T->data);

    /*step 2:用先序的方式去访问左子树*/
    pre_order(T->Left);

    /*step 3:用先序的方式去访问右子树*/
    pre_order(T->Right);
}

/*用递归的方式,实现二叉树的中序遍历*/
void mid_order(BstNode *T)
{
    if(NULL == T)
    {
        return ;
    }

    /*step 1:用中序的方式去访问左子树*/
    mid_order(T->Left);

    /*step 2:访问根*/
    printf("%d ",T->data);

    /*step 3:用中序的方式去访问右子树*/
    mid_order(T->Right);
}

/*用递归的方式,实现二叉树的后序遍历*/
void post_order(BstNode *T)
{
    if(NULL == T)
    {
        return ;
    }

    /*step 1:用后序的方式去访问左子树*/
    post_order(T->Left);

    /*step 2:用后序的方式去访问右子树*/
    post_order(T->Right);

    /*step 3:访问根*/
    printf("%d ",T->data);
}

//产生n个不重复的随机数
void CreateArr(TElemType* num, const int n)
{
    bool flg;
    //产生随机数,存储在num数组中
    for (int i=0; i<n; i++)
    {
        flg = true;
        int data = rand() % 100;

        //判断生成的数是否重复
        for (int j=0; j<i; j++)
        {
            if(data == num[j])
            {
                flg = false;
                i--;
                break;
            }
        }

        if (flg)
        {
            num[i] = data;
        }
    }
}

//将数组中的数输出
void ShowArr(TElemType* num, const int n)
{
    for (int i=0; i<n; i++)
    {
        printf("%3d ", num[i]);
        if (0 == (i+1) % 5)
        {
            printf("\n");
        }
    }

    printf("\n");
}

int main()
{
    while (1)
    {
        TElemType num[128];
        int n = 8;
        printf("----------------------------------\n");
//        printf("How many numbers need?\t");
//        scanf("%d", &n);
//        if (0 == n)
//        {
//            return 0;
//        }
    //    srand(time(NULL) );   //设置随机数种子
        CreateArr(num, n);
        ShowArr(num, n);

        BstNode *T = CreatBST(num, n);

        printf("pre_order:\n");
        pre_order(T);
    //    printf("\nmid_order:\n");
    //    mid_order(T);
    //    printf("\npost_order:\n");
    //    post_order(T);
        putchar('\n');

    //    printf("\nDrawByLevel:\n");
    //    DrawByLevel(T);
        printf("\nDrawByTree:\n");
        DrawByTree(T, 0);

        printf("----------------------------------\n");
        printf("Delete:\t");
        TElemType key;
        scanf("%d", &key);
        printf("----------------------------------\n");
        T = DeleteBstNode(T, key);
        DrawByTree(T, 0);

    }

}

  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面是二叉树的C语言代码示例。 首先,我们需要定义二叉树的结构体: ```c struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; ``` 接下来,我们分别实现二叉树操作: 1. 加节点 ```c struct TreeNode* insertNode(struct TreeNode* root, int val) { if (!root) { struct TreeNode* node = (struct TreeNode*)malloc(sizeof(struct TreeNode)); node->val = val; node->left = NULL; node->right = NULL; return node; } if (val < root->val) { root->left = insertNode(root->left, val); } else if (val > root->val) { root->right = insertNode(root->right, val); } return root; } ``` 2. 除节点 ```c struct TreeNode* deleteNode(struct TreeNode* root, int key) { if (!root) { return NULL; } if (root->val == key) { if (!root->left) { struct TreeNode* tmp = root->right; free(root); return tmp; } else if (!root->right) { struct TreeNode* tmp = root->left; free(root); return tmp; } else { struct TreeNode* p = root->right; while (p->left) { p = p->left; } root->val = p->val; root->right = deleteNode(root->right, p->val); } } else if (root->val > key) { root->left = deleteNode(root->left, key); } else { root->right = deleteNode(root->right, key); } return root; } ``` 3. 修节点 ```c struct TreeNode* modifyNode(struct TreeNode* root, int oldVal, int newVal) { root = deleteNode(root, oldVal); root = insertNode(root, newVal); return root; } ``` 4. 找节点 ```c struct TreeNode* searchNode(struct TreeNode* root, int val) { if (!root || root->val == val) { return root; } if (root->val > val) { return searchNode(root->left, val); } else { return searchNode(root->right, val); } } ``` 以上就是二叉树的C语言代码示例。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值