二叉树

定义

一棵二叉树t是有限个元素的几何(可以为空)。当二叉树非空时,其中有一个元素称为,余下的元素(如果有的话)被划分为两棵二叉树,分别称为t的左子树右子树

特性

  • 一棵二叉树有n个元素,n>0,它有n-1条边;
  • 一棵二叉树的高度为h,h>=0,它最少有h个元素,最多有2^h-1个元素;
  • 一棵二叉树有n个元素,n>0,它的最大高度为n,最小高度为[log(n+1)];
  • 设完全二叉树的一个元素其编号为i,1<=i<=n。有以下关系成立:
    1)如果i=1,则该元素为二叉树的根。若i>1,则其父节点的编号为[i/2];
    2)如果2i>n,则该元素无左孩子。否则,其左孩子的编号为2i;
    3)如果2i+1>n,则该元素无右孩子。否则,其右孩子的编号为2I+1。

链表描述

链表二叉树的节点结构

template<class T>
struct binaryTreeNode
{
   T element;
   binaryTreeNode<T>* leftChild;//左子树
   binaryTreeNode<T>* rightChild;//右子树
   binaryTreeNode(){leftChild=rightChild=null}
   binaryTreeNode(const T& theElement)
   {
      element(theElement)
      leftChild=rightChild=null;
   }
   binaryTreeNode(const T& theElement,binaryTreeNode* theLeftChild,binaryTreeNode* theRightChild)
   {
      element(theElement)
      leftChild=theLeftChild;
      rightChild=theRightChild;
   }
}

二叉树遍历

有4种遍历二叉树的常用方法:

  • 前序遍历
  • 中序遍历
  • 后序遍历
  • 层次遍历

前序遍历

template <class T>
void preOrder(binaryTreeNode<T> *t)
{
   if(t!=nullptr)
   {
     visit(t);//访问树根
     preOrder(t->leftChild);//前序遍历左子树
     preOrder(t->rightChild);//前序遍历右子树
   }
}

中序遍历

template <class T>
void inOrder(binaryTreeNode<T> *t)
{
   if(t!=nullptr)
   {
     inOrder(t->leftChild);//中序遍历左子树
     visit(t);//访问树根
     inOrder(t->rightChild);//中序遍历右子树
   }
}

后序遍历

template <class T>
void postOrder(binaryTreeNode *t)
{
     postOrder(t->leftChild);//后序遍历左子树
     postOrder(t->rightChild);//后序遍历右子树
     visit(t);//访问树根
}

层次遍历

template<class T>
void levelOrder(binaryTreeNode<T> *t)
{
   arrayQueue<binaryTreeNode<T>*> q;
   while(t!=nullptr)
   {
      visit(t);//访问树根
      if(t->leftChild!=null)
          q.push(t->leftChild);
      if(t->rightChild!=null)
          q.push(t->leftChild);
   }
   try{t=q.front();}
   catch(queueEmpty)
      {return 0;}
      q.pop();
}

visit函数

template<class T>
void visit(binaryTreeNode<T>* x)
{
   cout<<x->element<<' ';
}

复杂度分析

设一棵二叉树有n个元素。这四种遍历算法的空间和时间复杂度都是O(n)。
1. 空间需求:
1)高度为n时。前序、中序和后序的所需的递归栈空间是O(n)。
2)满二叉树时,层次遍历所需的队列空间为O(n)
2. 时间需求:假设访问一个节点时间是O(1),每一个遍历花在一个节点上的时间为O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值