有序二叉树的创建与遍历

c++版,网上查找的,自己稍微修改了一下,里面有先变量不太清楚他的用法:比如先序创建函数里for循环的作用不太清楚,我尝试把for循环去掉,结果没有错具体的用法请查阅资料。
#include <iostream>  
using namespace std;

//节点
struct BiTNode { 
    char data;   //数据域,指针域
    struct BiTNode* lchild, *rchild; // 左右孩子  
};

void CreatBiTree(BiTNode* &T);// 先序递归创建二叉树

void PreOrderTraverse(BiTNode* &T); // 先序遍历二叉树  
void Inoder(BiTNode* &T); // 中序遍历二叉树  
void Posoder(BiTNode* &T);  // 后序遍历二叉树  

int main() 
{
    cout << "创建一颗二叉树,其中A~Z字符代表树的数据,用'#'表示空树:" << endl;
    BiTNode* T;
    CreatBiTree(T); 

    cout << "先序递归遍历" << endl;
    PreOrderTraverse(T);
    cout <<  endl;

    cout << "中序递归遍历" << endl;
    Inoder(T);
    cout << endl;

    cout << "后序递归遍历" << endl;
    Posoder(T);
    cout << endl;

    return 0;
}

void CreatBiTree(BiTNode* &T) { // 先序递归创建二叉树  
    char ch;
    for (int  j = 0; j < 1; ++j)//此for循环可以去掉,具体作用我不太清楚
    {
        if ((ch = getchar()) == '#')//先执行的Getchar();
            T = NULL;       //  ***************** 递归的结束语句
        else
        {
            T = new BiTNode; // 产生新的子树  
            T->data = ch; //将读入的数据存入父节点的数据域
            //然后创建左右子树
            CreatBiTree(T->lchild); //左,父节点指针域指向左子树的数据域;
            CreatBiTree(T->rchild); //右,同理;
        }
    }
}
void PreOrderTraverse(BiTNode* &T) {    // 先序遍历二叉树  
    if (T) { // 当节点数据域不为空时执行  

    //父节点的数据输出
    //左子树的父节点输出
    //右子树的父节点输出
        cout << T->data;
        PreOrderTraverse(T->lchild);
        PreOrderTraverse(T->rchild);
    }
    else
        cout << "";
}
void Inoder(BiTNode* &T) { // 中序遍历二叉树  
    if (T)
    {
        Inoder(T->lchild);
        cout << T->data;
        Inoder(T->rchild);
    }
    else
        cout << "";

}
void Posoder(BiTNode* &T) { // 后序遍历二叉树  
    if (T) {
        Posoder(T->lchild);
        Posoder(T->rchild);
        cout << T->data;
    }
    else
        cout << "";
}

C语言版有序二叉树,函数定义可两个结构体,一个为树节点的结构体Node,一个为根节点的结构体Tree。函数主要实现得功能有插入一个节点,删除一个节点,需要删除一个节点就会有查找。清空一颗二叉树,判断二叉树是否为空/满

//实现有序二叉树的各种操作  
#include <stdio.h>  
#include <stdlib.h>  

//定义节点的数据类型  
typedef struct Node
{
    int data;//存储数据内容  
    struct Node* left;//左子树的地址  
    struct Node* right;//右子树的地址  
}Node;

//定义有序二叉树的数据类型  
typedef struct
{
    Node* root;//记录根节点的地址  
    int cnt;//记录节点的个数  
}Tree;

void insert_data(Tree* pt, int data);//实现向有序二叉树中插入新节点的操作  
void insert(Node** pRoot, Node* pn);//插入新节点的递归函数

void travel_data(Tree* pt);//采用中序遍历方法进行遍历  
void travel(Node* pRoot);//遍历的递归函数  

Node* create_node(int data);//实现创建新节点  

void clear_data(Tree* pt);//实现清空树中的所有节点  
void clear(Node** pRoot);//实现清空的递归函数 

Node** find_data(Tree* pt, int data);//实现查找一个指定的节点  
Node** find(Node** pRoot, int data);//查找的递归函数  

void del_data(Tree* pt, int data);//实现删除指定的节点  

void modify(Tree* pt, int data, int new_data);//修改指定元素的操作  
int empty(Tree* pt);//判断二叉树是否为空  

int full(Tree* pt);//判断二叉树是否为满  
int size(Tree* pt);//计算二叉树中节点的个数  
int get_root(Tree* pt);//获取根节点的元素值  

int main(void)
{
    //创建有序二叉树,并且进行初始化  
    Tree tree;
    tree.root = NULL;//节点的初始化
    tree.cnt = 0;
    int p,q;
    printf("请输出你需要进行操作序号:\n1.建立一颗二叉树\n2.插入元素\n3.删除元素\n4.替换元素\n5.输出树的基本信息\n6.输入0时退出操作\n");
    scanf_s("%d", &p);
        while (p != 0)
        {
            switch (p)
            {
            case 1:printf("请输入元素,输入-1时结束:");
                scanf_s("%d", &p);
                while (p != -1)
                {
                    insert_data(&tree, p);
                    scanf_s("%d", &p);
                }
                travel_data(&tree);
                printf("------------------\n");
                break;
            case 2:printf("请输入需要插入的元素:");
                scanf_s("%d", &p);
                insert_data(&tree, p);
                travel_data(&tree);
                printf("------------------\n");
                break;
            case 3:printf("请输入需要删除的元素:");
                scanf_s("%d", &p);
                del_data(&tree, p);
                travel_data(&tree);
                printf("--------------------\n");
                break;
            case 4:printf("请输入需要替换的元素和替换后的元素:");
                scanf_s("%d%d", &p, &q);
                modify(&tree, p, q);
                travel_data(&tree);
                printf("--------------------\n");
                break;
            case 5:
                printf("二叉树中根节点的元素是:%d\n", get_root(&tree));//70  
                printf("二叉树中节点的个数是:%d\n", size(&tree));//3  
                printf("%s\n", empty(&tree) ? "二叉树为空" : "二叉树不为空");
                printf("%s\n", full(&tree) ? "二叉树已满" : "二叉树没有满");
                break;
            default:
                printf("输入有误请重新输入:");
                break;
            }
            printf("请输出你需要进行操作序号:\n1.建立一颗二叉树\n2.插入元素\n3.删除元素\n4.替换元素\n5.输出树的基本信息\n6.输入0退出操作\n");
            scanf_s("%d", &p);
        }
    return 0;
}

