思路:利用陣列把二叉樹用**表示出來,例如建立下面這顆樹:
int a = ;
傳參時把陣列名、陣列下標以及非法值傳過去。invalid是『#』的ascll碼值,代表null,如果某節點的左右孩子都是『#』,那他就是葉子。
建立使用的是遞迴法,具體**實現如下:
(ps:此處傳陣列下標採用的是傳址方式,因為遞迴法會有多層函式棧幀,用傳值的方法的話,在這層函式棧幀裡修改了下標並不會影響其它棧幀裡面下標的值,那樣就會導致建立樹失敗!)
typedef
int btstdatatype;
typedef
struct binarytreenode
btnode;
btnode* buybtnode(btstdatatype x)
btnode* createbtree(btstdatatype* a, size_t* pindex, btstdatatype invalid)// 建立二叉樹
return root;
}
思路:用棧結構來實現非遞迴前序遍歷:建立乙個棧s並初始化;
從樹根開始,把1,2,3依次入棧並輸出;
訪問3的左孩子時,它為null,內層迴圈結束;
3出棧,訪問3的右孩子;
………….
void btreeprevordernonr(btnode* root)
top = stacktop(&s);
stackpop(&s);
cur = top->_right; //子問題}}
void btreeinordernonr(btnode* root)
top = stacktop(&s);
printf("%d ", top->_data);
stackpop(&s);
cur = top->_right;}}
首先 1、2、3依次入棧;
訪問3的左孩子,為null,跳出內層迴圈,top = 3;
輸出3,prev = 3,節點3出棧;
top = 2,跳過if進入else,cur = 4;
4入棧,cur = null,top = 4,prev = 4,4出棧;
top = 2,進入if,輸出2,prev = 2,2出棧;
……………….
void btreepostordernonr(btnode* w)
top = stacktop(&s);
//判斷top的右樹有沒有訪問過
if (null
== top->_right || top->_right == prev)
else}}
思路:一棵樹的節點個數 = 它左子樹節點個數 + 它右子樹節點個數 + 加它本身
size_t btreesize(btnode* root)//節點個數
//轉換成子問題:樹節點個數等於左子樹節點個數 + 右子樹節點個數 + 加自己
return btreesize(root->_left) + btreesize(root->_right) +
1;}
size_t btreeleafsize(btnode* root) //計算樹葉子的數量
if (root->_left ==
null
&& root->_right ==
null)
return btreeleafsize(root->_left) + btreeleafsize(root->_right);
}
思路:樹tree第k層節點個數 = 它左子樹第k-1層節點個數 + 它右子樹第k-1層節點個數
size_t btreeklevelsize(btnode* root, size_t k)
if (1
== k)
return btreeklevelsize(root->_left, k -
1) + btreeklevelsize(root->_right, k -
1);}
思路:一棵樹的深度 = 它左、右子樹深度較大的那個子樹的深度 + 1
size_t btreedepth(btnode* root)
size_t leftdepth = btreedepth(root->_left);
size_t rightdepth = btreedepth(root->_right);
//樹的深度 = 它左右兩個子樹深度較大的那個 + 1;
return leftdepth > rightdepth ? leftdepth +
1 : rightdepth +
1;}
btnode* btreefind(btnode* root, btstdatatype x)
if (x == root->_data)
btnode* leftret = btreefind(root->_left, x);
if (leftret !=
null)
btnode* rightret = btreefind(root->_right, x);
if (rightret !=
null)
return
null;
}
思路:建立乙個佇列q並初始化;1. 根節點1入隊,*front = 1,輸出1,1出隊;
2. 把1的左、右孩子2和5入隊;
3. *front = 2,輸出2,2出隊;
4. 把2的左、右孩子3和5入隊;
5. *front = 5,輸出5,5出隊;
6. 把5的左孩子6入隊(5的右孩子為null);
………………….
void btreelevelorder(btnode* root)
while (queueempty(&q) !=
0)
if (front->_right !=
null)}}
思路:採用和上一題相似的方法,把樹的節點按層入隊,當遇到null時,入隊部分結束,進入下乙個迴圈,把佇列裡的元素出隊,如果此時佇列的元素都是null,那這棵樹就是完全二叉樹;如果還有非空元素,那就是非完全二叉樹。
int iscompletebtree(btnode* root)// 判斷完全二叉樹
while (queueempty(&q) !=
0)
else
}while (queueempty(&q) !=
0)
queuepop(&q);
}return
1; //是完全二叉樹
}
思路:利用乙個flag變數,先還是層序的方法進出隊,遇到null時,flag = 0;如果下次再出隊的遇到非空元素且此時flag = 0,那這就是非完全二叉樹。
int iscompletebtree1(btnode* root)// flag的方式判斷 非遞迴遍歷
while (queueempty(&q) !=
0)
queuepush(&q, front->_left);
}else
if (front->_right !=
null)
queuepush(&q, front->_right);
}else
}return
1;}
二叉樹面試題
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...
保安日記之二叉樹高階面試題 上
一 前言 關於二叉樹的的基本操作以及初階的面試題在前面的部落格已經介紹完畢,這篇部落格用二叉樹這種資料結構來解決一些更加複雜的程式設計問題 二 二叉樹的層序遍歷 2.1 題目 給你乙個二叉樹,請你返回其按 層序遍歷 得到的節點值 即逐層地,從左到右訪問所有節點 示例 二叉樹 3,9,20,null,...