前序、中序、后序、层次遍历(超详细解答,实例含代码

关于前序、中序、后序、层次遍历完整代码放在文章末尾:


书上的概念emmm(虽然看了概念,但是很迷糊,可能是我有点莽,还是实例好理解):

前序遍历

1.访问根节点
2.前序遍历左子树
3.前序遍历右子树
(所以到底是怎么遍历的嘛,,,o( ̄︶ ̄)o
看图在这里插入图片描述

前序遍历:
对于所遍历的当前节点,直接输出,然后先找它的左孩子,最后找它的右孩子。
注意,我的意思是说找到它的左孩子,那么更新它的左孩子为当前节点,又从左孩子
的左孩子开始找
那么当它左孩子这条线的所有后代都遍历完全了才去遍历祖宗的右孩子

具体过程如下:

前序遍历顺序结果:1 2 4 8 10 5 3 6 7 91)输出 11是根节点,遍历左孩子22)输出 2:遍历左孩子43)输出 4:没有左孩子,遍历右孩子84)输出 8:没有左孩子,输出右孩子105)输出10:没有孩子,回到父节点,父节点遍历完全,回到祖父节点,
            祖父节点遍历完全,再回到曾祖父节点2,因为2已经遍历过
            左孩子,所以遍历右孩子56)输出 5:没有孩子。往上一辈走。
(7)输出 3:输出左孩子68)输出 6:没有孩子,回到父节点3,遍历右孩子
(9)输出 7:只有左孩子,输出左孩子910)输出 9:遍历完毕

前序遍历代码:

template<class T>
void binaryTree<T>::preOrder(binaryTreeNode<T> *t)
{// Preorder traversal.
   if (t != NULL)
   {
      counts[(t->element)-1]=treeCount(t);
      deep[(t->element)-1]=height(t);
      binaryTree<T>::visit(t);
      preOrder(t->leftChild);
      preOrder(t->rightChild);
   }
}

中序遍历

1.中序遍历左子树
2.访问根节点
3.中序遍历右子树
(所以概念是在干嘛,我还是木知,继续实例
在这里插入图片描述

中序遍历:
对于所遍历的当前节点,先找出它的左孩子输出,再输出它本身,
最后找出它的右孩子。我的意思就是你需要一直找到最晚辈的左边,然后输出它,
再把最晚辈的第一个祖宗的右孩子输出。(有点抽象,看实例.原来书上的概念就是
让你好好理解子树和树,根,理解了应该莫得问题

具体过程如下:

中序遍历:4 8 10 2 5 1 6 3 9 71)输出 41的左孩子22的左孩子44没有左孩子,输出,再看4的右孩子8
     为当前节点。8没有左孩子,输出
(2)输出 88的右孩子103)输出 10:回到自己的祖宗22的左子树遍历完全,输出
(4)输出 2:再看右子树, 只有一个右孩子,输出
(5)输出 5:找祖宗,发现1的左子树遍历完全
(6)输出 1:找1的右晚辈(右子树),右孩子33有左孩子,左孩子没孩子,输出
(7)输出 66的父亲38)输出 33的右孩子7,但是7有左孩子99)输出 99的父亲710)输出 7:遍历完全

中序遍历代码:

template<class T>
void binaryTree<T>::inOrder(binaryTreeNode<T> *t)
{// Inorder traversal.
   if (t != NULL)
   {
      inOrder(t->leftChild);
      binaryTree<T>::visit(t);
      inOrder(t->rightChild);
   }
}

后序遍历

1.后序遍历左子树
2.后序遍历右子树
3.访问根节点(看完了前两个讲解,我认为你应该对概念有意识了吧,
还木有???我们继续,谁让文章题目叫做超详细呢,╭(╯^╰)╮
在这里插入图片描述

后序遍历:
    对于当前节点,先找出它的左晚辈(左子树),再找出它的右晚辈,最后输出它
    自己。我的意思就是对于当前节点,我就从它开始,找它左孩子,再看它左孩子
    有木有孩子,左孩子那边找完了,再找右边,右边找完了,就是它自己。
    Do you understand?(木有???

具体过程如下:

后序遍历:10 8 4 5 2 6 9 7 3 11)输出 101是老祖宗,找它最左晚辈44木有左孩子,找4的右孩子88木有左孩子,找8的右孩子1010没有孩子,输出
(2)输出 810的父亲,找到8的父亲43)输出 44的父亲是2,但是2还有右孩子,输出54)输出 5:再找5的父亲
(5)输出 2:发现2的父亲1是老祖宗,那么整棵树的左子树就遍历完了,遍历右子树
(6)输出 61的左孩子33的左孩子66木有孩子,只能输出,3有右孩子呀,所以
     更新3的右孩子为当前节点,继续往下找
