Binary Tree (二叉树)

Some Concepts

  • Full Binary Tree (满二叉树)

    国内定义:所有分支结点都有左孩子和右孩子,并且叶子结点都集中在最下层的二叉树。

    国际定义:A full binary tree is a tree in which every node has either 0 or 2 children.

  • Complete Binary Tree (完全二叉树)

    将满二叉树从右至左、从下到上按顺序删除结点所得到的树。完全二叉树除了最下层以外,其他结点的度必然为2,即除去最下层的完全二叉树将得到满二叉树。

  • Binary Search Tree (二叉搜索树)

    features:结点的左子树的所有key值均小于该结点的key值, 结点的右子树的key值均大于该结点的key值。

Traversal Algorithm

PreOrder (先序遍历)

  • Recursion

    steps:

    1. 访问节点;

    2. 先序遍历左子树;

    3. 先序遍历右子树。

    code

    void preOrderRecursion(BTNode* tree)
    {
        if (tree != NULL)
        {
            printf("%d ", tree -> data);
            preOrderRecursion(tree -> lChild);
            preOrderRecursion(tree -> rChild);
        }
    }
    
  • Non-Recursion

    steps:

    1. 循环遍历左子树,访问结点,若是有右子树,将右子树入栈;

    2. 遍历到叶子结点时,出栈,并重复步骤1;

    3. 直到栈空,完毕。

    code:

    void preOrderNonRecursion(BTNode* tree)
    {
        linked_stack* stack = NULL;
        if (init_stack(&stack))
        {
            push(stack, tree);
            while(!isEmptyStack(stack))
            {
                stack_type btnode = pop(stack);
                while(btnode != NULL)
                {
                    printf("%d ", btnode -> data);
                    if (btnode -> rChild)
                        push(stack, btnode -> rChild);
    
                    btnode = btnode -> lChild;
                }
            }
            free(stack);
        }
    }
    

InOrder (中序遍历)

  • Recursion

    steps:

    1. 中序遍历左子树;

    2. 访问结点;

    3. 中序遍历右子树。

    code:

    if (tree != NULL)
    {
        inOrderRecursion(tree -> lChild);
        printf("%d ", tree -> data);
        inOrderRecursion(tree -> rChild);
    }
    
  • Non-Recursion

    steps:

    1. 循环遍历左子树并将结点入栈;

    2. 若结点无左子树,出栈,访问该结点,并将该结点的右子树当做起始位置,重复步骤1;

    3. 直到栈空并且遍历指针nodeIndex为NULL,完毕。

    针对step3,之所以要附加上遍历指针为NULL的条件是因为当循环遍历到根节点时,将根节点pop出去后此时栈为空,若此二叉树根节点有右子树,则此时根节点的右子树并未遍历完,因此不能以栈空作为结束循环的条件。

    code:

    void inOrderNonRecursion(BTNode* tree)
    {
        linked_stack* stack = NULL;
        if (init_stack(&stack))
        {
            stack_type nodeIndex = tree;
            do
            {
                while (nodeIndex != NULL)
                {
                    push(stack, nodeIndex);
                    nodeIndex = nodeIndex -> lChild;
                }
                nodeIndex = pop(stack);
                printf("%d ", nodeIndex -> data);
                nodeIndex = nodeIndex -> rChild;
            } while ((!isEmptyStack(stack)) || (nodeIndex != NULL));
            free(stack);
        }
    }
    
  • Notes

    • How to judge a binary tree is a BST?

      用中序遍历方式遍历该树,若所得序列为递增序列,则为BST。

PostOrder (后序遍历)

  • Recursion

    steps:

    1. 后序遍历左子树;

    2. 后序遍历右子树;

    3. 访问结点。

    code:

    if (tree != NULL)
    {
        postOrderRecursion(tree -> lChild);
        postOrderRecursion(tree -> rChild);
        printf("%d ", tree -> data);
    }
    
  • Non-Recursion

    后序遍历的非递归方法需要有额外的字段来记录结点是否被访问过

Level (层次遍历)

steps:

  1. 建立一个循环队列,并将二叉树的根节点入队列;

  2. 若队列不为空,出队列,访问该结点,并将该结点的左孩子和右孩子入队列;

  3. 不断重复步骤2,直到队列为空。

code:

void levelTraversal(BTNode* tree)
{
    if (tree != NULL)
    {
        // Loop queue initialization.
        LoopQueue loopQ;
        loopQ.front = 0;
        loopQ.rear = 0;
        LoopQueue* loopQueue = &loopQ;

        // Enqueue the root node.
        if (!enqueue(loopQueue, tree))
            return;

        while (!isEmpty(loopQueue))
        {
            // Dequeue and visit the node.
            BTNode* node = dequeue(loopQueue);
            printf( "%d ", node -> data);

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

推荐阅读更多精彩内容

  • 一.前序遍历 非递归实现 根据前序遍历访问的顺序,优先访问根结点,然后再分别访问左孩子和右孩子。即对于任一结...
    Arryn_阅读 911评论 0 0
  • 一些概念 数据结构就是研究数据的逻辑结构和物理结构以及它们之间相互关系,并对这种结构定义相应的运算,而且确保经过这...
    Winterfell_Z阅读 5,806评论 0 13
  • 目录 1、什么是树 2、相关术语 3、二叉树 3.1、二叉树的类型 3.2、二叉树的性质 3.3、二叉树的结构 3...
    我哈啊哈啊哈阅读 2,549评论 0 10
  • 数据结构和算法--二叉树的实现 几种二叉树 1、二叉树 和普通的树相比,二叉树有如下特点: 每个结点最多只有两棵子...
    sunhaiyu阅读 6,464评论 0 14
  • 今天检查一辆现代,检查出一些问题,在与客户沟通的时候,把一些不更换的重要性聊清楚,把主要的都整了,很满意,服务好客...
    88e94d537f85阅读 182评论 0 0