//修改指定元素的操作  

void modify(Tree* pt, int data, int new_data)
{//旧元素不存在时,直接插入新元素即可  
    del_data(pt, data);//1.删除旧元素  
    insert_data(pt, new_data);//2.插入新元素  
}
int empty(Tree* pt)
{
    return NULL == pt->root;//判断二叉树是否为空  
}
int full(Tree* pt)
{//判断二叉树是否为满  
    return 0;
}
int size(Tree* pt)
{
    return pt->cnt;//计算二叉树中节点的个数  
}
int get_root(Tree* pt)
{//获取根节点的元素值  
    if (empty(pt))
    return -1;//表示失败(以后讲到)  
    return pt->root->data;
}
void del_data(Tree* pt, int data)
{//实现删除指定的节点  
    Node** pp = find_data(pt, data);//1.查找目标元素所在节点的地址  
    if (NULL == *pp)//2.判断查找失败情况,不需要删除  
    {
        printf("目标元素不存在,删除失败\n");
        return;
    }
    if ((*pp)->left != NULL)//3.合并左右子树,左子树插入到右子树中  
                            //左子树不为空时,需要插入到右子树中 
        insert(&(*pp)->right, (*pp)->left);
    Node* q = *pp;//4.寻找指针记录要删除的节点地址  
    *pp = (*pp)->right;//5.将原来指向要删除节点的指针 重新指向 合并之后的右子树  
    free(q);//6.删除目标元素所在的节点
    q = NULL;
    pt->cnt--;//7.节点个数减1  
}
Node** find(Node** pRoot, int data)
{//查找的递归函数  
    if (NULL == *pRoot)//1.判断二叉树是否为空,为空直接返回  
        return pRoot;//&pt->root;         
    if (data == (*pRoot)->data)//2.比较根节点元素和目标元素的大小,如果相等,直接返回
        return pRoot;//&pt->root;  
    else if (data < (*pRoot)->data)//3.若目标元素小于根节点元素值,左子树查找  
        return find(&(*pRoot)->left, data);
    else//4.若目标元素大于根节点元素,去右子树查找  
        return find(&(*pRoot)->right, data);
}
//实现查找一个指定的节点  
//返回 指向目标元素所在节点的指针 的地址  
Node** find_data(Tree* pt, int data)
{
    return find(&pt->root, data);   //调用递归函数实现查找  
}
void clear(Node** pRoot)//实现清空的递归函数  
{
    if (*pRoot != NULL)//判断二叉树是否为空  
    {
        clear(&(*pRoot)->left);//1.清空左子树  
        clear(&(*pRoot)->right);//2.清空右子树  
        free(*pRoot);//3.清空根节点  
        *pRoot = NULL;
    }
}
void clear_data(Tree* pt)//实现清空树中的所有节点  
{   
    clear(&pt->root);//调用递归函数实现清空  
    pt->cnt = 0;//二叉树的节点个数清零  
}
Node* create_node(int data)//实现创建新节点  
{
    Node* pn = (Node*)malloc(sizeof(Node));
    pn->data = data;
    pn->left = NULL;
    pn->right = NULL;
    return pn;
}
void travel(Node* pRoot)//中序遍历的递归函数  
{
    if (pRoot != NULL)//判断二叉树不为空时才需要遍历  
    {   
        travel(pRoot->left);       //1.遍历左子树  
        printf("%d ", pRoot->data);//2.遍历根节点  
        travel(pRoot->right);      //3.遍历右子树
    }
}
void travel_data(Tree* pt)//采用中序遍历方法进行遍历 
{
    travel(pt->root);//调用递归函数进行遍历   
    printf("\n");//打印换行  
}
void insert(Node** pRoot, Node* pn)//插入新节点的递归函数  
{
    if (NULL == *pRoot)//1.判断二叉树是否为空,如果为空则让根节点指针直接指向新节点  
    {
        *pRoot = pn;
        return;
    }

    //2.如果二叉树非空,比较根节点和新节点大小  
    //2.1 如果根节点大于新节点,插入左子树  
    if ((*pRoot)->data > pn->data)
        insert(&(*pRoot)->left, pn);
    else//2.2 如果根节点小于等于新节点,插入右子树  
        insert(&(*pRoot)->right, pn);
}
void insert_data(Tree* pt, int data)
{//实现向有序二叉树中插入新节点的操作  

    //1.创建新节点pn<===>create_node(data)可以相互替换
    /*Node* pn = (Node*)malloc(sizeof(Node));  
    pn->data = data;  
    pn->left = NULL;  
    pn->right = NULL;  */

    //2.插入新节点到二叉树中,调用递归函数  
    insert(&pt->root, create_node(data));
    //3.二叉树中节点个数加1  
    pt->cnt++;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值