τα στοιχεία επικοινωνίας μου
Ταχυδρομείο[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Στην αναπαράσταση λίστας με συνδεδεμένη γειτνίαση, κάθε κορυφή vvv Υπάρχει μια συνδεδεμένη λίστα και κάθε κόμβος στη συνδεδεμένη λίστα αντιπροσωπεύει έναν slave vvv Αρχική άκρη.για να υπολογίσετε GTG^TσολΤ, πρέπει να διασχίσουμε GGσολ για κάθε άκρη του , και αντιστρέφοντας την κατεύθυνση της άκρης, προσθέστε στο GTG^TσολΤ στην αντίστοιχη συνδεδεμένη λίστα.
Υλοποίηση γλώσσας Go:
package main
import (
"fmt"
)
// Graph 使用邻接链表表示
type Graph struct {
vertices int
adjList map[int][]int
}
// NewGraph 创建一个新的图
func NewGraph(vertices int) *Graph {
return &Graph{
vertices: vertices,
adjList: make(map[int][]int),
}
}
// AddEdge 添加一条边到图中
func (g *Graph) AddEdge(u, v int) {
g.adjList[u] = append(g.adjList[u], v)
}
// Transpose 计算图的转置
func (g *Graph) Transpose() *Graph {
gT := NewGraph(g.vertices)
for u, adj := range g.adjList {
for _, v := range adj {
gT.AddEdge(v, u) // 反转边的方向
}
}
return gT
}
func main() {
g := NewGraph(4)
g.AddEdge(0, 1)
g.AddEdge(0, 2)
g.AddEdge(1, 2)
g.AddEdge(2, 0)
g.AddEdge(2, 3)
gT := g.Transpose()
fmt.Println("Original Graph:")
for u, adj := range g.adjList {
fmt.Printf("%d -> %vn", u, adj)
}
fmt.Println("nTransposed Graph:")
for u, adj := range gT.adjList {
fmt.Printf("%d -> %vn", u, adj)
}
}
χρονική πολυπλοκότητα:
Στην αναπαράσταση του πίνακα γειτνίασης, χρησιμοποιούμε έναν δισδιάστατο πίνακα για την αποθήκευση πληροφοριών ακμών, όπου matrix[u][v]
Υποδεικνύει εάν υπάρχει γραμμή από uuu φθάνω vvv πλευρά.για να υπολογίσετε GTG^TσολΤ, διασχίζουμε το πάνω τρίγωνο (ή το κάτω τρίγωνο, ανάλογα με τις συνήθειες αναπαράστασης του πίνακα) του πίνακα και αντιστρέφουμε την κατεύθυνση των άκρων, δηλαδή, matrix[u][v]
Η τιμή εκχωρείται σεmatrixT[v][u]
。
Υλοποίηση γλώσσας Go(Απλοποιημένη έκδοση, εξετάζει μόνο την ύπαρξη και δεν λαμβάνει υπόψη τα βάρη ακμών):
// 假设使用二维布尔切片表示邻接矩阵
type GraphMatrix [][]bool
// Transpose 计算图的转置
func (g GraphMatrix) Transpose() GraphMatrix {
n := len(g)
gT := make(GraphMatrix, n)
for i := range gT {
gT[i] = make([]bool, n)
}
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
gT[j][i] = g[i][j] // 反转边的方向
}
}
return gT
}
// 注意:这里没有完整的GraphMatrix类型实现,因为示例仅关注Transpose函数
χρονική πολυπλοκότητα:
Για ένα κατευθυνόμενο γράφημα που αντιπροσωπεύεται από μια λίστα γειτνίασης, μπορούμε να προσθέσουμε τις γειτονικές κορυφές κάθε κορυφής στη λίστα γειτνίασης της μετατιθέμενης κορυφής του νέου γραφήματος διασχίζοντας τη λίστα γειτνίασης κάθε κορυφής. Τα συγκεκριμένα βήματα είναι τα εξής:
Ανάλυση χρονικής πολυπλοκότητας: απαιτείται η διέλευση κάθε κορυφής του αρχικού γραφήματος O ( ∣ V ∣ ) O(|V|)Ο(∣V∣) Ο χρόνος που απαιτείται για τη διέλευση της λίστας γειτνίασης κάθε κορυφής είναι O ( ∣ E ∣ ) O(|E|)Ο(∣μι∣) χρόνος, άρα η συνολική χρονική πολυπλοκότητα είναι O ( ∣ V ∣ + ∣ E ∣ ) O(|V| + |E|)Ο(∣V∣+∣μι∣)。
Για ένα κατευθυνόμενο γράφημα που αντιπροσωπεύεται από έναν πίνακα γειτνίασης, μπορούμε να λάβουμε τον πίνακα γειτνίασης ενός νέου γραφήματος μεταφέροντας τον πίνακα γειτνίασης του αρχικού γραφήματος. Τα συγκεκριμένα βήματα είναι τα εξής:
Ανάλυση χρονικής πολυπλοκότητας: απαιτείται η διέλευση του πίνακα γειτνίασης του αρχικού γραφήματος O ( ∣ V ∣ 2 ) O(|V|^2)Ο(∣V∣2) χρόνος, άρα η συνολική χρονική πολυπλοκότητα είναι O ( ∣ V ∣ 2 ) O(|V|^2)Ο(∣V∣2)。
Ο παρακάτω είναι ο κώδικας που εφαρμόζεται στη γλώσσα Go:
// 邻接链表表示的有向图转置
func transposeAdjList(G map[int][]int) map[int][]int {
GT := make(map[int][]int)
for v, neighbors := range G {
for _, u := range neighbors {
GT[u] = append(GT[u], v)
}
}
return GT
}
// 邻接矩阵表示的有向图转置
func transposeAdjMatrix(G [][]int) [][]int {
n := len(G)
GT := make([][]int, n)
for i := range GT {
GT[i] = make([]int, n)
}
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
GT[j][i] = G[i][j]
}
}
return GT
}
Στην αναπαράσταση λίστας με συνδεδεμένη γειτνίαση, μπορούμε να διασχίσουμε απευθείας την αρχική εικόνα GGσολΗ λίστα γειτνίασης κάθε κόμβου προστίθεται στη συνέχεια στο νέο γράφημα αφού αντιστραφεί η κατεύθυνση κάθε ακμής. GTG^{T}σολΤστον αντίστοιχο κόμβο.
type Graph struct {
Vertices []*Node // 存储图中所有节点的指针
}
type Node struct {
Value int
Adjacent []*Node // 存储与该节点相邻的所有节点的指针
}
func (g *Graph) Transpose() *Graph {
transposed := &Graph{make([]*Node, len(g.Vertices))}
for i, node := range g.Vertices {
transposed.Vertices[i] = &Node{node.Value, make([]*Node, 0)}
}
for _, node := range g.Vertices {
for _, adj := range node.Adjacent {
// 将边反向添加到转置图中
transposed.Vertices[adj.Value].Adjacent = append(transposed.Vertices[adj.Value].Adjacent, transposed.Vertices[node.Value])
}
}
return transposed
}
Επομένως, η συνολική χρονική πολυπλοκότητα είναι O ( ∣ V ∣ + ∣ E ∣ ) O(|V| + |E|)Ο(∣V∣+∣μι∣)。
Στη σημειογραφία μήτρας γειτνίασης, μπορούμε να δημιουργήσουμε μια νέα μήτρα γειτνίασης και στη συνέχεια να διασχίσουμε την αρχική εικόνα GGσολμήτρα γειτνίασης, κάθε στοιχείο στη μήτρα ( i , j ) (i, j)(Εγώ,ι)εκχωρήθηκε στη νέα μήτρα ( j , i ) (j, i)(ι,Εγώ)θέση, ολοκληρώνοντας έτσι την αναστροφή της άκρης.
type MatrixGraph struct {
Matrix [][]bool // 存储邻接矩阵
}
func (mg *MatrixGraph) Transpose() *MatrixGraph {
transposed := &MatrixGraph{make([][]bool, len(mg.Matrix))}
for i := range mg.Matrix {
transposed.Matrix[i] = make([]bool, len(mg.Matrix))
for j := range mg.Matrix[i] {
// 将边反向赋值到转置矩阵中
transposed.Matrix[i][j] = mg.Matrix[j][i]
}
}
return transposed
}
Επομένως, η συνολική χρονική πολυπλοκότητα είναι O ( ∣ V ∣ 2 ) O(|V|^2)Ο(∣V∣2)。
Για την αναπαράσταση λίστας συνδεδεμένης γειτνίασης, η χρονική πολυπλοκότητα του αλγόριθμου μεταφοράς είναι O ( ∣ V ∣ + ∣ E ∣ ) O(|V| + |E|)Ο(∣V∣+∣μι∣)και για την αναπαράσταση του πίνακα γειτνίασης, η χρονική πολυπλοκότητα του αλγορίθμου μεταφοράς είναι O ( ∣ V ∣ 2 ) O(|V|^2)Ο(∣V∣2) .Σε πρακτικές εφαρμογές, εάν το γράφημα είναι σχετικά αραιό (δηλ. ∣ E ∣ |E|∣μι∣πολύ μικρότερο από ∣ V ∣ 2 |V|^2∣V∣2 ), θα ήταν πιο αποτελεσματικό να χρησιμοποιήσετε την αναπαράσταση της συνδεδεμένης λίστας γειτνίασης.Εάν το γράφημα είναι πυκνό (δηλ. ∣ E ∣ |E|∣μι∣κοντά ∣ V ∣ 2 |V|^2∣V∣2), τότε η αναπαράσταση του πίνακα γειτνίασης μπορεί να είναι πιο κατάλληλη.
Στην αναπαράσταση γραφήματος, οι λίστες συνδεδεμένες με γειτνίαση και οι πίνακες γειτνίασης είναι και οι δύο μέθοδοι που χρησιμοποιούνται συνήθως. Οι λίστες γειτονικών συνδέσεων χρησιμοποιούνται για την αναπαράσταση μη κατευθυνόμενων και κατευθυνόμενων γραφημάτων, ενώ οι πίνακες γειτνίασης χρησιμοποιούνται συνήθως για την αναπαράσταση μη κατευθυνόμενων γραφημάτων. Για τη μεταφορά ενός κατευθυνόμενου γραφήματος, μπορούμε να λειτουργήσουμε ξεχωριστά τη συνδεδεμένη λίστα γειτνίασης και τον πίνακα γειτνίασης.
Για ένα κατευθυνόμενο γράφημα που αντιπροσωπεύεται από μια συνδεδεμένη λίστα γειτνίασης, η μεταφορά του γραφήματος μπορεί να επιτευχθεί διασχίζοντας κάθε κορυφή του αρχικού γραφήματος και τροποποιώντας τις εξερχόμενες ακμές του αρχικού γραφήματος σε εισερχόμενες ακμές.
package main
import (
"fmt"
)
// 定义图的顶点结构
type Vertex struct {
Name string
Edges []*Vertex
Visited bool
}
// 计算图的转置
func Transpose(g *Vertex) {
for _, v := range g.Edges {
// 遍历顶点v的所有出边
for _, w := range v.Edges {
// 在原图中查找顶点w指向顶点v的边,并反转
for i, e := range w.Edges {
if e == v {
w.Edges[i] = v
break
}
}
}
}
}
func main() {
// 创建顶点
a := &Vertex{Name: "A"}
b := &Vertex{Name: "B"}
c := &Vertex{Name: "C"}
// 建立有向图关系
a.Edges = []*Vertex{b, c}
b.Edges = []*Vertex{a}
c.Edges = []*Vertex{a}
// 打印原图
fmt.Println("原图:")
PrintGraph(a)
// 计算转置图
Transpose(a)
// 打印转置图
fmt.Println("转置图:")
PrintGraph(a)
}
// PrintGraph 用于打印图的邻接链表表示
func PrintGraph(g *Vertex) {
g.Visited = true
for _, v := range g.Edges {
if !v.Visited {
fmt.Println(g.Name, "->", v.Name)
PrintGraph(v)
}
}
}
Για ένα κατευθυνόμενο γράφημα που αντιπροσωπεύεται από έναν πίνακα γειτνίασης, η μεταφορά του γραφήματος μπορεί να επιτευχθεί μετατρέποντας κάθε σειρά του αρχικού γραφήματος στην αντίστοιχη στήλη του νέου γραφήματος.
package main
import (
"fmt"
)
// 计算邻接矩阵的转置
func TransposeMatrix(mat [][]int) [][]int {
transposed := make([][]int, len(mat[0]))
for i := range transposed {
transposed[i] = make([]int, len(mat))
}
for i, row := range mat {
for j, val := range row {
if val == 1 {
transposed[j][i] = 1
}
}
}
return transposed
}
func main() {
// 创建邻接矩阵
originalMatrix := [][]int{
{0, 1, 1},
{0, 0, 1},
{1, 0, 0},
}
// 计算转置矩阵
transposedMatrix := TransposeMatrix(originalMatrix)
// 打印转置矩阵
fmt.Println("转置矩阵:")
for _, row := range transposedMatrix {
fmt.Println(row)
}
}
Για τη μεταφορά μιας λίστας συνδεδεμένης γειτνίασης, η χρονική πολυπλοκότητα του αλγορίθμου είναι O(E), όπου E είναι ο αριθμός των ακμών στο γράφημα. Αυτό συμβαίνει επειδή κάθε άκρη πρέπει να διασχιστεί μία φορά.
Για τη μεταφορά του πίνακα γειτνίασης, η χρονική πολυπλοκότητα του αλγορίθμου είναι O(V^2), όπου V είναι ο αριθμός των κορυφών στο γράφημα. Αυτό συμβαίνει επειδή κάθε στοιχείο πίνακα πρέπει να διασχιστεί μία φορά και το μέγεθος του πίνακα είναι V×V.
Αυτοί οι αλγόριθμοι είναι όλοι αποτελεσματικοί και εκτελούνται
Να εφαρμόσει έναν αλγόριθμο για τον υπολογισμό ενός κατευθυνόμενου γραφήματος GGσολ μεταφορά του GTG^{T}σολΤ , μπορούμε να επεξεργαστούμε τις δύο αναπαραστάσεις της συνδεδεμένης λίστας γειτνίασης και της μήτρας γειτνίασης αντίστοιχα. Παρακάτω θα περιγράψω τους αλγόριθμους για αυτές τις δύο περιπτώσεις αντίστοιχα και θα δώσω παραδείγματα κώδικα στη γλώσσα Go.
newAdjList
Χρησιμοποιείται για την αποθήκευση του μεταφερόμενου γραφήματος.adjList
。(u, v)
, προσθέστε το σε newAdjList[v]
Μέσης.newAdjList
。type Graph struct {
vertices []*Vertex
}
type Vertex struct {
key int
adjacent []*Vertex
}
func (g *Graph) Transpose() *Graph {
gt := &Graph{make([]*Vertex, len(g.vertices))}
for i := range g.vertices {
gt.vertices[i] = &Vertex{key: i}
}
for _, u := range g.vertices {
for _, v := range u.adjacent {
// Add edge (v, u) to the transpose graph.
gt.vertices[v.key].adjacent = append(gt.vertices[v.key].adjacent, gt.vertices[u.key])
}
}
return gt
}
Ο χρόνος εκτέλεσης αυτού του αλγόριθμου είναι O(|V| + |E|), όπου |V| είναι ο αριθμός των κορυφών και |E|. Αυτό συμβαίνει γιατί πρέπει να διασχίσουμε όλες τις κορυφές και τις ακμές μία φορά.
newAdjMatrix
Χρησιμοποιείται για την αποθήκευση του μεταφερόμενου γραφήματος.adjMatrix
。adjMatrix[i][j]
, αναθέστε το σε newAdjMatrix[j][i]
。newAdjMatrix
。type Graph struct {
matrix [][]bool
}
func (g *Graph) Transpose() *Graph {
gt := &Graph{make([][]bool, len(g.matrix))}
for i := range gt.matrix {
gt.matrix[i] = make([]bool, len(g.matrix))
}
for i := range g.matrix {
for j := range g.matrix[i] {
// Copy the adjacency values with swapped indices.
gt.matrix[j][i] = g.matrix[i][j]
}
}
return gt
}
Ο χρόνος εκτέλεσης αυτού του αλγόριθμου είναι O(|V|^2), όπου |V| είναι ο αριθμός των κορυφών. Αυτό συμβαίνει επειδή πρέπει να διασχίσουμε ολόκληρο τον πίνακα γειτνίασης και το μέγεθος του πίνακα γειτνίασης είναι |V x |V|.
Το παραπάνω παράδειγμα κώδικα είναι μόνο το βασικό μέρος του αλγορίθμου Σε πραγματικές εφαρμογές, ενδέχεται να χρειαστεί να προστεθούν άλλες λειτουργίες, όπως ο χειρισμός σφαλμάτων, η είσοδος και η έξοδος. Επιπλέον, για να απλοποιηθεί ο κώδικας, θεωρείται ότι δεν υπάρχουν επαναλαμβανόμενες ακμές στο γράφημα και οι αριθμοί κορυφής αριθμούνται διαδοχικά ξεκινώντας από το 0.
Ο παρακάτω είναι ένας αλγόριθμος γραμμένος σε γλώσσα Go για τον υπολογισμό του G^T από το γράφημα G και δίνονται επίσης οι αντίστοιχες συνδεδεμένες γειτονικές μέθοδοι αναπαράστασης λίστας και μήτρας γειτνίασης:
package main
import "fmt"
// 图的节点结构体
type Node struct {
Value int // 节点的值
Next *Node // 下一个节点指针
}
// 邻接链表表示法的图结构体
type Graph struct {
Vertices []*Node // 图中所有节点的数组
}
// 添加有向边到邻接链表
func (g *Graph) AddEdge(u, v int) {
newNode := &Node{Value: v}
if g.Vertices[u] == nil {
g.Vertices[u] = newNode
} else {
curr := g.Vertices[u]
for curr.Next != nil {
curr = curr.Next
}
curr.Next = newNode
}
}
// 输出邻接链表表示的图信息
func (g *Graph) Print() {
for i, node := range g.Vertices {
fmt.Printf("顶点 %d:", i)
for node != nil {
fmt.Printf("%d ", node.Value)
node = node.Next
}
fmt.Println()
}
}
// 获取图 G 的转置图 G^T 的邻接链表表示法
func GetTranspose(g *Graph) *Graph {
transpose := &Graph{
Vertices: make([]*Node, len(g.Vertices)),
}
for i, node := range g.Vertices {
for node != nil {
v := node.Value
// 在转置图中添加反向边
transpose.AddEdge(v, i)
node = node.Next
}
}
return transpose
}
// 输出邻接链表表示的转置图信息
func PrintTranspose(g *Graph) {
fmt.Println("转置图 G^T:")
g.Print()
}
// 邻接矩阵表示法的图结构体
type Matrix struct {
Vertices [][]int // 邻接矩阵,存储边的连接关系(0 表示无边,1 表示有边)
}
// 初始化邻接矩阵表示的图
func InitMatrix(numVertices int) *Matrix {
matrix := &Matrix{
Vertices: make([][]int, numVertices),
}
for i := range matrix.Vertices {
matrix.Vertices[i] = make([]int, numVertices)
}
return matrix
}
// 添加有向边到邻接矩阵
func (m *Matrix) AddEdge(u, v int) {
m.Vertices[u][v] = 1
}
// 获取图 G 的转置图 G^T 的邻接矩阵表示法
func GetTransposeMatrix(m *Matrix) *Matrix {
numRows := len(m.Vertices)
numCols := len(m.Vertices[0])
transpose := InitMatrix(numRows)
for i := 0; i < numRows; i++ {
for j := 0; j < numCols; j++ {
if m.Vertices[i][j] == 1 {
// 在转置矩阵中添加反向边
transpose.AddEdge(j, i)
}
}
}
return transpose
}
// 输出邻接矩阵表示的转置图信息
func PrintTransposeMatrix(m *Matrix) {
numRows := len(m.Vertices)
numCols := len(m.Vertices[0])
fmt.Println("转置图 G^T:")
for i := 0; i < numRows; i++ {
fmt.Printf("顶点 %d:", i)
for j := 0; j < numCols; j++ {
if m.Vertices[i][j] == 1 {
fmt.Printf("%d ", j)
}
}
fmt.Println()
}
}
func main() {
// 邻接链表表示的有向图 G
g := &Graph{
Vertices: make([]*Node, 4),
}
g.AddEdge(0, 1)
g.AddEdge(1, 2)
g.AddEdge(2, 3)
g.AddEdge(3, 1)
// 输出原始图 G 的邻接链表表示法
fmt.Println("原始图 G:")
g.Print()
// 获取转置图 G^T 的邻接链表表示法并输出
transpose := GetTranspose(g)
PrintTranspose(transpose)
// 邻接矩阵表示的有向图 G
m := InitMatrix(4)
m.AddEdge(0, 1)
m.AddEdge(1, 2)
m.AddEdge(2, 3)
m.AddEdge(3, 1)
// 输出原始图 G 的邻接矩阵表示法
fmt.Println("原始图 G:")
for _, row := range m.Vertices {
fmt.Println(row)
}
// 获取转置图 G^T 的邻接矩阵表示法并输出
transposeMatrix := GetTransposeMatrix(m)
PrintTransposeMatrix(transposeMatrix)
}
Η χρονική πολυπλοκότητα αυτού του αλγορίθμου είναι O(V + E), όπου V είναι ο αριθμός των κορυφών και E είναι ο αριθμός των ακμών. Η διαδικασία κατασκευής του μετατιθέμενου γραφήματος απαιτεί τη διέλευση όλων των άκρων του αρχικού γραφήματος και την πρόσθεσή τους στο μεταφερόμενο γράφημα αντίστροφα, έτσι ώστε η συνολική χρονική πολυπλοκότητα να είναι ανάλογη με τον αριθμό των κορυφών και των ακμών.
Τα μεταφερθέντα γραφήματα κατευθυνόμενων γραφημάτων μπορούν να αναπαρασταθούν από δύο κύριες δομές δεδομένων: λίστες συνδεδεμένες με γειτνίαση και πίνακες γειτνίασης. Παρακάτω θα παρουσιάσω τους αλγόριθμους σε αυτές τις δύο περιπτώσεις αντίστοιχα και θα παράσχω δείγμα κώδικα στη γλώσσα Go.
Για ένα γράφημα που αντιπροσωπεύεται από μια συνδεδεμένη λίστα γειτνίασης, μπορούμε να μεταφέρουμε το γράφημα διασχίζοντας τη λίστα γειτνίασης κάθε κορυφής και στη συνέχεια προσθέτοντας μια αντίστροφη ακμή σε κάθε σημείο γειτονίας. Η χρονική πολυπλοκότητα αυτής της μεθόδου είναι O(V + E), όπου V είναι ο αριθμός των κορυφών και E είναι ο αριθμός των ακμών.
type Vertex struct {
Value int
Adj []Vertex
}
func transposeGraph(graph []Vertex) []Vertex {
transposed := make([]Vertex, len(graph))
for _, v := range graph {
for _, adjV := range v.Adj {
// 为邻接点添加反向边
found := false
for _, tV := range transposed[adjV.Value].Adj {
if tV.Value == v.Value {
found = true
break
}
}
if !found {
transposed[adjV.Value].Adj = append(transposed[adjV.Value].Adj, v)
}
}
}
return transposed
}
Για ένα γράφημα που αντιπροσωπεύεται από έναν πίνακα γειτνίασης, μπορούμε να εφαρμόσουμε τη μεταφορά ανταλλάσσοντας τις γραμμές και τις στήλες του πίνακα. Η χρονική πολυπλοκότητα αυτής της μεθόδου είναι O(V^2).
func transposeMatrix(matrix [][]int) [][]int {
n := len(matrix)
transposed := make([][]int, n)
for i := 0; i < n; i++ {
transposed[i] = make([]int, n)
for j := 0; j < n; j++ {
transposed[i][j] = matrix[j][i]
}
}
return transposed
}
Σε πρακτικές εφαρμογές, ποιος αλγόριθμος να επιλέξει εξαρτάται από την αραιότητα του γραφήματος και τη διαθέσιμη μνήμη. Για αραιά γραφήματα, οι λίστες γειτονικών συνδέσεων μπορεί να είναι πιο αποδοτικές στη μνήμη για πυκνά γραφήματα, οι πίνακες γειτνίασης μπορεί να είναι πιο αποτελεσματικοί.
Για να υπολογίσετε ένα κατευθυνόμενο γράφημα G = ( V , E ) G=(V,E)σολ=(V,μι) μεταφορά του GT = ( V , ET ) G^T=(V,E^T)σολΤ=(V,μιΤ), μπορούμε να δώσουμε αντίστοιχους αλγόριθμους για τις δύο μεθόδους αναπαράστασης της συνδεδεμένης λίστας γειτνίασης και της μήτρας γειτνίασης αντίστοιχα, και να αναλύσουμε τον χρόνο εκτέλεσης τους.
type Edge struct {
dest int
}
type AdjacencyList struct {
edges map[int][]Edge
}
func TransposeGraph(graph AdjacencyList) AdjacencyList {
transposed := AdjacencyList{edges: make(map[int][]Edge)}
for u, neighbors := range graph.edges {
for _, edge := range neighbors {
v := edge.dest
transposed.edges[v] = append(transposed.edges[v], Edge{dest: u})
}
}
return transposed
}
func main() {
// 示例图的邻接链表表示
graph := AdjacencyList{edges: map[int][]Edge{
0: {{dest: 1}},
1: {{dest: 2}},
2: {{dest: 0}},
}}
// 计算转置图
transposedGraph := TransposeGraph(graph)
// 打印转置图的邻接链表
for u, neighbors := range transposedGraph.edges {
fmt.Printf("Node %d -> Nodes: ", u)
for _, edge := range neighbors {
fmt.Printf("%d ", edge.dest)
}
fmt.Println()
}
}
Σε αυτόν τον κώδικα ορίζουμε α Edge
δομή για την αναπαράσταση ακμών, και αAdjacencyList
Δομή για την αναπαράσταση μιας συνδεδεμένης λίστας γειτνίασης.TransposeGraph
Η συνάρτηση δέχεται αAdjacencyList
τύπου παράμετρος και επιστρέφει μια αναπαράσταση λίστας συνδεδεμένης γειτονίας του μεταφερθέντος γραφήματος.υπάρχειmain
συνάρτηση, δημιουργούμε ένα παράδειγμα γραφήματος, υπολογίζουμε και εκτυπώνουμε το μεταφερόμενο γράφημα του.