1. 程式人生 > >真題2004 (非)遞迴層次列印完全二叉樹所有元素

真題2004 (非)遞迴層次列印完全二叉樹所有元素

題目:一棵完全二叉樹結點按層次自上而下,自左而右儲存在一維陣列A[1:n]中(設結點的值為整數)。設計兩個函式(或過程),分別實現下列功能。 (1)按層次依次列印完全二叉樹中所有元素,要求每個元素以一個偶對顯示(X,i),X為元素值,i為該元素在樹中的層次。要求設計為非遞迴演算法。 (2)按中序遍歷次序列印完全二叉樹中各元素。每個元素仍以上述元素值和層次的偶對顯示。要求設計為遞迴演算法。 題目分析:

  1. <方法1>層次遍歷 這個題目的意思就是輸出二叉樹的某一層的所有元素,這個首先想到的是層次遍歷,層次遍歷最簡單的方法就是用佇列實現,我們傳統的層次遍歷方法是可以輸出所有元素,那麼如何區分相鄰兩層之間的元素呢? 其實我們可以用兩個整數變數line1,line2來記錄相鄰兩層的元素個數,其中line1代表出棧那一層留下的元素個數,line2代表下一層進棧元素的個數,每當line1為0的時候,說明上一層已經全部出棧,下一層已經全部入棧,那麼層次遍歷層數就加一,這個時候將line2的值複製給line1,line2=0,當遍歷到第dep層的時候,便把那一層的所有元素輸出,停止遍歷。
classTreeLevel{
	public:
		ListNode*getTreeLevel(TreeNode*root,intdep){
			//writecodehere
			if(dep<=0||root==NULL)
				returnNULL;
			ListNode*list=newListNode(-1);
			ListNode*listHead=list;
			queue<TreeNode*>qu;
			qu.push(root);
			intlines1=1,lines2=0,num=1;
			while(!qu.empty())
			{
				if(num==dep)
				{
					for(inti=0;i<lines1;i++)
					{
						TreeNode*root1=qu.front();
						list->next=newListNode(root1->val);
						list=list->next;
						qu.pop();
					}
					returnlistHead->next;
				}
				TreeNode*root1=qu.front();
				if(root1->left)
				{
					qu.push(root1->left);
					lines2++;
				}
				if(root1->right)
				{
					qu.push(root1->right);
					lines2++;
				}
				qu.pop();
				if(--lines1==0)
				{
					lines1=lines2;
					lines2=0;
					num++;
				}
			}
			returnlistHead->next;
		}
		}
  1. 遞迴遍歷 其實也可以用遞迴遍歷實現,剛開始為深度為dep,每往下遞迴一層,則深度減一(dep=dep-1),當dep==1的時候,便輸出那個元素,如果先遞迴左子樹,那麼則實現從左到右列印,如果先遞迴右子樹,則實現從右往左列印。
在這裡插入程式碼片
classTreeLevel{
	public:
		ListNode*getTreeLevel(TreeNode*root,intdep){
			//writecodehere
			ListNode*list=newListNode(-1);
			ListNode*listHead=list;
			get1(root,list,dep);
			returnlistHead->next;
		}
		voidget1(TreeNode*root,ListNode*&list,intdep)
		{
			if(dep<=0||root==NULL)
				return;
			if(dep==1)
			{
				ListNode*listnext=newListNode(root->val);
				list->next=listnext;
				list=list->next;
				return;
			}
			get1(root->left,list,dep-1);
			get1(root->right,list,dep-1);
		}
};

分析2 二叉樹的層序遍歷演算法實現 一,問題描述:實現二叉樹的層序遍歷–從根開始,依次向下,對於每一層從左向右遍歷。 二,演算法分析 層序遍歷與先序、中序、後序遍歷不同。層序遍歷用到了佇列,而先、中、後序需要用到棧。因此,先、中、後序遍歷可以採用遞迴方式來實現,而層序遍歷則沒有遞迴方式。 演算法步驟: 初始時,根結點入佇列。然後,while迴圈判斷佇列不空時,彈出一個結點,訪問它,並把它的所有孩子結點入佇列。 三,程式碼實現 一,問題描述:實現二叉樹的層序遍歷–從根開始,依次向下,對於每一層從左向右遍歷。 二,演算法分析 層序遍歷與先序、中序、後序遍歷不同。層序遍歷用到了佇列,而先、中、後序需要用到棧。因此,先、中、後序遍歷 可以 採用遞迴方式來實現,而層序遍歷則沒有遞迴方式。 演算法步驟: 初始時,根結點入佇列 然後,while迴圈判斷佇列不空時,彈出一個結點,訪問它,並把它的所有孩子結點入佇列。 程式碼如下:

public void levelTraverse(BinarySearchTree<T> tree){
	levelTraverse(tree.root);
}
private void levelTraverse(BinaryNode<T> root){
	if(root == null)
		return;
	Queue<BinaryNode<T>> queue = new LinkedList<>();//層序遍歷時儲存結點的佇列
	queue.offer(root);//初始化
	while(!queue.isEmpty()){
		BinaryNode<T> node = queue.poll();
		System.out.print(node.element + " ");//訪問節點
		if(node.left != null)
			queue.offer(node.left);
		if(node.right != null)
			queue.offer(node.right);
	}
}