關於完全二叉樹的一道面試題

2021-10-04 01:21:10 字數 3346 閱讀 8651

存在一棵完全二叉樹,從鍵盤輸入一組資料,並將資料從二叉樹的根結點順序存入每個結點 ,輸出從根結點到葉結點最大的路徑長度。

輸入第一行為完全二叉樹的結點數 n。

輸入第二行為對應的的所有整數,用空格隔開。

輸出最大的路徑長度

輸入:7

5 4 3 10 5 9 2

輸出:19

1、該題目實際上是有一定難度的,需要邊建立二叉樹一邊賦值,而且數值並不是已經存好的數值,需要在程式執行時手動輸入,如果用遞迴的方法建樹,結點賦值就會出現乙個很大的問題,所以,本題目不考慮遞迴方法。

2、可以動態創立一組長度為n

nn的二叉樹型別陣列,可以一邊建立結點,一邊為從鍵盤上為結點賦值,再通過完全二叉樹的性質,更改父結點左右指標的指向即可建立二叉樹,這樣就為動態的為結點插入資料提供了便利。

3、本題目要求返回二叉樹的最大帶權路徑長度(區別於哈夫曼樹中的帶權路徑長度(wpl)的定義,該問題不乘路徑長度值),即二叉樹中結點數值之和最大的路徑,思路可以是一邊在父結點指標指向左右孩子結點,一邊用乙個陣列記錄父結點與其孩子結點的權值累加,這樣在建立二叉樹結束後,陣列中就可以記錄每乙個葉子結點到父結點的路徑之和,返回最大值即可。

4、搞懂本題目的同學可以清楚地知道,只要建立乙個int型別的陣列,然後通過完全二叉樹的性質,用另乙個陣列記錄葉子結點到父結點的權值之和即可,完全沒有必要建立二叉樹結點這一系列工作。對,你的想法是正確的,我之所以這麼寫,是為了讓你了解二叉樹的相關知識而已。

#define _crt_secure_no_warnings 

// 也可以將該巨集定義放入到vs專案的屬性中

#include

#include

#include

typedef

struct bitnode

bitnode,

*bitree;

bitree createbitree

(int n,

int* arr)

// 建立結點數為n的完全二叉樹

printf

("請依次輸入%d個整數:\n"

, n)

;int num =0;

// 用於存放鍵盤中輸入的資料

for(

int i =

0; i < n; i++

)// 將n個整數存放在了bitree型別的陣列中,即每個結點已經存放好資料

for(

int i =

0; i <= n /2-

1; i++

)//迴圈建立完全二叉樹if(

2* i +

2<= n -1)

}return bitreearr;

// 返回二叉樹頭結點

}int

maxlength

(int

* arr,

int n)

// 返回陣列中的最大值

}return maxlength;

// 返回陣列中的最大值 即為二叉樹最大路徑長度

}int

main()

int* arr =

(int*)

malloc

(sizeof

(int

)* n)

;// 可以用malloc開闢陣列長度 但a[n]是錯誤的語法

bitree =

createbitree

(n, arr)

;//建立結點為n的完全二叉樹 用arr陣列記錄根結點到任意結點的路徑長度

maxlength =

maxlength

(arr, n)

;// 返回路徑長度的最大值

printf

("該完全二叉樹的最大路徑長度是:%d\n"

, maxlength)

;system

("pause");

return0;

}

用遞迴的方法如下,是不提倡的

// 這種方法不利於本題目的求解

void

createbitree

(bitree bitree,

int n)

// 建立結點數為n的完全二叉樹

i++;if

(i == n)

createbitree

(bitree->left, n)

;createbitree

(bitree->right, n)

;}

1、用二級指標開闢結點陣列

bitree* bitreearr =

(bitree*

)malloc

(sizeof

(bitree)

* n)

;

用這種方法建立的是n個指向二叉樹結點型別的指標變數,如果用每乙個指標指向其餘結點是完全沒問題的,但對於本題目,不合適,這樣做沒有建立結點,不能執行賦值等其他操作。

2、如何一邊插入數值一邊建立結點是本題的難點,所以我認為本題目不適合用遞迴方法來解答。

3、曾經看過一本名叫《征服c指標》一書,其中作者將陣列型別叫做指標型別的語法糖,具體含義就是用指標定義陣列,尋找陣列中的值對於c語言來說速度更快,但用[ ]來尋找陣列中的值對於人類來說更好理解,所以陣列型別可以是指標型別的昇華,名為語法糖。

int a[10]

;for

(int i =

0; i <

10; i++

)scanf

("%d "

,&a[i]);

// 需要取位址

for(

int i =

0;i <

10; i++

)printf

("%d "

, a[i]);

int* a =

(int*)

malloc

(sizeof

(int)*

10);// 與 a[10]; 等同

for(

int i =

0;i <

10;i++

)scanf

("%d"

,(a + i));

// 是指標型別

for(

int i =

0;i <

10;i++

)printf

("%d ",*

(a + i));

// 與 a[i] 等同

上面兩者的實現效果是一樣的。

4、本題目原本是上機考試,使用的是oj系統,所以答案不會這麼複雜,我這樣寫的目的是更好的掌握每乙個知識點。通過main函式呼叫api函式,模組化設計,也是c語言的靈魂所在。

阿里一道面試題 完全二叉樹的最後一顆節點

今天和朋友聊天,說是阿里有道面試題。已知一顆完全二叉樹,有n個節點 求最後乙個節點,亦即最後一排最右邊的那個節點。節點數目2 0 2 k 1 n 2 0 2 1 2 2 2 3 2 k 那麼樹深為k 1,最後個節點在最後層為第 n 2 0 2 k 1 個 如果 n 2 0 2 k 1 2 k 2,那...

二叉樹面試題

1.求二叉樹節點個數 可以使用遞迴解決。將問題分解為求根節點 左子樹的節點數 右節點的節點數。實現 public size t size private size t size node root 2.求頁節點個數 頁節點 左右子樹都為空的節點被稱為頁節點,使用遞迴遍歷,當碰到乙個左右子樹為空的節點...

面試題 二叉樹

面試題 二叉樹 1.重建二叉樹 前序 中序 treenode reconstructbinarytree vector pre,vector vin treenode root new treenode pre 0 int pos 0 for pos pre left,vin left,pre ri...