(7)输出 99没有孩子
(8)输出 779的父亲,3的孩子呀,孙子呀等就遍历完了
(9)输出 3:发现只剩下老祖宗了,肯定要输出吧
(10)输出 1

后序遍历代码:

template<class T>
void binaryTree<T>::postOrder(binaryTreeNode<T> *t)
{// Postorder traversal.
   if (t != NULL)
   {
      postOrder(t->leftChild);
      postOrder(t->rightChild);
      binaryTree<T>::visit(t);
   }
}

层次遍历

1.层次遍历当前层(从左至右
2.层次遍历下一层
(-_-|| ,大概概念是这个,话不多说,看图有真相
在这里插入图片描述

层次遍历:
比前面3种遍历简单得多,但是代码有点困难。
就是从当前层最左节点开始,一直往其右边找点。找完了就进入下一层

具体过程如下:

层次遍历:1 2 3 4 5 6 7 8 9 101)输出 1:第一层只有 1,进入下一层
(2)输出 2:第二层有232是最左端,3是最右端
(3)输出 3:进入下一层
(4)输出 4:第三层有4个元素,4是最左端,7是最右端,依次输出
(5)输出 56)输出 67)输出 7:进入下一层
(8)输出 8:第四层有2个元素
(9)输出 9:进入下一层
(10)输出 10:最后一层,只有一个元素,遍历完

层次遍历代码:

template <class T>
void binaryTree<T>::levelOrder()
{// Level-order traversal.
 binaryTreeNode <T>* q[treeSize];
   q[0]=root;//起始元素肯定是根
   cout<<q[0]->element<<" ";
   for(int i=1;i<treeSize;i++)//遍历每一个元素
   {
     int index=0;//定义一个索引
     while(q[index]==NULL||q[index]->leaves==1)
     {
      index++;
  }
     if(i%2!=0)
     {
      q[i]=q[index]->leftChild;
      if(q[i]!=NULL)
       cout<<q[i]->element<<" ";
     }
     else
     {
      q[i]=q[index]->rightChild;
      q[index]->leaves=1;
      if(q[i]!=NULL)
       cout<<q[i]->element<<" ";
  }
   }
}

实例完整代码

题目
创建二叉树类。二叉树的存储结构使用链表。提供操作:前序遍历、中序遍历、后序遍历、层次遍历、计算二叉树结点数目、计算二叉树高度。

输入格式
第一行为一个数字n (10<=n<=100000),表示有这棵树有n个节点,编号为1~n。
之后n行每行两个数字,第 i 行的两个数字a、b表示编号为 i 的节点的左孩子节点为 a,右孩子节点为 b,-1表示该位置没有节点。
保证数据有效,根节点为1。
输出格式
第一行,n个数字,表示该树的层次遍历。
第二行,n个数字,第i个数字表示以 i 节点为根的子树的节点数目。
第三行,n个数字,第i个数字表示以 i 节点为根的子树的高度。

输入:
5
2 3
4 5
-1 -1
-1 -1
-1 -1

输出:
1 2 3 4 5
5 3 1 1 1
3 2 1 1 1

输入:
5
3 2
-1 -1
4 5
-1 -1
-1 -1

输出:
1 3 2 4 5
5 1 3 1 1
3 1 2 1 1

输入:
10
2 -1
4 3
6 -1
5 8
9 7
-1 -1
-1 -1
-1 -1
10 -1
-1 -1

输出:
1 2 4 3 5 8 6 9 7 10
10 9 2 6 4 1 1 1 2 1
6 5 2 4 3 1 1 1 2 1

