【劍指offer】從上向下列印二叉樹
轉載請註明出處:http://blog.csdn.net/ns_code/article/details/26089165
劍指offer上的第23題,實際上就是考察二叉樹的層序遍歷,具體思想可以參考這裡。
- 題目描述:
從上往下列印出二叉樹的每個節點,同層節點從左至右列印。
- 輸入:
輸入可能包含多個測試樣例,輸入以EOF結束。
對於每個測試案例,輸入的第一行一個整數n(1<=n<=1000, :n代表將要輸入的二叉樹元素的個數(節點從1開始編號)。接下來一行有n個數字,代表第i個二叉樹節點的元素的值。接下來有n行,每行有一個字母Ci。
Ci=’d’表示第i個節點有兩子孩子,緊接著是左孩子編號和右孩子編號。
Ci=’l’表示第i個節點有一個左孩子,緊接著是左孩子的編號。
Ci=’r’表示第i個節點有一個右孩子,緊接著是右孩子的編號。
Ci=’z’表示第i個節點沒有子孩子。
- 輸出:
對應每個測試案例,
按照從上之下,從左至右列印出二叉樹節點的值。
- 樣例輸入:
7 8 6 5 7 10 9 11 d 2 5 d 3 4 z z d 6 7 z z
- 樣例輸出:
8 6 10 5 7 9 11
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
/*
二叉樹的儲存結構
*/
typedef struct BTNode
{
int data;
int rchild;
int lchild;
}BTNode;
/*
佇列的儲存結構
*/
typedef struct Node
{
BTNode data;
struct Node *pNext;
}NODE,*PNODE;
typedef struct Queue
{
PNODE front; //隊頭指標
PNODE rear; //隊尾指標
}QUEUE,*PQUEUE;
/*
建立一個空佇列,隊頭指標和隊尾指標都指向頭結點,
頭結點中不存放資料,只存放指標
*/
PQUEUE create_queue()
{
PQUEUE pS = (PQUEUE)malloc(sizeof(QUEUE));
pS->front = (PNODE)malloc(sizeof(NODE));
if(!pS || !pS->front)
{
printf("pS or front malloc failed!!");
exit(-1);
}
else
{
pS->rear = pS->front;
pS->front->pNext = NULL;
}
return pS;
}
/*
判斷佇列是否為空
*/
bool is_empty(PQUEUE pS)
{
if(pS->front == pS->rear)
return true;
else
return false;
}
/*
進隊函式,從隊尾進隊,隊頭指標保持不變
*/
void en_queue(PQUEUE pS, BTNode e)
{
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if(!pNew)
{
printf("pNew malloc failed");
exit(-1);
}
else
{
pNew->data = e;
pNew->pNext = NULL;
pS->rear->pNext = pNew;
pS->rear = pNew;
}
return;
}
/*
出隊函式,從隊頭出隊,隊尾指標保持不變,但當最後一個元素出隊時,
需要對隊尾指標重新賦值,使其指向頭結點
*/
bool de_queue(PQUEUE pS,BTNode *pData)
{
if(is_empty(pS))
return false;
else
{
PNODE p = pS->front->pNext;
*pData = p->data;
pS->front->pNext = p->pNext;
//這裡是佇列頭元素出隊的特殊情況,一般情況下,刪除隊頭元素時
//僅需修改頭結點中的指標,但當佇列中最後一個元素被刪除時,
//佇列尾指標也丟失了,因此需對隊尾指標重新賦值(指向頭結點)。
if(pS->rear == p)
pS->rear = pS->front;
free(p);
}
return true;
}
/*
銷燬佇列,頭結點也被銷燬,最後也將pS節點銷燬,並將其指向為空,避免垂直指標的產生
*/
void destroy_queue(PQUEUE pS)
{
if(is_empty(pS))
return;
else
{
while(pS->front)
{
pS->rear = pS->front->pNext;
free(pS->front);
pS->front = pS->rear;
}
}
free(pS);
pS = 0;
return;
}
/*
層序遍歷二叉樹
*/
void LevelTraverse(BTNode *pTree,int index,int *LevTraverse,int n)
{
if(pTree == NULL)
return;
if(index == -1)
return;
BTNode pBTNode;
PQUEUE pS = create_queue();
en_queue(pS, pTree[0]);
int i = 0;
while(!is_empty(pS) && i<n)
{
de_queue(pS,&pBTNode);
//同樣,先把元素按層序遍歷的順序儲存起來
LevTraverse[i++] = pBTNode.data;
if(pBTNode.lchild != -1)
en_queue(pS, pTree[pBTNode.lchild]);
if(pBTNode.rchild != -1)
en_queue(pS, pTree[pBTNode.rchild]);
}
destroy_queue(pS);
}
int main()
{
int n;
while(scanf("%d",&n) != EOF)
{
//輸入樹pTree各節點的值
BTNode *pTree = NULL;
if(n>0)
{
pTree = (BTNode *)malloc(n*sizeof(BTNode));
if(pTree == NULL)
exit(EXIT_FAILURE);
int i,data;
//輸入n個節點的data
for(i=0;i<n;i++)
{
scanf("%d",&data);
pTree[i].data = data;
pTree[i].rchild = -1;
pTree[i].lchild = -1;
}
//輸入n行節點連線關係
for(i=0;i<n;i++)
{
char ci;
//這兩行的作用是為了跳過緩衝區中的換行符
//這裡不能用fflush(stdin),gcc不支援,這只是一些編譯器自加的,
//如果用了,測試系統會報RE。
while(getchar() != '\n')
continue;
scanf("%c",&ci);
if(ci == 'z')
continue;
else if(ci == 'l')
{
int lindex;
scanf("%d",&lindex);
pTree[i].lchild = lindex-1;
}
else if(ci == 'r')
{
int rindex;
scanf("%d",&rindex);
pTree[i].rchild = rindex-1;
}
else if(ci == 'd')
{
int lindex,rindex;
scanf("%d",&lindex);
scanf("%d",&rindex);
pTree[i].lchild = lindex-1;
pTree[i].rchild = rindex-1;
}
}
}
//先將遍歷的元素依次儲存到preTraverse陣列中
int *LevTraverse = (int *)malloc(n*sizeof(int));
if(LevTraverse == NULL)
exit(EXIT_FAILURE);
LevelTraverse(pTree,0,LevTraverse,n);
int i;
for(i=0;i<n;i++)
{
//使輸出符合測試系統要求的格式
if(i == n-1)
printf("%d\n",LevTraverse[i]);
else
printf("%d ",LevTraverse[i]);
}
free(LevTraverse);
LevTraverse = NULL;
free(pTree);
pTree = NULL;
}
return 0;
}
/**************************************************************
Problem: 1523
User: mmc_maodun
Language: C
Result: Accepted
Time:0 ms
Memory:916 kb
****************************************************************/
相關文章
- 劍指offer——從上往下列印二叉樹C++二叉樹C++
- [劍指offer] 把二叉樹列印成多行二叉樹
- 劍指 Offer 32 - III. 從上到下列印二叉樹 III二叉樹
- LeetCode 劍指offer——從上到下列印二叉樹 II、從上到下列印二叉樹 IIILeetCode二叉樹
- 《劍指offer》:[60]把二叉樹列印成多行二叉樹
- 【劍指offer】5.二叉樹的映象和列印二叉樹
- 劍指offer(C++)——把二叉樹列印成多行C++二叉樹
- 劍指 Offer 32 - I. 從上到下列印二叉樹(java解題)二叉樹Java
- 劍指offer——重建二叉樹二叉樹
- 【劍指offer】二叉樹深度二叉樹
- 劍指offer--把二叉樹列印成多行(C++)二叉樹C++
- 《劍指offer》:[61]按之字形順序列印二叉樹二叉樹
- 劍指offer(四)重建二叉樹二叉樹
- 劍指 Offer 32 - II. 從上到下列印二叉樹 II 做題筆記二叉樹筆記
- 劍指offer刷題筆記-32.從上到下列印二叉樹 進階筆記二叉樹
- 劍指 Offer 07. 重建二叉樹二叉樹
- 【劍指offer】判斷二叉樹平衡二叉樹
- 劍指Offer-40-二叉樹的深度二叉樹
- 劍指offer——二叉樹的映象C++二叉樹C++
- 【劍指offer】27. 二叉樹的映象二叉樹
- 劍指offer——二叉樹的深度C++二叉樹C++
- 《劍指offer》:[59]對稱的二叉樹二叉樹
- 《劍指offer》:[39]求解二叉樹的深度二叉樹
- 《劍指offer》:[62]序列化二叉樹二叉樹
- 劍指offer | 55 - I. 二叉樹的深度二叉樹
- 力扣 - 劍指 Offer 27. 二叉樹的映象力扣二叉樹
- 劍指OFFER-從頭到尾列印連結串列(Java)Java
- # 劍指 Offer 68 - II. 二叉樹的最近公共祖先二叉樹
- 《劍指offer》之在完全二叉樹中新增子節點二叉樹
- 《劍指offer》:[58]二叉樹的下一個結點二叉樹
- 劍指 Offer 列印從1到最大n位數c++C++
- 劍指offer-從尾到頭列印連結串列-phpPHP
- 劍指offer之順序列印陣列陣列
- 【劍指offer】順時針列印矩陣矩陣
- 《劍指offer》:[39-1]判斷是否為平衡二叉樹二叉樹
- 【劍指offer】二叉樹中和為某一值的路徑二叉樹
- 【劍指offer】樹的子結構
- 22.從上往下列印二叉樹二叉樹