真題2004 (非)遞迴層次列印完全二叉樹所有元素
阿新 • • 發佈:2018-12-18
題目:一棵完全二叉樹結點按層次自上而下,自左而右儲存在一維陣列A[1:n]中(設結點的值為整數)。設計兩個函式(或過程),分別實現下列功能。 (1)按層次依次列印完全二叉樹中所有元素,要求每個元素以一個偶對顯示(X,i),X為元素值,i為該元素在樹中的層次。要求設計為非遞迴演算法。 (2)按中序遍歷次序列印完全二叉樹中各元素。每個元素仍以上述元素值和層次的偶對顯示。要求設計為遞迴演算法。 題目分析:
- <方法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; } }
- 遞迴遍歷 其實也可以用遞迴遍歷實現,剛開始為深度為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);
}
}