二叉樹的層序遍歷

1.      問題描述
      使用隊列做爲輔助存儲,按樹的結點的深度,從根開始依次訪問全部結點。

2.問題分析與算法描述算法

         所謂層序遍歷,就是按照二叉樹的節點深度,將處於每一層,也就是節點深度相同的節點按照從左到右的順序依次訪問。咱們以前所作的先序遍歷,中序 以及後序遍歷能夠經過遞歸以及調整訪問的順序便可實現,可是層序遍歷則不行,層序遍歷必需要從上到下,從左到右依次訪問,遞歸的話會倒序訪問也就 是直到遞歸結束時回溯訪問,這顯然實現層序遍歷是不行的,對於一課樹當咱們訪問到一個節點是若是這個節點比其餘節點先訪問,則他的兒子也必定比其  他節點的兒子優先訪問,這樣咱們就能夠在訪問一個節點的時候把他的左兒子右兒子一次保存,而後訪問下一個節點的時候咱們就從保存的節點中取出訪   問,知道把全部的節點「存儲-訪問」完成爲止。這就要求咱們的所用的輔助存儲結構可以先存儲的先訪問,這種特色就能夠用用隊列知足。設計

下面是算法步驟:code

   1)根節點入隊 遞歸

   2)將節點出隊,若是該節點有兒子,按照從左到右的順序入隊隊列

   3)判斷隊列是否爲空,若爲空,則訪問結束,不然轉到2element

3.算法實現it

   因爲要用到隊列,按照算法的設計,須要用到隊列的入隊,出隊,以及爲空判斷的操做,因爲不一樣的樹的高度未知,每一層的節點數量不一樣,所以入隊的節點的個數就不肯定。咱們能夠經過循環利用隊列來儘量的充分利用隊列的存儲空間,這種循環能夠經過對隊列的空間長度取餘實現io

下面是實現隊列相關操做的例程:class

/*
*功能:二叉樹的層序遍歷
*做者:KDF5000
*時間:2013.1.18
*/
#include<stdio.h>
#include<stdlib.h>
typedef  struct treeNode *Node;

struct treeNode{
    int element;
	treeNode *left;
	treeNode *right;
};

struct Queue{
	int size;
	int head;
	int tail;
	treeNode *que;
};

Queue * initQueue(int qSize)
{
    Queue *Q;
	Q=(Queue *)malloc(sizeof(Queue));
	Q->size=qSize;
    Q->que=(treeNode *)malloc(sizeof(treeNode)*qSize);
	Q->head=qSize;
	Q->tail=0;
    return Q;
}
//判斷隊列是否爲空
int isEmpty(Queue *Q)
{
	return Q->head%(Q->size)==Q->tail;
}
//入隊
void pushQue(Queue *Q,treeNode *p)
{
	*(Q->que+Q->tail++)=*p;
	Q->tail %=Q->size;
}
//出隊
treeNode * popQue(Queue *Q)
{
	Q->head %=Q->size;
    return Q->que+(Q->head ++);
}
//層序遍歷
void traverse(treeNode *tree)
{
  Queue  *Q=NULL;
  treeNode *p;
  Q=initQueue(20);
  pushQue(Q,tree);
  printf(" [");
  while(!isEmpty(Q))
  {
	p=popQue(Q);
	printf("%d,",p->element);
	if(p->left!=NULL)
      pushQue(Q,p->left);
	if(p->right!=NULL)
	  pushQue(Q,p->right);
  }
  printf("]\n");
}
//插入節點
treeNode *insert(treeNode *tree,int element)
{
	if(tree==NULL)
	{
        treeNode *newNode=(treeNode *)malloc(sizeof(treeNode));
		if(newNode==NULL)
			return newNode;
        newNode->element=element;
		newNode->left=NULL;
		newNode->right=NULL;
		tree=newNode;
		return tree;
	}
	if(tree->element>=element)
          tree->left=insert(tree->left,element);
	else
          tree->right=insert(tree->right,element);
	return tree;
}
//構造一個二叉樹amount爲想要隨機生成的二叉樹的節點個數
treeNode * creatTree(int amount)
{
   treeNode *tree=NULL;
   for(int i=0;i<amount;i++)
   {
       tree=insert(tree,rand()%50);
   }
   return tree;
}
//先序輸出
void outputPre(treeNode * tree)
{
	if(tree==NULL)
		printf("空樹!!!");
	else
	{
		printf("%d,",tree->element);
		if(tree->left!=NULL)
			outputPre(tree->left);
		if(tree->right!=NULL)
			outputPre(tree->right);
	}
}
//中序輸出全部節點
void outputMid(treeNode *tree)
{
	if(tree==NULL)
		printf("空樹!!!");
	else
	{
		if(tree->left!=NULL)
			outputMid(tree->left);
		printf("%d,",tree->element);
		if(tree->right!=NULL)
			outputMid(tree->right);
	}
}

void main()
{
  treeNode *tree=creatTree(10);
  if(tree==NULL)
	  return;
  printf("先序遍歷結果:\n");
  printf(" [");
  outputPre(tree);
  printf("]\n");
  printf("中序遍歷結果:\n");
  printf(" [");
  outputMid(tree);
  printf("]\n");
  printf("層序遍歷結果:\n");
  traverse(tree);
}


5.實際運行結果二叉樹

下面是隨機構造的一個節點數爲10 的二叉樹的遍歷結果:

相關文章
相關標籤/搜索