第六章:创建二叉树(赋完整版代码)

  • 二叉链表的节点存储结构
    由一个数据域和两个指针域组成。指针域分别存放指向左孩子和右孩子的指针。
struct TreeNode
{
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
};
结构示意图
  • 二叉树的建立
    我们要在内存建立一个如图所示的树,为了能让每个结点确认是否有左右孩子,对它进行扩展变成图2左图的样子,也就是将二叉树中每个结点的空指针引出一个虚结点,其值为特定值比如:#或0.我们称这种处理后的二叉树为原二叉树的扩展二叉树。扩展二叉树就可以做到一个遍历序列确定一颗二叉树了。如图2左图的前序遍历就为AB#D##C##
    image.png

    这样就可以把前序遍历AB#D##C##用键盘挨个输入。实现的算法如下:
struct TreeNode *create(struct TreeNode *tree)
{
    
    int ch ;
    scanf("%d",&ch);
    if(ch == '#')
    {
        tree = NULL;
    }
    else
    {
        tree = new struct TreeNode;
        //tree = (TreeNode *)calloc(1,sizeof(TreeNode));
        tree->val = ch;
        tree->left = create(tree->left);
        tree->right= create(tree->right);
    }
    return tree;
}
  • 细节说明
  1. 代码中的tree都应该是结点,也就是一个结构体结点。因为我用linux下的c++环境编译执行,不需要对其进行特别的强调。但是在c环境中需要对所有treestruct关键字说明强调该结点是定义一个结构体结点,而不是一个指针类型。为了保险起见,我把代码中加入struct关键字。
  2. 递归过程中为每个新加入的数据开辟内存空间的方法:
    可以用new分配如 tree = new struct TreeNode,
    也可以使用calloc方式分配内存
 tree = (TreeNode *)calloc(1,sizeof(TreeNode))

3)使用scanf输入数据时,需要注意:在一行输入,每个字符中间空格A B # D # # C # #,最后回车。
也可以把字符放入一个数组中,然后再函数中不断让数组下标加一取值。需要定义一个index_1,(因为index和包中某个命名冲突,故我们命名为index_1),该变量必须放在函数外面。

char chars_tree[] = "AB#D##C##";
int index_1 = 0;
TreeNode *create(TreeNode *tree)
{
    char ch = chars_tree[index_1++];

    if(ch == '#')
    {
        tree = NULL;
    }
    else
    {
        tree = new TreeNode;
        tree->val = ch;
        tree->left = create(tree->left);
        tree->right= create(tree->right);
    }
    return tree;
}
  • 详细分析构造二叉树的过程
    1)index_1=0即取第一个字符AA不等于#,执行else操作。开辟结构体结点空间,把字符A赋值给结点的数据域,递归进入A结点的左子树,递归开始。
  1. index_1=1即取第二个字符BB不等于#,执行else操作。开辟结构体结点空间,把字符B赋值给结点的数据域,递归进入B结点的左子树。
  2. index_1=2即取第三个字符##等于#,执行tree = NULL操作即该结点为空。跳过else,直接return该结点即B结点无左子树。跳出tree->left = create(tree->left)该语句。进入下一条语句,找B结点的右子树。
  3. index_1=3即取第4个字符DD不等于#,执行else操作。开辟结构体结点空间,把字符D赋值给结点的数据域,递归进入D结点的左子树。
  4. index_1=4即取第5个字符##等于#,执行tree = NULL操作即该结点为空。跳过else,直接return该结点,即D结点无左子树。跳出tree->left = create(tree->left)该语句。进入下一条语句,找D结点的右子树。
  5. index_1=5即取第6个字符##等于#,执行tree = NULL操作即该结点为空。跳过else,即D结点无右子树,直接return该空结点,跳出tree->right= create(tree->right)语句。返回D结点,D结点遍历完毕返回B结点,B结点遍历完毕,返回A结点,进入A结点的右子树。
  6. index_1=6即取第7个字符CC不等于#,执行else操作。开辟结构体结点空间,把字符C赋值给结点的数据域,递归进入C结点的左子树。
  7. index_1=7即取第8个字符##等于#,执行tree = NULL操作即该结点为空。跳过else,直接return该结点,即C结点无左子树。跳出tree->left = create(tree->left)该语句。进入下一条语句,找C结点的右子树。
  8. index_1=8即取第9个字符##等于#,执行tree = NULL操作即该结点为空。跳过else,直接return该结点,即C结点无右子树。跳出tree->right= create(tree->right);该语句。执行完毕。

赋完整版代码

  • 说明二叉树的结构为1,2,4,0,0,0,3,0,0,空结点用0代替。构建该二叉树并先序输出。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;

struct TreeNode
{
    int val;
    TreeNode *left;
    TreeNode *right;
};
int array_tree[] = {1,2,4,0,0,0,3,0,0};
int index_1 = 0;
TreeNode *create(TreeNode *tree)
{
    int ch = array_tree[index_1++];
    if(ch == 0)
    {
        tree = NULL;
    }
    else
    {
        tree = new TreeNode;
        //tree = (TreeNode *)calloc(1,sizeof(TreeNode));
        tree->val = ch;
        tree->left = create(tree->left);
        tree->right= create(tree->right);
    }
    return tree;
}

void preOrder(TreeNode *tree)
{
    if(tree)
    {
        cout << tree->val <<" ";
        preOrder(tree->left);
        preOrder(tree->right);
    }
}

int main()
{
    TreeNode *tree = NULL;
    tree = create(tree);
    cout << "前序输出:" << endl;
    preOrder(tree);
    cout<<endl;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容