美文网首页
数据结构之二叉树2

数据结构之二叉树2

作者: 一直在路上_求名 | 来源:发表于2021-04-15 00:10 被阅读0次

    二叉树的创建

    二叉树的创建用到了辅助队列,通过辅助队列来创建二叉树;

    void buildBinaryTree(PTree_Node* root, PTree_Queue* phead, PTree_Queue* ptail,Tree_Element val) {
        PTree_Node newTree = (PTree_Node)calloc(1, sizeof(Tree_Node));
        PTree_Queue newQueue = (PTree_Queue)calloc(1, sizeof(Tree_Queue));
        newTree -> val = val;
        newQueue -> insertPos = newTree;
        PTree_Queue cur = *phead;
        //根节点为空,说明树是空的
        if (NULL == *root) {
            *root = newTree;
            *phead = newQueue;
            *ptail = newQueue;
        } else {
            (*ptail) -> snext = newQueue;
            *ptail = newQueue;
            //左孩子为空,赋给左孩子
            if (NULL == cur -> insertPos -> left) {
                cur -> insertPos -> left = newTree;
            //右孩子为空,赋给右孩子
            } else if (NULL == cur -> insertPos -> right) {
                cur -> insertPos -> right = newTree;
                //左右孩子都设置完成的结点,从队列里移除
                *phead = cur -> snext;
                free(cur);
                cur = NULL;
            }
        }
    }
    

    二叉树的遍历

    前(先)序遍历

    1、递归实现

    void pre_order(PTree_Node root) {
      if(NULL == root) {
        return;
      }
      visit(root);
      pre_order(root -> left);
      pre_order(root -> right);
    }
    

    2、非递归实现

    void pre_order(BiTree root) {
      Stack< BiTreeNode> s;
      //初始化一个栈
      init_stack(s);  
      BiTree p = root;
       //栈中有数据,就需要遍历
      while(p || !isEmpty(s)){
        if(p) {
          //根节点先访问
          visit(p);
          //访问后push到栈中,为了遍历右结点使用
          push(s, p);
          //访问完根结点后,就该访问左结点了
          p = p -> left; 
        } else {
          //到这里说明当前结点没有左结点,因此该弹出结点访问右结点
          pop(s, p);
          //访问当前结点的右结点,如果右结点还有左结点又回进行上门的循环
          //直到所有结点都被访问后结束
          p = p -> right;
        }
      }
    }
    

    中序遍历

    1、递归实现

    void in_order(BiTree root) {
      if (NULL == root) {
        return;
      }
      in_order(root -> left);
      visit(root);
      in_order(root -> right);
    }
    

    2、非递归实现

    void in_order(BiTree root) {
      Stack<BiTreeNode> s;
      init_stack(s);
      BiTree p root;
      while (p || !isEmpty(s)) {
        if (p) {
          push(s, p);
          p = p -> left;
        } else {
          pop(s, p);
          visit(p);
          p = p -> right;
        }
      }
    }
    

    后序遍历

    1、递归实现

    void post_order(BiTree root) {
      if (NULL == root) {
        return;
      }
      post_order(root -> left);
      post_order(root -> right);
      visit(root);
    }
    

    2、非递归实现

    void post_order(BiTree root) {
      Stack<BiTree> s;
      init_stack(s);
      BiTree p = root;
      while(p || !isEmpty(s)) {
        BiTree visitFlag;
        if(p) {
          push(s, p);
          p = p -> left;
        } else {
          //这里需要注意的是一个结点如果有右结点被访问后,由于当前结点还在栈中
          //所以会造成死循环,所以这里需要标识,避免死循环
          top(s, p);
          if  (p -> right && p -> right != visitFlag) {
            p = p -> right;
          } else {
            pop(s, p);
            visit(p);
            //出栈后记录一下,防止重复入栈,避免死循环
            visit_flag = p;
            p = NULL;
          }
        }
      }
    }
    

    层次遍历

    1、顺序遍历

    //层次遍历整体比较简单就是借助队列,
    //先访问根结点,如果有左孩子就入栈,有右孩子再入栈,一次扫描栈,直至为空
    void levelOrder(BiTree root) {
      BiTree p;
      Queue<BiTree> q;
      initQueue(q);
      enQueue(q, root);
      while (!isEmpty(q)) {
        deQueue(q, p);
        if (p -> left) {
          enQueue(p -> left);
        }
        if (p -> right) {
          enQueue(p -> right);
        }
      }
    }
    

    2、逆序遍历

    void levelOrderReverse (BiTree root) {
      if (NULL == root) {
        return;
      }
      BiTree cur = root;
       //定义栈,将各结点放入栈中,然后遍历
      Stack<BiTree> s;
      //队列用于层序的正向遍历
      Queue<BiTree> q;
      initStack(s);
      initQueue(s);
      //将树的根结点先入栈
      enQueue(q, cur);
      //将顺序入队的数据,放入栈中
      while (!isEmpty(q)) {
        //出栈
        deQueue(q, cur);
        //放入栈
        push(s, cur);
        if (cur  -> left) {
          enQueue(q, cur -> left);
        }
        if (cur -> right) {
          enQueue(q, cur  -> right);
        }
      }
      //将栈中数据出栈分别访问
      while (!isEmpty(s)) {
        pop(s, p);
        visit(p);
      }
    }
    

    相关文章

      网友评论

          本文标题:数据结构之二叉树2

          本文链接:https://www.haomeiwen.com/subject/cohllltx.html