本章內容討論的是一般意義上的樹,即子結點個數不限且子結點沒有先後次序的樹。
建議使用靜態寫法,即用陣列下標來代替所謂的位址。這需要事先開乙個大小不低於結點上限個數的結點陣列。
struct node node[maxn]
;//結點陣列,maxn為結點上限個數
而child陣列的長度由於無法預知子結點個數只能開到最大,有些時候不可接受,故使用stl中的vector。
struct node node[maxn]
;//結點陣列,maxn為結點上限個數
新建結點
int index =0;
intnewnode
(int v)
但一般情況下會給出結點的編號,並且編號一定是0,1,…,n-1或1,2,…,n情況下就不需要newnode函式了
樹的先根遍歷
針對不同的題目,需要在此基礎上增加相關的**。
void
preorder
(int root)
}
樹的層次遍歷
實現方法類似二叉樹的層次遍歷
void
layerorder
(int root)
}}
如需要對結點的層號進行求解,只需要在結構體node的定義中增加變數來記錄結點的層號:
struct node
;
樹的層次遍歷改寫後:
void
layerorder
(int root)
}}
從樹的遍歷看dfs與bfs
廣度優先搜尋(bfs)與層序遍歷
對所有合法的bfs求解過程,可以畫出一棵樹並且將廣度優先搜尋問題轉換為樹的層序遍歷的問題。
例項:
給定一棵樹和每個結點的權值,求所有從根結點到葉子結點的路徑,使得每條路徑上的結點的權值之和等於給定的常數s。如果有多條這樣的路徑,則按路徑非遞增的順序輸出。其中路徑的大小是指,如果兩條路徑分別為a1->a2->…->ai->an與b1->b2->…->bi->bm,且有a1 == b1、a2 == b2、… 、ai-1 == bi-1成立,但ai > bi,那麼稱第一條路徑比第二條路徑大。
輸入樣例
20924
10243
510218
9722
13121
8622
0040102
0304021
0504206
0703311
1213061
0907208
1016115
1331416
1717218
19
輸出樣例
1052
710410
10336
21033
62
樣例解釋
從根到葉子的帶權路徑和為24的路徑有4條,經過的結點標號分別為(括號中為點權):
00(10)->04(5)->06(2)->09(7)
00(10)->02(4)->05(10)
00(10)->03(3)->13(3)->17(6)->19(2)
00(10)->03(3)->13(3)->17(6)->18(2)
思路:指標域使用vector存放所有孩子結點的編號,考慮到最後的輸出需要按權值從大到小排序,不妨在讀入時事先對每個結點的子結點vector進行排序,這樣在遍歷時就會優先遍歷到權值大的子結點
令int型陣列path[maxv]存放遞迴過程中產生的路徑上的結點編號。接下來進行dfs,引數有三個:當前訪問的結點標號index、當前路徑path上的結點個數numnode(也是遞迴層數)以及當前路徑上的權值和sum。遞迴過程的偽**:
2.1 若sum > s,直接return。
2.2 若sum == s,說明當前訪問結點index位置,輸入中需要達到的s已經得到,這時如果結點index為葉子結點,則輸出path陣列中的所有資料;否則return。
2.3 若sum < s,說明要求還未滿足。此時列舉當前訪問結點index的所有子結點,對每乙個子結點child,先將其存入path[numnode],然後再此基礎上往下一層遞迴,下一層的遞迴引數為child、numnode + 1、sum + node[child].weight。
#include
#include
#include
using
namespace std;
const
int maxn =
110;
struct node node[maxn]
;bool
cmp(
int a,
int b)
int n, m, s;
//結點數、邊數、給定的和
int path[maxn]
;//記錄路徑
//當前訪問結點為index,numnode為當前路徑path上的結點個數
//sum為當前的結點點權和
void
dfs(
int index,
int numnode,
int sum)
return
;//返回
}for
(int i =
0; i < node[index]
.child.
size()
; i++)}
intmain()
int id, k, child;
for(
int i =
0; i < m; i++
)sort
(node[id]
.child.
begin()
, node[id]
.child.
end(
), cmp)
;//排序
} path[0]
=0;//路徑的第乙個結點設定為0號結點
dfs(0,
1, node[0]
.weight)
;return0;
}
演算法筆記 哈夫曼樹基本操作
樹的帶權路徑長度 weight path length of tree,wpl 等於它所有葉子結點的帶權路徑長度之後 哈夫曼問題 已知n個數,尋找一棵樹,使得樹的所有葉子結點的權值恰好為著n個數,並且使得這棵樹的帶權路徑長度最小。帶權路徑長度最小的樹被稱為哈夫曼樹 又稱最優二叉樹 顯然,對同一組葉子...
樹的基本操作演算法
關於樹的一些基本操作,本來把自己的一些研究寫出來!方便大家學習!樹可以以陣列的形式存放,也可以以鍊錶的形式存放!根據程式不同的需要選擇不同的存放形式!陣列的操作比較簡單作有限!本文不做研究!本文只是對鏈式儲存,做了一些簡單的研究!樹的鍊錶形式 struct node2 也可以是 struct nod...
《演算法筆記》9 3 樹的遍歷
一.樹的靜態寫法 1.結構體 struct node node maxn 2.新建結點 int index 0 intnewnode int v 3.如果題目中不涉及結點的資料域,上面的結構體可以簡化地寫成 vector 陣列 vectorchild maxn 二.樹的先根遍歷 void preor...