Gitt en rettet Eulersk graf er oppgaven å skrive ut en Euler krets . En Euler-krets er en bane som krysser hver kant av en graf nøyaktig én gang, og banen ender på startpunktet.
Note: Den gitte grafen inneholder en Euler-krets.
Eksempel:
Inngang : Rettet graf
![]()
Produksjon: 0 3 4 0 2 1 0
Forutsetninger:
- Vi har diskutert problem med å finne ut om en gitt graf er Eulerian eller ikke for en urettet graf
- Betingelser for Eulerisk krets i en rettet Grpag: (1) Alle toppunkter tilhører en enkelt sterkt tilkoblet komponent. (2) Alle toppunkter har samme inn-grad og ut-grad. Merk at for en urettet graf er betingelsen forskjellig (alle toppunkter har jevn grad)
Nærme:
- Velg et hvilket som helst startpunkt v og følg et spor av kanter fra det toppunktet til du går tilbake til v. Det er ikke mulig å bli sittende fast ved noe annet toppunkt enn v fordi indegree og outdegree for hvert toppunkt må være det samme når stien går inn i et annet toppunkt w det må være en ubrukt kant som forlater w. Turen dannet på denne måten er en lukket tur, men dekker kanskje ikke alle toppunktene og kantene på den første grafen.
- Så lenge det eksisterer et toppunkt u som tilhører den nåværende turen, men som har tilstøtende kanter som ikke er en del av turen, starter du en annen sti fra u følger ubrukte kanter til du går tilbake til u og blir med på turen dannet på denne måten til forrige tur.
Illustrasjon:
Ta eksempel på grafen ovenfor med 5 noder: adj = {{2 3} {0} {1} {4} {0}}.
- Start ved toppunktet 0 :
- Gjeldende bane: [0]
- Krets: []
- Toppunkt 0 → 3 :
- Nåværende bane: [0 3]
- Krets: []
- Toppunkt 3 → 4 :
- Nåværende bane: [0 3 4]
- Krets: []
- Toppunkt 4 → 0 :
- Nåværende bane: [0 3 4 0]
- Krets: []
- Toppunkt 0 → 2 :
- Nåværende bane: [0 3 4 0 2]
- Krets: []
- Toppunkt 2 → 1 :
- Gjeldende bane: [0 3 4 0 2 1]
- Krets: []
- Toppunkt 1 → 0 :
- Gjeldende bane: [0 3 4 0 2 1 0]
- Krets: []
- Gå tilbake til toppunkt 0 : Legg til 0 til kretsen.
- Gjeldende bane: [0 3 4 0 2 1]
- Krets: [0]
- Gå tilbake til toppunkt 1 : Legg til 1 til kretsen.
- Nåværende bane: [0 3 4 0 2]
- Krets: [0 1]
- Gå tilbake til toppunkt 2 : Legg til 2 til kretsen.
- Nåværende bane: [0 3 4 0]
- Krets: [0 1 2]
- Gå tilbake til toppunkt 0 : Legg til 0 til kretsen.
- Nåværende bane: [0 3 4]
- Krets: [0 1 2 0]
- Gå tilbake til toppunkt 4 : Legg til 4 til kretsen.
- Nåværende bane: [0 3]
- Krets: [0 1 2 0 4]
- Gå tilbake til toppunkt 3 : Legg til 3 til kretsen.
- Gjeldende bane: [0]
- Krets: [0 1 2 0 4 3]
- Gå tilbake til toppunkt 0 : Legg til 0 til kretsen.
- Gjeldende bane: []
- Krets: [0 1 2 0 4 3 0]
Nedenfor er implementeringen for tilnærmingen ovenfor:
C++// C++ program to print Eulerian circuit in given // directed graph using Hierholzer algorithm #include using namespace std; // Function to print Eulerian circuit vector<int> printCircuit(vector<vector<int>> &adj) { int n = adj.size(); if (n == 0) return {}; // Maintain a stack to keep vertices // We can start from any vertex here we start with 0 vector<int> currPath; currPath.push_back(0); // list to store final circuit vector<int> circuit; while (currPath.size() > 0) { int currNode = currPath[currPath.size() - 1]; // If there's remaining edge in adjacency list // of the current vertex if (adj[currNode].size() > 0) { // Find and remove the next vertex that is // adjacent to the current vertex int nextNode = adj[currNode].back(); adj[currNode].pop_back(); // Push the new vertex to the stack currPath.push_back(nextNode); } // back-track to find remaining circuit else { // Remove the current vertex and // put it in the circuit circuit.push_back(currPath.back()); currPath.pop_back(); } } // reverse the result vector reverse(circuit.begin() circuit.end()); return circuit; } int main() { vector<vector<int>> adj = {{2 3} {0} {1} {4} {0}}; vector<int> ans = printCircuit(adj); for (auto v: ans) cout << v << ' '; cout << endl; return 0; }
Java // Java program to print Eulerian circuit in given // directed graph using Hierholzer algorithm import java.util.*; class GfG { // Function to print Eulerian circuit static List<Integer> printCircuit(List<List<Integer>> adj) { int n = adj.size(); if (n == 0) return new ArrayList<>(); // Maintain a stack to keep vertices // We can start from any vertex here we start with 0 List<Integer> currPath = new ArrayList<>(); currPath.add(0); // list to store final circuit List<Integer> circuit = new ArrayList<>(); while (currPath.size() > 0) { int currNode = currPath.get(currPath.size() - 1); // If there's remaining edge in adjacency list // of the current vertex if (adj.get(currNode).size() > 0) { // Find and remove the next vertex that is // adjacent to the current vertex int nextNode = adj.get(currNode).get(adj.get(currNode).size() - 1); adj.get(currNode).remove(adj.get(currNode).size() - 1); // Push the new vertex to the stack currPath.add(nextNode); } // back-track to find remaining circuit else { // Remove the current vertex and // put it in the circuit circuit.add(currPath.get(currPath.size() - 1)); currPath.remove(currPath.size() - 1); } } // reverse the result vector Collections.reverse(circuit); return circuit; } public static void main(String[] args) { List<List<Integer>> adj = new ArrayList<>(); adj.add(new ArrayList<>(Arrays.asList(2 3))); adj.add(new ArrayList<>(Arrays.asList(0))); adj.add(new ArrayList<>(Arrays.asList(1))); adj.add(new ArrayList<>(Arrays.asList(4))); adj.add(new ArrayList<>(Arrays.asList(0))); List<Integer> ans = printCircuit(adj); for (int v : ans) System.out.print(v + ' '); System.out.println(); } }
Python # Python program to print Eulerian circuit in given # directed graph using Hierholzer algorithm # Function to print Eulerian circuit def printCircuit(adj): n = len(adj) if n == 0: return [] # Maintain a stack to keep vertices # We can start from any vertex here we start with 0 currPath = [0] # list to store final circuit circuit = [] while len(currPath) > 0: currNode = currPath[-1] # If there's remaining edge in adjacency list # of the current vertex if len(adj[currNode]) > 0: # Find and remove the next vertex that is # adjacent to the current vertex nextNode = adj[currNode].pop() # Push the new vertex to the stack currPath.append(nextNode) # back-track to find remaining circuit else: # Remove the current vertex and # put it in the circuit circuit.append(currPath.pop()) # reverse the result vector circuit.reverse() return circuit if __name__ == '__main__': adj = [[2 3] [0] [1] [4] [0]] ans = printCircuit(adj) for v in ans: print(v end=' ') print()
C# // C# program to print Eulerian circuit in given // directed graph using Hierholzer algorithm using System; using System.Collections.Generic; class GfG { // Function to print Eulerian circuit static List<int> printCircuit(List<List<int>> adj) { int n = adj.Count; if (n == 0) return new List<int>(); // Maintain a stack to keep vertices // We can start from any vertex here we start with 0 List<int> currPath = new List<int> { 0 }; // list to store final circuit List<int> circuit = new List<int>(); while (currPath.Count > 0) { int currNode = currPath[currPath.Count - 1]; // If there's remaining edge in adjacency list // of the current vertex if (adj[currNode].Count > 0) { // Find and remove the next vertex that is // adjacent to the current vertex int nextNode = adj[currNode][adj[currNode].Count - 1]; adj[currNode].RemoveAt(adj[currNode].Count - 1); // Push the new vertex to the stack currPath.Add(nextNode); } // back-track to find remaining circuit else { // Remove the current vertex and // put it in the circuit circuit.Add(currPath[currPath.Count - 1]); currPath.RemoveAt(currPath.Count - 1); } } // reverse the result vector circuit.Reverse(); return circuit; } static void Main(string[] args) { List<List<int>> adj = new List<List<int>> { new List<int> { 2 3 } new List<int> { 0 } new List<int> { 1 } new List<int> { 4 } new List<int> { 0 } }; List<int> ans = printCircuit(adj); foreach (int v in ans) { Console.Write(v + ' '); } Console.WriteLine(); } }
JavaScript // JavaScript program to print Eulerian circuit in given // directed graph using Hierholzer algorithm // Function to print Eulerian circuit function printCircuit(adj) { let n = adj.length; if (n === 0) return []; // Maintain a stack to keep vertices // We can start from any vertex here we start with 0 let currPath = [0]; // list to store final circuit let circuit = []; while (currPath.length > 0) { let currNode = currPath[currPath.length - 1]; // If there's remaining edge in adjacency list // of the current vertex if (adj[currNode].length > 0) { // Find and remove the next vertex that is // adjacent to the current vertex let nextNode = adj[currNode].pop(); // Push the new vertex to the stack currPath.push(nextNode); } // back-track to find remaining circuit else { // Remove the current vertex and // put it in the circuit circuit.push(currPath.pop()); } } // reverse the result vector circuit.reverse(); return circuit; } let adj = [[2 3] [0] [1] [4] [0]]; let ans = printCircuit(adj); for (let v of ans) { console.log(v ' '); }
Produksjon
0 3 4 0 2 1 0
Tidskompleksitet: O(V + E) hvor V er antall toppunkter og E er antall kanter i grafen. Grunnen til dette er fordi algoritmen utfører et dybde-først-søk (DFS) og besøker hvert toppunkt og hver kant nøyaktig én gang. Så for hvert toppunkt tar det O(1) tid å besøke det, og for hver kant tar det O(1) tid å krysse det.
Romkompleksitet: O(V + E) som algoritmen bruker en stabel for å lagre gjeldende bane og en liste for å lagre den endelige kretsen. Maksimal størrelse på stabelen kan i verste fall være V + E, så plasskompleksiteten er O(V + E).
Lag quiz