二叉树创建和遍历

#include <stdio.h>
#include <stdlib.h>
// 带返回值创建二叉树 最简单方法
//节点数据结构
struct bs_node
{
    int value;
    struct bs_node *left;
    struct bs_node *right;
};
typedef struct bs_node tree;
// tree *head,*p,*root;

//创建二元查找树 有返回值的可以不传参 没有的话如何传参
//输入0代表到了某个叶子节点
tree *creat()
{
    int ch;
    tree *p=NULL;

    printf("input a num\n");
    scanf("%d",&ch);
    if(ch!=0)
    {
        p=(tree *)malloc(sizeof(tree));
        p->value=ch;
        printf("%d left child\n",ch);
        p->left=creat();
        printf("%d ringht child\n",ch);
        p->right=creat();
    }
    return p;
}

//先序遍历
int preorder(tree *p)
{
    if(p!=NULL)
    {
        printf("%d\n",p->value);
        preorder(p->left);
        preorder(p->right);
    }
    return 0;
}
// zhongxubianli
int midorder(tree *p)
{
    if(p!=NULL)
    {
        midorder(p->left);
        printf("%d\n",p->value);
        midorder(p->right);
    }
    return 0;
}
// houxubianli
int postorder(tree *p)
{
    if(p!=NULL)
    {
        postorder(p->left);
        postorder(p->right);
        printf("%d\n",p->value);
    }
    return 0;
}


// main hanshu
int main(int argc, char const *argv[])
{
    //tree *root=(tree *)malloc(sizeof(tree));
    tree *root=NULL;
    root=creat();
    // printf("%d\n",root->value);
    // printf("%d\n",root->left->value);
    printf("11111111111111\n");
    preorder(root);

    printf("222222222222\n");
    midorder(root);

    printf("333333333333\n");
    postorder(root);

    return 0;
}

上面是带返回值的创建函数,比较容易理解。创建和遍历都是采用递归的方法。

#include <stdio.h>
#include <stdlib.h>
// 带参数创建二叉树 二层指针
//节点数据结构
struct bs_node
{
    int value;
    struct bs_node *left,*right;
};
typedef struct bs_node tree;
//带参数的因为考虑到参数为*p的话需要改变p,这是不可以的 所以用二层指针 或者用指针的引用他们的在函数体内形式不一样 以及如何调用
void creat(tree **p)
{
    int ch;
    printf("input a num\n");
    scanf("%d",&ch);
    *p=(tree *)malloc(sizeof(tree));
    (*p)->value=ch;

    if(ch==0)
    {
        *p=NULL;
        return;
    }
    else
    {
        printf("%d left child\n",ch);
        creat(&((*p)->left));

        printf("%d right child\n",ch);
        creat(&((*p)->right));
    }
}

int init(tree **p)
{
    *p=(tree *)malloc(sizeof(tree));
    (*p)->value=5;
    return 0;
}

void preoder(tree *p)
{
    if(p!=NULL)
    {
        printf("%d\n",p->value);
        preoder(p->left);
        preoder(p->right);
    }
    else
        return;
}

int main(int argc, char const *argv[])
{   
    tree *a=NULL;
    creat(&a);
    preoder(a);
    return 0;
}

上面采用的二层指针传参

#include <stdio.h>
#include <stdlib.h>
//指针的引用带参数创建二叉树c文件
//节点数据结构
struct bs_node
{
    int value;
    struct bs_node *left,*right;
};
typedef struct bs_node tree;
//reference of a poiter as 调用方法及里面p类型需要注意
int creat(tree *&p)
{
    int ch;
    printf("input a num\n");
    scanf("%d",&ch);
    p=(tree *)malloc(sizeof(tree));
    if(ch==0)
    {
        p=NULL;
    }
    else
    {

        p->value=ch;
        printf("%d left child\n",ch);
        creat(p->left);
        printf("%d right child\n",ch);
        creat(p->right);
    }
    return 0;
}


int preoder(tree *p)
{
    if(p!=NULL)
    {
        printf("%d\n",p->value);
        preoder(p->left);
        preoder(p->right);
    }
    return 0;
}
// 测试指针引用的例子
int test(tree *&p)
{
    p=(tree *)malloc(sizeof(tree));
    p->value=5555;
    return 0;
}

int main(int argc, char const *argv[])
{   
    tree *a=NULL;
    // test(a);
    creat(a);
    // printf("%d \n",a->value);
    preoder(a);
    return 0;
}

参数为指针的引用总结。

我的个人总结:对于一个指针我们应该知道几个性质,1指针变量,2指针变量的地址,3指针变量指向的内存区域。指针变量本身的内存区域一般为4个字节(与编译器有关,与它指向的内存区域大小无关,就算指向的是一个特别大的数据结构,它也只是一个数字,这个数字是特别大的数据结构的地址。它存了一个数字,存到那里了呢?这个地方就是它的地址)。int *p;则p是指针变量,&p是它的地址,*p是它指向的东西。

二叉树程序总结
主要在于指针传参问题
1.一层指针传参create(tree*P),可以修改*p,但坚决不允许改p,例如p=NUL,或者给p分配内存,这在函数体内部都是不对的,不适合建立二叉树,也可能有奇怪的方法我不知道。。(使用带返回值的可以解决一些问题{tree create();},例如不传参在函数体内建立一个指针,对指针操作后返回指针,调用时候赋值给一个已经声明的指针变量即可),

2.参数为二层指针int create (tree **P),可以修改*p(一个指针),**P(一个结构体),不可以修改p,调用时候为了避免创建二层指针显得比较奇怪,用tree *P;create(&p)就可以。

3.参数为指针的引用int create(tree *&p);p是一个单层指针(函数参数是一个指针p,但是传递的是p的地址),可以修改p,可以和1对比。调用 tree *P;create(p);

注:引用传参需要用g++编译,gcc不支持引用传参

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值