Katakanlah Anda ingin mengimplementasikan pencarian pertama dari pohon biner secara rekursif . Bagaimana Anda melakukannya?
Apakah mungkin hanya menggunakan tumpukan panggilan sebagai penyimpanan tambahan?
Katakanlah Anda ingin mengimplementasikan pencarian pertama dari pohon biner secara rekursif . Bagaimana Anda melakukannya?
Apakah mungkin hanya menggunakan tumpukan panggilan sebagai penyimpanan tambahan?
Jawaban:
(Saya berasumsi bahwa ini hanya semacam latihan pemikiran, atau bahkan trik mengerjakan pekerjaan rumah / wawancara, tapi saya kira saya bisa membayangkan beberapa skenario aneh di mana Anda tidak diizinkan menimbun ruang untuk beberapa alasan [beberapa kebiasaan yang sangat buruk manajer memori? beberapa masalah runtime / OS yang aneh?] ketika Anda masih memiliki akses ke tumpukan ...)
Breadth-first traversal secara tradisional menggunakan antrian, bukan tumpukan. Sifat antrian dan tumpukan cukup berlawanan, jadi mencoba menggunakan panggilan stack (yang merupakan tumpukan, maka nama) sebagai penyimpanan tambahan (antrian) cukup banyak ditakdirkan untuk gagal, kecuali jika Anda melakukan sesuatu yang konyol dengan tumpukan panggilan yang seharusnya tidak Anda lakukan.
Pada token yang sama, sifat dari setiap rekursi non-ekor yang Anda coba implementasikan pada dasarnya menambahkan tumpukan ke algoritma. Ini membuatnya tidak lagi luas pencarian pertama pada pohon biner, dan dengan demikian run-time dan yang lainnya untuk BFS tradisional tidak lagi sepenuhnya berlaku. Tentu saja, Anda selalu dapat dengan mudah mengubah perulangan apa pun menjadi panggilan rekursif, tetapi itu bukan jenis rekursi yang berarti.
Namun, ada cara, seperti yang ditunjukkan oleh orang lain, untuk mengimplementasikan sesuatu yang mengikuti semantik BFS dengan biaya tertentu. Jika biaya perbandingannya mahal tetapi node traversal murah, maka seperti yang dilakukan @Simon Buchan , Anda bisa menjalankan pencarian kedalaman-iteratif pertama, hanya memproses daun. Ini berarti tidak ada antrian tumbuh yang disimpan di heap, hanya variabel kedalaman lokal, dan tumpukan yang dibangun berulang-ulang di tumpukan panggilan saat pohon dilintasi berulang-ulang. Dan seperti yang dicatat oleh @Patrick , pohon biner yang didukung oleh array biasanya disimpan dalam urutan traversal pertama, jadi pencarian pertama yang luas akan sepele, juga tanpa perlu antrian tambahan.
Jika Anda menggunakan array untuk mendukung pohon biner, Anda dapat menentukan simpul berikutnya secara aljabar. jika i
adalah simpul, maka anak-anaknya dapat ditemukan di 2i + 1
(untuk simpul kiri) dan 2i + 2
(untuk simpul kanan). Tetangga node berikutnya diberikan oleh i + 1
, kecuali i
kekuatan dari2
Inilah pseudocode untuk implementasi yang sangat naif dari pencarian pertama luasnya pada pohon pencarian biner array yang didukung. Ini mengasumsikan array ukuran tetap dan karenanya pohon kedalaman tetap. Ini akan melihat node tanpa orangtua, dan dapat membuat tumpukan besar tidak terkelola.
bintree-bfs(bintree, elt, i)
if (i == LENGTH)
return false
else if (bintree[i] == elt)
return true
else
return bintree-bfs(bintree, elt, i+1)
Saya tidak dapat menemukan cara untuk melakukannya sepenuhnya rekursif (tanpa struktur data tambahan). Tetapi jika antrian Q dilewatkan dengan referensi, maka Anda dapat memiliki fungsi rekursif ekor konyol berikut:
BFS(Q)
{
if (|Q| > 0)
v <- Dequeue(Q)
Traverse(v)
foreach w in children(v)
Enqueue(Q, w)
BFS(Q)
}
Metode berikut menggunakan algoritma DFS untuk mendapatkan semua node di kedalaman tertentu - yang sama dengan melakukan BFS untuk tingkat itu. Jika Anda menemukan kedalaman pohon dan melakukan ini untuk semua tingkatan, hasilnya akan sama dengan BFS.
public void PrintLevelNodes(Tree root, int level) {
if (root != null) {
if (level == 0) {
Console.Write(root.Data);
return;
}
PrintLevelNodes(root.Left, level - 1);
PrintLevelNodes(root.Right, level - 1);
}
}
for (int i = 0; i < depth; i++) {
PrintLevelNodes(root, i);
}
Menemukan kedalaman pohon adalah sepotong kue:
public int MaxDepth(Tree root) {
if (root == null) {
return 0;
} else {
return Math.Max(MaxDepth(root.Left), MaxDepth(root.Right)) + 1;
}
}
level
nol.
Rekursi BFS dan DFS sederhana di Jawa:
Cukup tekan / tawarkan simpul akar pohon di stack / antrian dan panggil fungsi-fungsi ini.
public static void breadthFirstSearch(Queue queue) {
if (queue.isEmpty())
return;
Node node = (Node) queue.poll();
System.out.println(node + " ");
if (node.right != null)
queue.offer(node.right);
if (node.left != null)
queue.offer(node.left);
breadthFirstSearch(queue);
}
public static void depthFirstSearch(Stack stack) {
if (stack.isEmpty())
return;
Node node = (Node) stack.pop();
System.out.println(node + " ");
if (node.right != null)
stack.push(node.right);
if (node.left != null)
stack.push(node.left);
depthFirstSearch(stack);
}
Saya menemukan algoritma terkait Breadth-First traversal terkait rekursif (bahkan fungsional) yang sangat indah. Bukan ide saya, tapi saya pikir itu harus disebutkan dalam topik ini.
Chris Okasaki menjelaskan algoritme penomoran pertamanya yang luas dari ICFP 2000 di http://okasaki.blogspot.de/2008/07/breadth-first-numbering-algorithm-in.html sangat jelas hanya dengan 3 gambar.
Implementasi Scala dari Debasish Ghosh, yang saya temukan di http://debasishg.blogspot.de/2008/09/breadth-first-first-numbering-okasakis.html , adalah:
trait Tree[+T]
case class Node[+T](data: T, left: Tree[T], right: Tree[T]) extends Tree[T]
case object E extends Tree[Nothing]
def bfsNumForest[T](i: Int, trees: Queue[Tree[T]]): Queue[Tree[Int]] = {
if (trees.isEmpty) Queue.Empty
else {
trees.dequeue match {
case (E, ts) =>
bfsNumForest(i, ts).enqueue[Tree[Int]](E)
case (Node(d, l, r), ts) =>
val q = ts.enqueue(l, r)
val qq = bfsNumForest(i+1, q)
val (bb, qqq) = qq.dequeue
val (aa, tss) = qqq.dequeue
tss.enqueue[org.dg.collection.BFSNumber.Tree[Int]](Node(i, aa, bb))
}
}
}
def bfsNumTree[T](t: Tree[T]): Tree[Int] = {
val q = Queue.Empty.enqueue[Tree[T]](t)
val qq = bfsNumForest(1, q)
qq.dequeue._1
}
Cara bodoh:
template<typename T>
struct Node { Node* left; Node* right; T value; };
template<typename T, typename P>
bool searchNodeDepth(Node<T>* node, Node<T>** result, int depth, P pred) {
if (!node) return false;
if (!depth) {
if (pred(node->value)) {
*result = node;
}
return true;
}
--depth;
searchNodeDepth(node->left, result, depth, pred);
if (!*result)
searchNodeDepth(node->right, result, depth, pred);
return true;
}
template<typename T, typename P>
Node<T>* searchNode(Node<T>* node, P pred) {
Node<T>* result = NULL;
int depth = 0;
while (searchNodeDepth(node, &result, depth, pred) && !result)
++depth;
return result;
}
int main()
{
// a c f
// b e
// d
Node<char*>
a = { NULL, NULL, "A" },
c = { NULL, NULL, "C" },
b = { &a, &c, "B" },
f = { NULL, NULL, "F" },
e = { NULL, &f, "E" },
d = { &b, &e, "D" };
Node<char*>* found = searchNode(&d, [](char* value) -> bool {
printf("%s\n", value);
return !strcmp((char*)value, "F");
});
printf("found: %s\n", found->value);
return 0;
}
Inilah solusi Scala singkat :
def bfs(nodes: List[Node]): List[Node] = {
if (nodes.nonEmpty) {
nodes ++ bfs(nodes.flatMap(_.children))
} else {
List.empty
}
}
Ide menggunakan nilai kembali sebagai akumulator sangat cocok. Dapat diimplementasikan dalam bahasa lain dengan cara yang sama, hanya pastikan bahwa proses rekursif Anda daftar node .
Daftar kode tes (menggunakan pohon tes @marco):
import org.scalatest.FlatSpec
import scala.collection.mutable
class Node(val value: Int) {
private val _children: mutable.ArrayBuffer[Node] = mutable.ArrayBuffer.empty
def add(child: Node): Unit = _children += child
def children = _children.toList
override def toString: String = s"$value"
}
class BfsTestScala extends FlatSpec {
// 1
// / | \
// 2 3 4
// / | | \
// 5 6 7 8
// / | | \
// 9 10 11 12
def tree(): Node = {
val root = new Node(1)
root.add(new Node(2))
root.add(new Node(3))
root.add(new Node(4))
root.children(0).add(new Node(5))
root.children(0).add(new Node(6))
root.children(2).add(new Node(7))
root.children(2).add(new Node(8))
root.children(0).children(0).add(new Node(9))
root.children(0).children(0).add(new Node(10))
root.children(2).children(0).add(new Node(11))
root.children(2).children(0).add(new Node(12))
root
}
def bfs(nodes: List[Node]): List[Node] = {
if (nodes.nonEmpty) {
nodes ++ bfs(nodes.flatMap(_.children))
} else {
List.empty
}
}
"BFS" should "work" in {
println(bfs(List(tree())))
}
}
Keluaran:
List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
Berikut ini implementasi python:
graph = {'A': ['B', 'C'],
'B': ['C', 'D'],
'C': ['D'],
'D': ['C'],
'E': ['F'],
'F': ['C']}
def bfs(paths, goal):
if not paths:
raise StopIteration
new_paths = []
for path in paths:
if path[-1] == goal:
yield path
last = path[-1]
for neighbor in graph[last]:
if neighbor not in path:
new_paths.append(path + [neighbor])
yield from bfs(new_paths, goal)
for path in bfs([['A']], 'D'):
print(path)
Berikut ini adalah implementasi Scala 2.11.4 dari BFS rekursif. Saya telah mengorbankan optimisasi panggilan ekor untuk singkatnya, tetapi versi TCOd sangat mirip. Lihat juga postingan @snv .
import scala.collection.immutable.Queue
object RecursiveBfs {
def bfs[A](tree: Tree[A], target: A): Boolean = {
bfs(Queue(tree), target)
}
private def bfs[A](forest: Queue[Tree[A]], target: A): Boolean = {
forest.dequeueOption exists {
case (E, tail) => bfs(tail, target)
case (Node(value, _, _), _) if value == target => true
case (Node(_, l, r), tail) => bfs(tail.enqueue(List(l, r)), target)
}
}
sealed trait Tree[+A]
case class Node[+A](data: A, left: Tree[A], right: Tree[A]) extends Tree[A]
case object E extends Tree[Nothing]
}
Berikut ini sepertinya cukup alami bagi saya, menggunakan Haskell. Ulangi secara berulang di atas level pohon (di sini saya mengumpulkan nama menjadi string besar yang diperintahkan untuk menunjukkan jalur melalui pohon):
data Node = Node {name :: String, children :: [Node]}
aTree = Node "r" [Node "c1" [Node "gc1" [Node "ggc1" []], Node "gc2" []] , Node "c2" [Node "gc3" []], Node "c3" [] ]
breadthFirstOrder x = levelRecurser [x]
where levelRecurser level = if length level == 0
then ""
else concat [name node ++ " " | node <- level] ++ levelRecurser (concat [children node | node <- level])
Berikut ini adalah implementasi Python traversal rekursif BFS, bekerja untuk grafik tanpa siklus.
def bfs_recursive(level):
'''
@params level: List<Node> containing the node for a specific level.
'''
next_level = []
for node in level:
print(node.value)
for child_node in node.adjency_list:
next_level.append(child_node)
if len(next_level) != 0:
bfs_recursive(next_level)
class Node:
def __init__(self, value):
self.value = value
self.adjency_list = []
Saya ingin menambahkan sen saya ke jawaban teratas karena jika bahasa mendukung sesuatu seperti generator, bfs dapat dilakukan secara rekursif.
Untuk mulai dengan, jawaban @ Tanzelax berbunyi:
Breadth-first traversal secara tradisional menggunakan antrian, bukan tumpukan. Sifat antrian dan tumpukan cukup berlawanan, jadi mencoba menggunakan panggilan stack (yang merupakan tumpukan, maka nama) sebagai penyimpanan tambahan (antrian) cukup banyak ditakdirkan untuk gagal
Memang, stack pemanggilan fungsi biasa tidak akan berperilaku seperti stack normal. Tetapi fungsi generator akan menunda eksekusi fungsi sehingga memberi kita kesempatan untuk menghasilkan anak-anak node level berikutnya tanpa menggali keturunan node yang lebih dalam.
Kode berikut adalah bfs rekursif dengan Python.
def bfs(root):
yield root
for n in bfs(root):
for c in n.children:
yield c
Intuisi di sini adalah:
Saya harus mengimplementasikan heap traversal yang menghasilkan dalam urutan BFS. Ini sebenarnya bukan BFS tetapi menyelesaikan tugas yang sama.
private void getNodeValue(Node node, int index, int[] array) {
array[index] = node.value;
index = (index*2)+1;
Node left = node.leftNode;
if (left!=null) getNodeValue(left,index,array);
Node right = node.rightNode;
if (right!=null) getNodeValue(right,index+1,array);
}
public int[] getHeap() {
int[] nodes = new int[size];
getNodeValue(root,0,nodes);
return nodes;
}
Biarkan v menjadi titik awal
Biarkan G menjadi grafik yang dipermasalahkan
Berikut ini adalah kode semu tanpa menggunakan antrian
Initially label v as visited as you start from v
BFS(G,v)
for all adjacent vertices w of v in G:
if vertex w is not visited:
label w as visited
for all adjacent vertices w of v in G:
recursively call BFS(G,w)
BFS untuk pohon biner (atau n-ary) dapat dilakukan secara rekursif tanpa antrian sebagai berikut (di sini di Jawa):
public class BreathFirst {
static class Node {
Node(int value) {
this(value, 0);
}
Node(int value, int nChildren) {
this.value = value;
this.children = new Node[nChildren];
}
int value;
Node[] children;
}
static void breathFirst(Node root, Consumer<? super Node> printer) {
boolean keepGoing = true;
for (int level = 0; keepGoing; level++) {
keepGoing = breathFirst(root, printer, level);
}
}
static boolean breathFirst(Node node, Consumer<? super Node> printer, int depth) {
if (depth < 0 || node == null) return false;
if (depth == 0) {
printer.accept(node);
return true;
}
boolean any = false;
for (final Node child : node.children) {
any |= breathFirst(child, printer, depth - 1);
}
return any;
}
}
Contoh nomor pencetakan traversal 1-12 dalam urutan menaik:
public static void main(String... args) {
// 1
// / | \
// 2 3 4
// / | | \
// 5 6 7 8
// / | | \
// 9 10 11 12
Node root = new Node(1, 3);
root.children[0] = new Node(2, 2);
root.children[1] = new Node(3);
root.children[2] = new Node(4, 2);
root.children[0].children[0] = new Node(5, 2);
root.children[0].children[1] = new Node(6);
root.children[2].children[0] = new Node(7, 2);
root.children[2].children[1] = new Node(8);
root.children[0].children[0].children[0] = new Node(9);
root.children[0].children[0].children[1] = new Node(10);
root.children[2].children[0].children[0] = new Node(11);
root.children[2].children[0].children[1] = new Node(12);
breathFirst(root, n -> System.out.println(n.value));
}
#include <bits/stdc++.h>
using namespace std;
#define Max 1000
vector <int> adj[Max];
bool visited[Max];
void bfs_recursion_utils(queue<int>& Q) {
while(!Q.empty()) {
int u = Q.front();
visited[u] = true;
cout << u << endl;
Q.pop();
for(int i = 0; i < (int)adj[u].size(); ++i) {
int v = adj[u][i];
if(!visited[v])
Q.push(v), visited[v] = true;
}
bfs_recursion_utils(Q);
}
}
void bfs_recursion(int source, queue <int>& Q) {
memset(visited, false, sizeof visited);
Q.push(source);
bfs_recursion_utils(Q);
}
int main(void) {
queue <int> Q;
adj[1].push_back(2);
adj[1].push_back(3);
adj[1].push_back(4);
adj[2].push_back(5);
adj[2].push_back(6);
adj[3].push_back(7);
bfs_recursion(1, Q);
return 0;
}
Berikut adalah Implementasi JavaScript yang memalsukan Breadth First Traversal dengan Rekursi Depth First. Saya menyimpan nilai-nilai simpul di setiap kedalaman di dalam array, di dalam hash. Jika level sudah ada (kami memiliki tabrakan), jadi kami hanya mendorong ke array di level itu. Anda bisa menggunakan array bukan objek JavaScript juga karena level kami numerik dan dapat berfungsi sebagai indeks array. Anda dapat mengembalikan node, nilai, dikonversi ke Daftar Tertaut, atau apa pun yang Anda inginkan. Saya hanya mengembalikan nilai demi kesederhanaan.
BinarySearchTree.prototype.breadthFirstRec = function() {
var levels = {};
var traverse = function(current, depth) {
if (!current) return null;
if (!levels[depth]) levels[depth] = [current.value];
else levels[depth].push(current.value);
traverse(current.left, depth + 1);
traverse(current.right, depth + 1);
};
traverse(this.root, 0);
return levels;
};
var bst = new BinarySearchTree();
bst.add(20, 22, 8, 4, 12, 10, 14, 24);
console.log('Recursive Breadth First: ', bst.breadthFirstRec());
/*Recursive Breadth First:
{ '0': [ 20 ],
'1': [ 8, 22 ],
'2': [ 4, 12, 24 ],
'3': [ 10, 14 ] } */
Berikut ini adalah contoh Breadth First Traversal yang sebenarnya menggunakan pendekatan iteratif.
BinarySearchTree.prototype.breadthFirst = function() {
var result = '',
queue = [],
current = this.root;
if (!current) return null;
queue.push(current);
while (current = queue.shift()) {
result += current.value + ' ';
current.left && queue.push(current.left);
current.right && queue.push(current.right);
}
return result;
};
console.log('Breadth First: ', bst.breadthFirst());
//Breadth First: 20 8 22 4 12 24 10 14
Berikut ini adalah kode saya untuk implementasi sepenuhnya rekursif dari pencarian luas-pertama dari grafik dua arah tanpa menggunakan loop dan antrian.
public class Graph
{
public int V;
public LinkedList<Integer> adj[];
Graph(int v)
{
V = v;
adj = new LinkedList[v];
for (int i=0; i<v; ++i)
adj[i] = new LinkedList<>();
}
void addEdge(int v,int w)
{
adj[v].add(w);
adj[w].add(v);
}
public LinkedList<Integer> getAdjVerted(int vertex)
{
return adj[vertex];
}
public String toString()
{
String s = "";
for (int i=0;i<adj.length;i++)
{
s = s +"\n"+i +"-->"+ adj[i] ;
}
return s;
}
}
//BFS IMPLEMENTATION
public static void recursiveBFS(Graph graph, int vertex,boolean visited[], boolean isAdjPrinted[])
{
if (!visited[vertex])
{
System.out.print(vertex +" ");
visited[vertex] = true;
}
if(!isAdjPrinted[vertex])
{
isAdjPrinted[vertex] = true;
List<Integer> adjList = graph.getAdjVerted(vertex);
printAdjecent(graph, adjList, visited, 0,isAdjPrinted);
}
}
public static void recursiveBFS(Graph graph, List<Integer> vertexList, boolean visited[], int i, boolean isAdjPrinted[])
{
if (i < vertexList.size())
{
recursiveBFS(graph, vertexList.get(i), visited, isAdjPrinted);
recursiveBFS(graph, vertexList, visited, i+1, isAdjPrinted);
}
}
public static void printAdjecent(Graph graph, List<Integer> list, boolean visited[], int i, boolean isAdjPrinted[])
{
if (i < list.size())
{
if (!visited[list.get(i)])
{
System.out.print(list.get(i)+" ");
visited[list.get(i)] = true;
}
printAdjecent(graph, list, visited, i+1, isAdjPrinted);
}
else
{
recursiveBFS(graph, list, visited, 0, isAdjPrinted);
}
}
C # implementasi algoritma pencarian luas-rekursif pertama untuk pohon biner.
IDictionary<string, string[]> graph = new Dictionary<string, string[]> {
{"A", new [] {"B", "C"}},
{"B", new [] {"D", "E"}},
{"C", new [] {"F", "G"}},
{"E", new [] {"H"}}
};
void Main()
{
var pathFound = BreadthFirstSearch("A", "H", new string[0]);
Console.WriteLine(pathFound); // [A, B, E, H]
var pathNotFound = BreadthFirstSearch("A", "Z", new string[0]);
Console.WriteLine(pathNotFound); // []
}
IEnumerable<string> BreadthFirstSearch(string start, string end, IEnumerable<string> path)
{
if (start == end)
{
return path.Concat(new[] { end });
}
if (!graph.ContainsKey(start)) { return new string[0]; }
return graph[start].SelectMany(letter => BreadthFirstSearch(letter, end, path.Concat(new[] { start })));
}
Jika Anda ingin algoritma berfungsi tidak hanya dengan binary-tree tetapi dengan grafik yang dapat memiliki dua dan lebih banyak node yang menunjuk ke node lain yang sama, Anda harus menghindari siklus sendiri dengan memegang daftar node yang sudah dikunjungi. Implementasinya mungkin terlihat seperti ini.
IDictionary<string, string[]> graph = new Dictionary<string, string[]> {
{"A", new [] {"B", "C"}},
{"B", new [] {"D", "E"}},
{"C", new [] {"F", "G", "E"}},
{"E", new [] {"H"}}
};
void Main()
{
var pathFound = BreadthFirstSearch("A", "H", new string[0], new List<string>());
Console.WriteLine(pathFound); // [A, B, E, H]
var pathNotFound = BreadthFirstSearch("A", "Z", new string[0], new List<string>());
Console.WriteLine(pathNotFound); // []
}
IEnumerable<string> BreadthFirstSearch(string start, string end, IEnumerable<string> path, IList<string> visited)
{
if (start == end)
{
return path.Concat(new[] { end });
}
if (!graph.ContainsKey(start)) { return new string[0]; }
return graph[start].Aggregate(new string[0], (acc, letter) =>
{
if (visited.Contains(letter))
{
return acc;
}
visited.Add(letter);
var result = BreadthFirstSearch(letter, end, path.Concat(new[] { start }), visited);
return acc.Concat(result).ToArray();
});
}
Saya telah membuat program menggunakan c ++ yang bekerja dalam grafik gabungan dan terpisah juga.
#include <queue>
#include "iostream"
#include "vector"
#include "queue"
using namespace std;
struct Edge {
int source,destination;
};
class Graph{
int V;
vector<vector<int>> adjList;
public:
Graph(vector<Edge> edges,int V){
this->V = V;
adjList.resize(V);
for(auto i : edges){
adjList[i.source].push_back(i.destination);
// adjList[i.destination].push_back(i.source);
}
}
void BFSRecursivelyJoinandDisjointtGraphUtil(vector<bool> &discovered, queue<int> &q);
void BFSRecursivelyJointandDisjointGraph(int s);
void printGraph();
};
void Graph :: printGraph()
{
for (int i = 0; i < this->adjList.size(); i++)
{
cout << i << " -- ";
for (int v : this->adjList[i])
cout <<"->"<< v << " ";
cout << endl;
}
}
void Graph ::BFSRecursivelyJoinandDisjointtGraphUtil(vector<bool> &discovered, queue<int> &q) {
if (q.empty())
return;
int v = q.front();
q.pop();
cout << v <<" ";
for (int u : this->adjList[v])
{
if (!discovered[u])
{
discovered[u] = true;
q.push(u);
}
}
BFSRecursivelyJoinandDisjointtGraphUtil(discovered, q);
}
void Graph ::BFSRecursivelyJointandDisjointGraph(int s) {
vector<bool> discovered(V, false);
queue<int> q;
for (int i = s; i < V; i++) {
if (discovered[i] == false)
{
discovered[i] = true;
q.push(i);
BFSRecursivelyJoinandDisjointtGraphUtil(discovered, q);
}
}
}
int main()
{
vector<Edge> edges =
{
{0, 1}, {0, 2}, {1, 2}, {2, 0}, {2,3},{3,3}
};
int V = 4;
Graph graph(edges, V);
// graph.printGraph();
graph.BFSRecursivelyJointandDisjointGraph(2);
cout << "\n";
edges = {
{0,4},{1,2},{1,3},{1,4},{2,3},{3,4}
};
Graph graph2(edges,5);
graph2.BFSRecursivelyJointandDisjointGraph(0);
return 0;
}