【实例代码】树的基本操作

树的基本操作


老规矩,了解了树的基本概念之后,咱们还是先从基本操作代码开始,在代码中和树交朋友

注:
1.二叉树的结点结构体

2.初始化

3.左插入孩子结点

4.右插入孩子结点

5.前序、中序、后序遍历

6.查找数据元素

本文以书本上的一个例子加以演示,包含一个头文件《BiTree.h》和一个源文件《main.cpp》

建立这样一颗二叉树:


BiTree.h:
#pragma once
#include<stdio.h>
#include<stdlib.h>
typedef int DataType;
//二叉树的结点结构体
struct BiTreeNode
{
    DataType data;              //数据域
    BiTreeNode *leftChild;  //左孩子指针域
    BiTreeNode *rightChild; //右孩子指针域
};
//初始化根结点
void initiate(BiTreeNode **root) {
    *root = (BiTreeNode *)malloc(sizeof(BiTreeNode));  //根结点分配内存空间
    (*root)->data = NULL;
    (*root)->leftChild = NULL;
    (*root)->rightChild = NULL;
}
/*结点curr左插入结点,成功返回插入好的结点,否则返回NULL
即将新的数据结点s变成curr的左孩子结点,curr以前的左孩子结点变成s的左孩子结点*/
BiTreeNode *insertLeftNode(BiTreeNode *curr,DataType data) {
    BiTreeNode *s;
    s = (BiTreeNode *)malloc(sizeof(BiTreeNode));
    s->data = data;                   //用数据建立新的二叉树结点
    if(curr == NULL) {                //防止当前结点为空
        printf("未找到目标结点!");
        return NULL;
    }
    s->leftChild = curr->leftChild;   //在curr的左子树变成s的左子树
    s->rightChild = NULL;             //默认新插入的结点的右孩子结点为NULL
    curr->leftChild = s;              //将s变成curr的左子树,因此被插入到树中
    return s;                         //返回插入好的结点
}
/*结点curr右插入结点,成功返回插入好的结点,否则返回NULL
即将新的数据结点s变成curr的右孩子结点,curr以前的右孩子结点变成s的右孩子结点*/
BiTreeNode *insertRightNode(BiTreeNode *curr, DataType data) {
    BiTreeNode *s;
    s = (BiTreeNode *)malloc(sizeof(BiTreeNode));
    s->data = data;                     //用数据建立新的二叉树结点
    if (curr == NULL) {                 //防止当前结点为空
        printf("未找到目标结点!");
        return NULL;
    }
    s->leftChild = NULL;             //默认新插入的结点的左孩子结点为NULL
    s->rightChild = curr->rightChild; //在curr的右子树变成s的右子树
    curr->rightChild = s;                //将s变成curr的右子树,因此被插入到树中
    return s;                           //返回插入好的结点
}
/*前序遍历 ,递归*/
void PreOrder(BiTreeNode *root) {
    if (root != NULL ) {
        if(root->data!=NULL)             //先访问根结点
           printf("%c  ", root->data);
        PreOrder(root->leftChild);       //再访问左孩子结点
        PreOrder(root->rightChild);      //再访问右孩子结点
    }
}
/*中序遍历*/
void InOrder(BiTreeNode *root) {
    if (root != NULL) {
        InOrder(root->leftChild);        //先访问左孩子结点
        if (root->data != NULL)          //再访问根结点
            printf("%c  ", root->data);
        InOrder(root->rightChild);       //再访问右孩子结点
    }
}
/*后序遍历*/
void PostOrder(BiTreeNode *root) {
    if (root != NULL) {
        PostOrder(root->leftChild);      //先访问左孩子结点
        PostOrder(root->rightChild);     //再访问右孩子结点
        if (root->data != NULL)          //最后访问根结点
            printf("%c  ", root->data);
    }
}
/*查找数据元素,递归调用,成功返回找到的结点,否则返回NULL*/
BiTreeNode *search(BiTreeNode *root,int data) {
    BiTreeNode *result = NULL;
    if (root != NULL) {
        if (root->data == data) {                        //首先在根结点找
            result = root;
        }
        else {//如果在根结点没找到
            result = search(root->leftChild,data);       //在左孩子结点找
            if (result == NULL) //如果在左孩子结点没找到
                result = search(root->rightChild, data); //在右孩子结点找
        }
    }
    return result;     //返回查找结果
}
main.c:
#include"BiTree.h"    //因为在BiTree.h中带入了stdio.h,此处可不重复导入
int main()
{
    BiTreeNode *root, *p;
    initiate(&root);                   //初始化根结点
    p = insertLeftNode(root, 'A');     //根结点左孩子插入A
    p = insertLeftNode(p, 'B');        //A结点左孩子插入B
    p = insertLeftNode(p, 'D');        //B结点左孩子插入D
    p = insertRightNode(p, 'G');       //D结点左孩子插入G
    p = insertRightNode(root->leftChild, 'C'); //A结点右孩子插入C
    insertLeftNode(p, 'E');            //C结点左孩子插入E
    insertRightNode(p, 'F');           //C结点右孩子插入F
    /*三种遍历*/
    printf("前序遍历:\n");
    PreOrder(root);
    printf("\n");
    printf("中序遍历:\n");
    InOrder(root);
    printf("\n");
    printf("后序遍历:\n");
    PostOrder(root);
    printf("\n");
    /*查找F*/
    p = search(root, 'F');
    if (p != NULL) {
        printf("已找到F元素!\n");
    }
    else
        printf("未找到F元素!\n");
    system("pause");       //暂停,防止闪屏
    return 0;
}

运行结果:


代码编译器:Visual Studio 2017
ok

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值