Más contenido relacionado La actualidad más candente (20) Similar a Tree and Graph Algorithms and Implementation (19) Tree and Graph Algorithms and Implementation3. Big-O (time complexity/space complexity)
top push pop empty
priority_queue 1/1 log(n)/1 log(n)/1 1/1
find insert erase empty clear size
map log(n)/1 log(n)/1 log(n)/1 1/1 n/1 1/1
find insert erase empty size
set log(n)/1 log(n)/1 log(n)/1 1/1 1/1
top pop empty push
stack 1/1 1/1 1/1 1/1
front back pop push empty size
queue 1/1 1/1 1/1 1/1 1/1 1/1
sort reverse push_back erase clear size
vector n*log(n)/log(n) n/1 1/1 n/1 n/1 1/1
https://leetcode.com/discuss/study-guide/1327203/c-stl-guide-stl-operations-and-time-complexities
5. Recap
► Queue https://www.cplusplus.com/reference/queue/queue/
1.#include <bits/stdc++.h>
2.using namespace std;
3.int main() {
4. int n, q;
5. queue<string> names;
6. string name;
7. cin >> n;
8. for (int i=0; i<n; i++) {
9. cin >> name;
10. names.push(name);
11. }
12. while (!names.empty()) {
13. cout << names.front() << endl;
14. names.pop();
15. }
16. return 0;
17.}
6. Trees
ต้นไม้ (Trees) เป็นโครงสร้างข้อมูลที่มีลักษณะเป็นกิ่งไม้ที่มีลำาต้น (Root)
และกิ่งลูก (Child Nodes) ที่เชื่อมต่อกันโดยใช้เส้นเชื่อม (Edges)
► โหนด (Nodes): จุดบนต้นไม้ที่เก็บข้อมูล
► เส้นเชื่อม (Edges): ลูกศรที่เชื่อมต่อระหว่างโหนดเพื่อแสดงความสัมพันธ์
► ราก (Root): โหนดบนสุดของต้นไม้ที่ไม่มีแม่
► แม่ (Parent): โหนดที่อยู่เหนือโหนดลูกในโครงสร้างต้นไม้
► ลูก (Child): โหนดที่ตำ่ากว่าโหนดแม่ในโครงสร้างต้นไม้
► ใบ (Leaf): โหนดที่ไม่มีโหนดลูก
► ต้นไม้ย่อย (Subtree): ต้นไม้ที่มีรากเป็นลูกของโหนดอื่น
► ความสูง (Height): จำานวนเส้นเชื่อมจากใบถึงรากของต้นไม้
1
2 3
4 5 6
8
7. Types of Trees
► Binary Tree
► Binary Search Tree
► Balanced Tree (AVL Tree, Red-Black Tree)
► Multi-way Tree (n-ary Tree)
10. Balanced Binary search Tree
ต้นไม้ที่กระจายโหนดอย่างสมดุล ช่วยให้การ
เข้าถึงข้อมูล
มีประสิทธิภาพมากขึ้น
คุณสมบัติ
► ค้นหาได้เร็ว
► อัลกอริทึมทำางานได้เร็ว
AVL Tree, Red-Black Tree
8
3
10
1
6 14
4 7 13
11. AVL Tree
Adelson-Velsky and Landis Tree is a self-balancing binary search tree.
► abs(h(left subtree) – h(right subtree)) <= 1
12
8
18
5
11
4
17
https://www.geeksforgeeks.org/introduction-to-avl-tree/
12. Red-Black Tree
a self-balancing binary search tree.
► Every node is either red or black.
► Root node is black.
► Red node can’t have red parent or red child.
► Every path from a node to descendant
leaf has same number of black nodes.
► Every leaf must be colored black.
7
3
18
8
10
11
22
https://www.geeksforgeeks.org/introduction-to-red-black-tree/
26
13. Heap
► โครงสร ้างข ้อมูลที่เก็บค่าในลักษณะต ้นไม ้ที่มีคุณสมบัติของ complete binary tree ช่วยให ้ค ้นหาข ้อมูลได ้เร็วขึ้น
10
15 30
40 50 70
70
45 50
10 15 50
เลขบนน้อยกว่าเลขล่าง
สองเลข
เลขบนมากกว่าเลขล่าง
สองเลข
Min Heap Max Heap
น้อย
ที่สุด
มาก
ที่สุด
14. สร ้าง
2
4 8
9 7 10 9
15 20 13
i=0
i=1 i=2
i=3 i=4 i=5 i=6
i=7 i=8 i=9
15. Max Heap #include <bits/stdc++.h>
using namespace std;
int main () {
int a[] = {2,4,8,9,7,10,9,15,20,13};
vector<int> v1(a, a+5);
vector<int> v2 = {2,4,8,9,7,10,9,15,20,13};
make_heap (v1.begin(), v1.end());
cout << "initial max heap : " << v.front() << 'n’;
pop_heap (v.begin(),v.end());
v.pop_back(); cout << "max heap after pop : " << v.front() << 'n’;
v.push_back(99);
push_heap (v.begin(),v.end());
cout << "max heap after push: " << v.front() << 'n’;
sort_heap (v.begin(),v.end());
cout << "final sorted range :";
for (unsigned i=0; i<v.size(); i++)
cout << ' ' << v[i]; cout << 'n’;
return 0;
}
16. Min Heap #include <bits/stdc++.h>
using namespace std;
void print(vector<int> const& v = {}) {
for (const auto& e : v)
cout << e << ' ‘;
cout << 'n’;
}
int main () {
vector<int> v = {2,4,8,9,7,10,9,15,20,13};
print(v);
make_heap(v.begin(), v.end(), greater<>{});
pop_heap(v.begin(), v.end(), greater<>{});
auto top = v.back();
v.pop_back();
print({top});
print(v1);
return 0;
}
17. Multi-way Tree
ต้นไม้หลายทาง (Multi-way Tree) เป็นโครงสร้างข้อมูลที่โหนด
แต่ละตัวอาจมีโหนดลูกมากกว่าหนึ่งโหนด
► โหนดลูกอาจมีจำานวนที่ไม่แน่นอน
► แต่ละโหนดอาจมีความสัมพันธ์กับโหนดอื่นๆ ในโครงสร้าง
ต้นไม้
ประโยชน์ของต้นไม้หลายทาง
► ช่วยให้สามารถจัดการข้อมูลแบบลำาดับการเชื่อมต่อได้อย่างมี
ประสิทธิภาพ
► เหมาะสำาหรับการจัดเก็บข้อมูลที่มีลำาดับการเชื่อมต่อที่ซับซ้อน
B-tree, Trie
27. Camp2_Tasks: GraphInput01 (directed graph)
9
ubonratchathani,sisaket
ubonratchathani,amnatcharoen
amnatcharoen,sisaket
amnatcharoen,yasothon
sisaket,roiet
sisaket,surin
yasothon,surin
yasothon,roiet
roiet,surin
surin,sisaket
no
► Input ► Input
28. Camp2_Tasks: GraphInput02 (undirected graph)
9
ubonratchathani,sisaket
ubonratchathani,amnatcharoen
amnatcharoen,sisaket
amnatcharoen,yasothon
sisaket,roiet
sisaket,surin
yasothon,surin
yasothon,roiet
roiet,surin
surin,sisaket
yes
► Input ► Input
34. (1) Adjacency Matrix
0 1 1 0 0 0
0 0 1 1 0 0
0 0 0 0 1 1
0 0 0 0 1 1
0 0 0 0 0 0
0
1
2
3
4
0 1 2 3 4 5
0 0 0 0 1 0
5
35. (1) Adjacency Matrix
0 1 1 0 0 0
0 0 1 1 0 0
0 0 0 0 1 1
0 0 0 0 1 1
0 0 0 0 0 0
0
1
2
3
4
0 1 2 3 4 5
0 0 0 0 1 0
5
1.int m[][6] = {
2. { 0, 1, 1, 0, 0, 0 },
3. { 0, 0, 1, 1, 0, 0 },
4. { 0, 0, 0, 0, 1, 1 },
5. { 0, 0, 0, 0, 1, 1 },
6. { 0, 0, 0, 0, 0, 0 },
7. { 0, 0, 0, 0, 1, 0 }
8.};
37. (2) Adjacency List
1 2
2
4 5
4 5
0
1
2
3
4
4
5
3
1.vector<vector<int>> m = {
2. {1, 2},
3. {2, 3},
4. {4, 5},
5. {4, 5},
6. {},
7. {4},
8.};
38. (2) Adjacency List
1 2
2
4 5
4 5
0
1
2
3
4
4
5
3
1.typedef vector<int> vi;
2.typedef vector<vi> vvi;
3.vvi m = {
4. {1, 2},
5. {2, 3},
6. {4, 5},
7. {4, 5},
8. {},
9. {4},
10.};
39. (2) Adjacency List
1 2
2
4 5
4 5
0
1
2
3
4
4
5
3
1.typedef vector<int> vi;
2.typedef map<int, vi> mivi;
3.mivi m = {
4. {0, {1, 2}},
5. {1, {2, 3}},
6. {2, {4, 5}},
7. {3, {4, 5}},
8. {5, {4}}
9.};
41. (1) Adjacency Matrix
0 1.17 1.05 0 0 0
0 0 1.10 0.77 0 0
0 0 0 0 1.53 2.15
0 0 0 0 2.03 0.88
0 0 0 0 0 0
0
1
2
3
4
0 1 2 3 4 5
0 0 0 0 2.08 0
5
42. (1) Adjacency Matrix
1.int m[][6] = {
2. { 0, 1.17, 1.05, 0, 0, 0 },
3. { 0, 0, 1.10, 0.77, 0, 0 },
4. { 0, 0, 0, 0, 1.53, 2.15 },
5. { 0, 0, 0, 0, 2.03, 0.88 },
6. { 0, 0, 0, 0, 0, 0 },
7. { 0, 0, 0, 0, 2.08, 0 }
8.};
0 1.17 1.05 0 0 0
0 0 1.10 0.77 0 0
0 0 0 0 1.53 2.15
0 0 0 0 2.03 0.88
0 0 0 0 0 0
0
1
2
3
4
0 1 2 3 4 5
0 0 0 0 2.08 0
5
44. (2) Adjacency List
<1,1.17> <2,1.05>
<2,1.10>
<4,1.53> <5,2.15>
<4,2.03> <5,0.88>
0
1
2
3
4
<4,2.08>
5
<3,0.77>
1.typedef pair<float, int> fi;
2.typedef vector<fi> vfi;
3.typedef vector<vfi> vvfi;
4.vector<vector<pair<float,i>>> m = {
5. {(1,1.17), (2,1.05)},
6. {(2,1.10), (3,0.77)},
7. {(4,1.53), (5,2.15)},
8. {(4,2.03), (5,0.88)},
9. {},
10. {(4,2.08)},
11.};
45. (2) Adjacency List
<1,1.17> <2,1.05>
<2,1.10>
<4,1.53> <5,2.15>
<4,2.03> <5,0.88>
0
1
2
3
4
<4,2.08>
5
<3,0.77>
1.typedef pair<int,int> ii;
2.typedef vector<ii> vii;
3.typedef vector<vii> vvii;
4.vvii m = {
5. {(1,1.17), (2,1.05)},
6. {(2,1.10), (3,0.77)},
7. {(4,1.53), (5,2.15)},
8. {(4,2.03), (5,0.88)},
9. {},
10. {(4,2.08)},
11.};
46. (2) Adjacency List
<1,1.17> <2,1.05>
<2,1.10>
<4,1.53> <5,2.15>
<4,2.03> <5,0.88>
0
1
2
3
4
<4,2.08>
5
<3,0.77>
1.typedef pair<int,int> ii;
2.typedef vector<ii> vii;
3.typedef map<int,<vii>> mivii;
4.mivii m = {
5. {0, {(1,1.17), (2,1.05)}},
6. {1, {(2,1.10), (3,0.77)}},
7. {2, {(4,1.53), (5,2.15)}},
8. {3, {(4,2.03), (5,0.88)}},
9. {4, {}},
10. {5, {(4,2.08)}},
11.};
49. Representation
1
3
4
5
0
1
2
3
4
5
1.typedef vector<int> vi;
2.typedef map<int, vi> mivi;
3.mivi m = {
4. {0, {1, 2}},
5. {1, {3}},
6. {2, {4}},
7. {3, {5}},
8. {4, {}},
9. {5, {}}
10.};
2
62. Depth First Traversal - iterative
1.# iterative depth first traversal
2.def dfti(graph, src=0):
3. stack = [ src ]
4. while len(stack) > 0:
5. current = stack.pop()
6. print(current)
7. for neighbor in graph[current]:
8. stack.append(neighbor)
63. Depth First Traversal - recursive
1.# recursive depth first traveral
2.def dftr(graph, src=0):
3. print(src)
4. for neighbor in graph[src]:
5. dftr(graph, neighbor)
6.
64. Depth First Traversal - iterative
1.// iterative depth first traversal
2.void dfti(mivi graph, int src) {
3. stack<int> s({src});
4. int current;
5. while (!s.empty()) {
6. current = s.top(); s.pop();
7. cout << "pop: " << current << endl;
8. for (auto neighbor : graph[current]) {
9. s.push(neighbor);
10. }
11. }
12.}
13.
65. Depth First Traversal - recursive
1.// recursive depth first traversal
2.void dftr(mivi graph, int src) {
3. cout << "pop: " << src << endl;
4. for (auto neighbor : graph[src]) {
5. dftr(graph, neighbor);
6. }
7.}
8.
78. Breadth First Traversal - iterative
1.# iterative breadth first traversal
2.def bfti(graph, src=0):
3. q = [ src ]
4. while len(q) > 0:
5. current = q.pop(0)
6. print(current)
7. for neighbor in graph[current]:
8. q.append(neighbor)
9.
79. Breadth First Traversal - iterative
1.void bft(mivi graph, int src) {
2. queue<int> q({ src });
3. int current;
4. while (!q.empty()) {
5. current = q.front(); q.pop();
6. cout << "pop: " << current << endl;
7. for (auto neighbor : graph[current]) {
8. q.push(neighbor);
9. }
10. }
11.}
12.
81. Representation
1 2
2
4 5
4 5
0
1
2
3
4
4
5
3
1.typedef vector<int> vi;
2.typedef map<int, vi> mivi;
3.mivi m = {
4. {0, {1, 2} },
5. {1, {2, 3} },
6. {2, {4, 5} },
7. {3, {4, 5} },
8. {4, {} },
9. {5, {4} },
10.};
88. Depth First Traversal – iterative 2
1.void dft2(mivi graph, int src) {
2. stack<int> s({src});
3. map<int, bool> visited;
4. int current;
5.
6. visited[src] = true;
7. while (!s.empty()) {
8. current = s.top(); s.pop();
9. cout << "pop: " << current << endl;
10. for (auto neighbor : graph[current]) {
11. if (visited.find(neighbor) == visited.end()) {
12. visited[neighbor] = true;
13. s.push(neighbor);
14. }
15. }
16. }
17.}
89. Depth First Traversal – recursive 2
1.void dftr2(mivi graph, int src, map<int, bool>& visited) {
2. if (visited.find(src) == visited.end()) {
3. cout << "pop: " << src << endl;
4. visited[src] = true;
5. for (auto neighbor : graph[src]) {
6. dftr2(graph, neighbor, visited);
7. }
8. }
9.}
90. Breadth First Traversal – iterative 2
1.void bft2(mivi graph, int src) {
2. queue<int> q({ src });
3. map<int, bool> visited;
4. int current;
5.
6. visited[src] = true;
7. while (!q.empty()) {
8. current = q.front(); q.pop();
9. cout << "pop: " << current << endl;
10. for (auto neighbor : graph[current]) {
11. if (visited.find(neighbor) == visited.end()) {
12. visited[neighbor] = true;
13. q.push(neighbor);
14. }
15. }
16. }
17.}
91. hasPath มีเส ้นทางจาก 1 ไป 4?
1
0
2
3
4
5
def hasPath(graph, src, dst): # depth first
if src == dst: return True
for neigbor in graph[src]:
if hasPath(graph, neigbor, dst):
return True
return False
92. hasPath มีเส ้นทางจาก 1 ไป 4?
1
0
2
3
4
5
def hasPath(graph, src, dst): # breadth first
queue = [ src ]
while len(queue) > 0:
current = queue.pop()
if current == dst: return True
for neighbor in graph[current]:
queue.push(neighbor)
return False
94. Representation
1 2
0
0 1
1 4
0
1
2
3
4
3
5
2
1.typedef vector<int> vi;
2.typedef vector<vi> vvi;
3.vvi m = {
4. {1, 2},
5. {0, 2, 3},
6. {0, 1, 4, 5},
7. {1, 4, 5},
8. {2, 3, 5},
9. {3, 4},
10.};
3
4 5
5
2 3 5
4
95. Homework
► Search
► Depth First
► Iterative & Recursive
► Breadth First
► iterative
► hasPath
► Depth First
► Iterative & Recursive
► Breadth First
► iterative
100. Exercise: W เป็นน้า L เป็นที่ดิน มีกี่เกาะ?
W L W W L W
L L W W L W
W L W W W W
W W W L L W
W L W L L W
W W W W W W
W L W W L W
L L W W L W
W L W W W W
W W W L L W
W L W L L W
W W W W W W
101. Explore()
def explore(grid, r, c, visited):
if !(0 <= r < len(grid)) || !(0 <= c < len(grid[r])): return 0
if grid[r][c] == ‘W’: return 0
if (r,c) in visited: return 0
visited.add( (r,c) )
explore(grid, r-1, c, visited)
explore(grid, r+1, c, visited)
explore(grid, r, c-1, visited)
explore(grid, r, c+1, visited)
return 1
103. Exercise: W เป็นน้า L เป็นที่ดิน ที่ดินติดกัน
มากที่สุดกี่ช่อง?
W L W W L W
L L W W L W
W L W W W W
W W W L L W
W L W L L W
W W W W W W
W L W W L W
L L W W L W
W L W W W W
W W W L L W
W L W L L W
W W W W W W
105. Exercise: W เป็นน้า L เป็นที่ดิน ที่ดินติดกัน
น้อยที่สุดกี่ช่อง?
W L W W L W
L L W W L W
W L W W W W
W W W L L W
W L W L L W
W W W W W W
W L W W L W
L L W W L W
W L W W W W
W W W L L W
W L W L L W
W W W W W W
107. Shortest Path – เส ้นทางสั้นที่สุด (Prelim)
def shortestPath(graph, src, dst): # bread first
queue = [ [src, 0] ]
visited = { src }
while len(queue) > 0:
node, distance = queue.pop()
if node == dst: return distance
for neighbor in graph[node]:
if node not in visited:
visited.add(node)
queue.push( [neighbor, distance+1] )
return -1 # path not found
108. Others shortest path algorithms?
► Minimum Spanning Tree
► Kruskal’s Algorithm
► Prim’s Algorithm
► Shortest Path Algorithms
► Dijkstra’s Algorithm
► Bellman Ford’s Algorithm
► Floyd Warshall’s Algorithm
109. Prim’s Algorithm
1.typedef vector<int> vi;
2.typedef pair<int, int> ii;
3.
4.vi taken;
5.priority_queue<ii> pq;
6.
7.void process(int vtx) {
8. taken[vtx] = 1;
9. for (int j=0; j < (int)graph[vtx].size(); j++) {
10. ii v = graph[vtx][j];
11. if (!taken[v.first])
12. pq.push(ii(-v.second, -v.first));
13. }
14.}
15.
110. Prim’s Algorithm
1.int main() {
2. ios_base::sync_with_stdio(false);
3. cin.tie(NULL);
4. taken.assign(V, 0);
5. process(0);
6. long mst_cost = 0;
7. while (!pq.empty()) {
8. ii front = pq.top(); pq.pop();
9. u = -front.second;
10. w = -front.first;
11. if (!taken[u]) {
12. mst_cost += w;
13. process(u);
14. }
15. }
16. cout << mst_cost << endl;
17. return 0;
18.}
111. Prim’s Algorithm
1.int main() {
2. ios_base::sync_with_stdio(false);
3. cin.tie(NULL);
4. taken.assign(V, 0);
5. process(0);
6. long mst_cost = 0;
7. while (!pq.empty()) {
8. ii front = pq.top(); pq.pop();
9. u = -front.second;
10. w = -front.first;
11. if (!taken[u]) {
12. mst_cost += w;
13. process(u);
14. }
15. }
16. cout << mst_cost << endl;
17. return 0;
18.}
112. Dijkstra
1.typedef vector<int> vi;
2.int main() {
3. vi dist(V, INF);
4. dist[s] = 0;
5. priority_queue<ii, vector<ii>, greater<ii>> pq;
6. pq.push(ii(0, s));
7. while (!pq.empty()) {
8. ii front = pq.top(); pq.pop();
9. int d = front.first, u = front.second;
10. if (d > dist[u]) continue;
11. for (int j=0; j<(int)graph[u].size(); j++) {
12. ii v = graph[u][j];
13. if (dist[u] + v.second < dist[v.first]) {
14. dist[v.first] = dist[u] + v.second;
15. pq.push(ii(dist[v.first], v.first));
16. }
17. }
18. }
19.}