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);
            }
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

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