樹的遍歷總結

前序遍歷(DLR)
  前序遍歷也叫作 先根遍歷、先序遍歷,可記作根左右。
  前序遍歷首先訪問根結點而後遍歷左子樹,最後遍歷右子樹。在遍歷左、右子樹時,仍然先訪問根結點,而後遍歷左子樹,最後遍歷右子樹。
  若 二叉樹爲空則結束返回,不然:
  (1)訪問根結點。 
  (2)前序遍歷左子樹
  (3)前序遍歷右子樹 。
  須要注意的是:遍歷左右子樹時仍然採用前序遍歷方法。
  如圖所示二叉樹
  前序遍歷,也叫先根遍歷,遍歷的順序是,根,左子樹,右子樹
  遍歷結果:ABDECF
   中序遍歷,也叫 中根遍歷,順序是 左子樹,根,右子樹
  遍歷結果:DBEAFC
   後序遍歷,也叫 後根遍歷,遍歷順序,左子樹,右子樹,根

  遍歷結果:DEBFCAhtml

C語言版本

  樹中節點結構爲: node

  typedef struct TreeNode c++

  { 算法

  int data; 數組

  TreeNode * left; post

  TreeNode * right; spa

  TreeNode * parent; htm

  }TreeNode; blog

  void pre_order(TreeNode * Node) 排序

  {

  if(Node != NULL)

  {

  printf("%d ", Node->data);

  pre_order(Node->left);

  pre_order(Node->right);

  }

    }

  調用時: pre_order(Root); //Root爲樹的根

中序遍歷(LDR)

中序遍歷也叫作中根遍歷,可記作左根右。

  中序遍歷首先遍歷左子樹,而後訪問根結點,最後遍歷右子樹。在遍歷左、右子樹時,仍然先遍歷左子樹,再訪問根結點,最後遍歷右子樹。即:

  若二叉樹爲空則結束返回,

  不然:

  (1)中序遍歷左子樹。

  (2)訪問根結點。

  (3)中序遍歷右子樹。

  注意的是:遍歷左右子樹時仍然採用中序遍歷方法。

  即左子樹(B D E)仍是左邊開始(D),而後是(B),再是右邊(E),完後通過(A),接着右子樹(C F) 仍是左邊開始(F),再是中間(C),

  即順序是DBEAFC

  中序遍歷的時間複雜度爲:O(n)。

  若是一棵二叉排序樹的節點值是數值,中序遍歷的結果爲升序排列的數組。能夠利用該性質檢測一棵樹是否爲二叉排序數。

c++版本

  樹中節點結構爲:

  typedef struct TreeNode

  {

  int data;

  TreeNode * left;

  TreeNode * right;

  TreeNode * parent;

  }TreeNode;

  void middle_order(TreeNode * Node)

  {

  if(Node != NULL)

  {

  middle_order(Node->left);

  printf("%d ", Node->data);

  middle_order(Node->right);

  }

  }

  調用時: middle_order(Root); //Root爲樹的根

後序遍歷

後序遍歷是二叉樹遍歷的一種。後序遍歷指在訪問根結點、遍歷左子樹與遍歷右子樹三者中,首先遍歷左子樹,而後遍歷右子樹,最後遍歷訪問根結點,在遍歷左、右子樹時,仍然先遍歷左子樹,而後遍歷右子樹,最後遍歷根結點。後序遍歷有遞歸算法和非遞歸算法兩種。

算法描述:

  (1)若二叉樹爲空,結束

  (2)後序遍歷左子樹

  (3)後序遍歷右子樹

  (4)訪問根結點

  遍歷結果:DEBFCA

c語言描述 (遞歸)

  struct btnode

  {

  int d;

  struct btnode *lchild;

  struct btnode *rchild;

  };

  void postrav(struct btnode *bt)

  {

  if(bt!=NULL)

  {

  postrav(bt->lchild);

  postrav(bt->rchild);

  printf("%d ",bt->d);

  }

  }

非遞歸算法 

算法1(c語言描述):

  void postrav1(struct btnode *bt)

  {

  struct btnode *p;

  struct

  {

  struct btnode *pt;

  int tag;

  }st[MaxSize];

  }

  int top=-1;

  top++;

  st[top].pt=bt;

  st[top].tag=1;

  while(top>-1) /*不爲空*/

  {

  if(st[top].tag==1) /*不能直接訪問的狀況*/

  {

  p=st[top].pt;

  top--;

  if(p!=NULL)

  {

  top++; /*根結點*/

  st[top].pt=p;

  st[top].tag=0;

  top++; /*右孩子結點*/

  st[top].pt=p->p->rchild;

  st[top].tag=1;

  top++; /*左孩子結點*/

  st[top].pt=p->lchild;

  st[top].tag=1;

  }

  }

  if(st[top].tag==0) /*直接訪問的狀況*/

  {

  printf("%d ",st[top].pt->d);

  top--;

  }

  }

  }

  算法2:

  void postrav2(struct btnode *bt)

  {

  struct btnode *st[MaxSize],*p;

  int flag,top=-1;

  if(bt!=NULL)

  {

  do

  {

  while(bt!=NULL)

  {

  top++;

  st[top]=bt;

  bt=bt->lchild;

  }

  p=NULL;

  flag=1;

  while(top!=-1 && flag)

  {

  bt=st[top];

  if(bt->rchild==p)

  {

  printf("%d ",bt->d);

  top--;

  p=bt;

  }

  else

  {

  bt=bt->rchild;

  flag=0;

  }

  }

  }while(top!=-1)

  printf("\n");

  }

  }

擴展:

已知一棵二叉樹的前序遍歷序列和中序遍歷序列,能夠惟一肯定這棵二叉樹。已知一棵二叉樹的後序遍歷序列和中序遍歷序列,也能夠惟一肯定這棵二叉樹。可是,已知一棵二叉樹的前序遍歷序列和後序遍歷序列,不能惟一肯定這棵二叉樹。

相關文章
相關標籤/搜索