#include<iostream>
using namespace std;
int counts[999999];
int deep[999999];
template<class T>
struct binaryTreeNode
{
   T element;int leaves;
   binaryTreeNode<T> *leftChild,*rightChild;  //左子树和右子树 
};
template<class T>
void erase(binaryTreeNode<T>*& proot)
{
 if(proot!=NULL)
 {
  erase(proot->leftChild);
  erase(proot->rightChild);
  delete proot;
  proot=NULL;
 }
}
template<class T>
class binaryTree{
 public:
 binaryTree(){root=NULL;treeSize=0;}//构造函数 
 ~binaryTree(){erase(root);}//析构函数 
 bool empty() const{return treeSize==0;}
 int size() const{return treeSize;}
 binaryTreeNode<T>** rootElement(){return &root;}
 void makeTree(T* elem,int n);
 void preOrder(binaryTreeNode<T>* t);
 void inOrder(binaryTreeNode<T>* t);
 void postOrder(binaryTreeNode<T>* t);
 int treeCount(binaryTreeNode<T> * t);
 void levelOrder();
 int height(binaryTreeNode<T> *t);
 private:
   binaryTreeNode<T> *root;           
      int treeSize;                     
      static void (*visit)(binaryTreeNode<T>*); 
}; 
template<class T>
void (*binaryTree<T>::visit)(binaryTreeNode<T>*);
template<class T>
int binaryTree<T>::treeCount(binaryTreeNode<T> * t)
{
 int n=0;
 if(t!=NULL)
 {
  n=treeCount(t->leftChild)+treeCount(t->rightChild)+1;
 }
 return n;
}
template<class T>
void binaryTree<T>::makeTree(T* elem,int n)
{
 binaryTreeNode <T>** (array[n/2])={};
    array[0]=&root;
    root=new binaryTreeNode<T>;
 root->element=elem[0];
 root->leftChild=NULL;
 root->rightChild=NULL;
 root->leaves=0;
 for(int i=1;i<n;i++)
 {
  int index=(i-1)/2;
  binaryTreeNode<T>* p=new binaryTreeNode<T>;
  if(elem[i]!=-1)
  {
   p->element=elem[i];
   p->leftChild=NULL;
   p->rightChild=NULL;
   p->leaves=0;
  }
  else
   p=NULL;
  if(i%2!=0)
  {
   (*array[index])->leftChild=p;
   if(p!=NULL)
    array[(p->element)-1]=&((*array[index])->leftChild);
  }
  else
  {
   (*array[index])->rightChild=p;
   if(p!=NULL)
    array[(p->element)-1]=&((*array[index])->rightChild);
  } 
    }
    treeSize=n;
}
template<class T>
void binaryTree<T>::preOrder(binaryTreeNode<T> *t)
{// Preorder traversal.
   if (t != NULL)
   {
      counts[(t->element)-1]=treeCount(t);
      deep[(t->element)-1]=height(t);
      //binaryTree<T>::visit(t);
      preOrder(t->leftChild);
      preOrder(t->rightChild);
   }
}
template<class T>
void binaryTree<T>::inOrder(binaryTreeNode<T> *t)
{// Inorder traversal.
   if (t != NULL)
   {
      inOrder(t->leftChild);
      binaryTree<T>::visit(t);
      inOrder(t->rightChild);
   }
}
template<class T>
void binaryTree<T>::postOrder(binaryTreeNode<T> *t)
{// Postorder traversal.
   if (t != NULL)
   {
      postOrder(t->leftChild);
      postOrder(t->rightChild);
      binaryTree<T>::visit(t);
   }
}
template <class T>
void binaryTree<T>::levelOrder()
{// Level-order traversal.
 binaryTreeNode <T>* q[treeSize];
   q[0]=root;
   cout<<q[0]->element<<" ";
   for(int i=1;i<treeSize;i++)//
   {
     int index=0;
     while(q[index]==NULL||q[index]->leaves==1)
     {
      index++;
  }
     if(i%2!=0)
     {
      q[i]=q[index]->leftChild;
      if(q[i]!=NULL)
       cout<<q[i]->element<<" ";
     }
     else
     {
      q[i]=q[index]->rightChild;
      q[index]->leaves=1;
      if(q[i]!=NULL)
       cout<<q[i]->element<<" ";
  }
   }
}
template <class T>
int binaryTree<T>::height(binaryTreeNode<T> *t)
{// Return height of tree rooted at *t.
   if (t == NULL)
      return 0;                    // empty tree
   int hl = height(t->leftChild);  // height of left
   int hr = height(t->rightChild); // height of right
   if (hl > hr)
      return ++hl;
   else
      return ++hr;
}
int main()
{
    int n;
 cin>>n;
 int *tr=new int[2*n+1];
 binaryTree<int> tre;
 tr[0]=1;
 for(int i=1;i<=(2*n);i++)
 {
  cin>>tr[i];
 }
 tre.makeTree(tr,2*n+1);
 tre.levelOrder();
 cout<<endl;
 binaryTreeNode<int>* node=*tre.rootElement();
 tre.preOrder(node);
 for(int i=0;i<n;i++)
  cout<<counts[i]<<" ";
 cout<<endl;
 for(int i=0;i<n;i++)
  cout<<deep[i]<<" "; 
 return 0;
} 
发布了45 篇原创文章 · 获赞 0 · 访问量 776
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 书香水墨 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览