Condivisione della tecnologia

Wen Xin Yi Yan VS iFlytek Spark VS chatgpt (300) -- Introduzione agli algoritmi 22.1 4 domande

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

4. Date più immagini G = ( V , E ) G=(V,E)G=(E,E)elenco collegato di adiacenza (il multigrafo è un grafico che consente bordi ripetuti e bordi con ciclo automatico), indicare un tempo di O ( V + E ) O( V + E )Lo(E+E)algoritmo, utilizzato per calcolare il grafo non orientato "equivalente" del grafo G ′ = ( V , E ′ ) G^{'}=(V,E^{'})G=(E,E) rappresentato da una lista concatenata di adiacenza.Qui E ′ E^{'}ESarà EEE I bordi ridondanti inseriti e i bordi rimanenti dopo l'eliminazione dei bordi del ciclo automatico. La rimozione dei bordi rimanenti si riferisce alla sostituzione di più bordi tra due nodi con un bordo. Se vuoi scrivere codice, usa il linguaggio go.

Le parole di Wen Xin:

Rappresentazione di liste collegate di adiacenza

Nella rappresentazione della lista concatenata di adiacenza, ogni vertice vvla Esiste una lista collegata e ciascun nodo nella lista collegata rappresenta uno schiavo vvla Bordo iniziale.per calcolare Buono a sapersiGT, dobbiamo attraversare GGG per ciascun bordo di , e invertendo la direzione del bordo, aggiungi a Buono a sapersiGT nell'elenco collegato corrispondente.

Vai all'implementazione della lingua

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)
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

complessità temporale

  • La complessità temporale dell'attraversamento di ciascun bordo è O ( E ) O(E)Lo(E),In EEE è il numero di spigoli.
  • Per ciascun bordo, eseguiamo un'operazione a tempo costante (aggiunta all'elenco di adiacenze di un altro grafico).
  • Pertanto, la complessità temporale totale è O ( E ) O(E)Lo(E)

Rappresentazione della matrice di adiacenza

Nella rappresentazione della matrice di adiacenza, utilizziamo un array bidimensionale per memorizzare le informazioni sui bordi, dove matrix[u][v] Indica se c'è una linea da uuio arrivare vvla lato.per calcolare Buono a sapersiGT, attraversiamo il triangolo superiore (o il triangolo inferiore, a seconda delle abitudini di rappresentazione della matrice) della matrice e invertiamo la direzione dei bordi, ovvero matrix[u][v] Il valore è assegnato amatrixT[v][u]

Vai all'implementazione della lingua(Versione semplificata, considera solo l'esistenza e non considera i pesi dei bordi):

// 假设使用二维布尔切片表示邻接矩阵
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函数
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

complessità temporale

  • L'iterazione su ciascun elemento della matrice richiede O(V2) O(V^2)Lo(E2) tempo, tra cui VVE è il numero di vertici.
  • Pertanto, la complessità temporale totale è O(V2) O(V^2)Lo(E2) . Questo potrebbe non essere il più efficiente quando il numero di vertici è molto maggiore del numero di spigoli.

Inserisci qui la descrizione dell'immagine

Inserisci qui la descrizione dell'immagine

Inserisci qui la descrizione dell'immagine

Inserisci qui la descrizione dell'immagine

iFlytek Spark:

Per un grafo diretto rappresentato da una lista di adiacenza, possiamo aggiungere i vertici adiacenti di ciascun vertice alla lista di adiacenza del vertice trasposto del nuovo grafo attraversando la lista di adiacenza di ciascun vertice. I passaggi specifici sono i seguenti:

  1. Crea un nuovo elenco di adiacenze Buono a sapersiGT, inizializzato su vuoto.
  2. Attraversa l'immagine originale GGG ogni vertice di vvla
  3. Vertici trasversali vvla lista concatenata di adiacenza, ogni vertice adiacente uuio Aggiungi a una nuova immagine Buono a sapersiGT vertice medio vvla nella lista collegata di adiacenza.
  4. Ritorna alla nuova immagine Buono a sapersiGT

Analisi della complessità temporale: richiede l'attraversamento di ciascun vertice del grafico originale O ( ∣ V ∣ ) O(|V|)Lo(E) Il tempo necessario per attraversare la lista di adiacenza di ciascun vertice è O ( ∣ E ∣ ) O(|E|)Lo(E) tempo, quindi la complessità temporale totale è O ( ∣ V ∣ + ∣ E ∣ ) O(|V| + |E|)Lo(E+E)

Per un grafo diretto rappresentato da una matrice di adiacenza, possiamo ottenere la matrice di adiacenza di un nuovo grafo trasponendo la matrice di adiacenza del grafo originale. I passaggi specifici sono i seguenti:

  1. Creane uno nuovo con le dimensioni ∣ V ∣ × ∣ V ∣ |V| volte |V|E×E matrice Buono a sapersiGT, inizializzato su una matrice tutta zero.
  2. Attraversa la matrice di adiacenza dell'immagine originale GGG,Volere G[io] [j] G[io][j]G[ioooo][J] Il valore è assegnato a GT[j][i]G^{T}[j][i]GT[J][ioooo]
  3. Restituisce la matrice di adiacenza del nuovo grafico Buono a sapersiGT

Analisi della complessità temporale: richiede l'attraversamento della matrice di adiacenza del grafo originale O( ∣ V ∣ 2 ) O(|V|^2)Lo(E2) tempo, quindi la complessità temporale totale è O( ∣ V ∣ 2 ) O(|V|^2)Lo(E2)

Quello che segue è il codice implementato in linguaggio 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
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

Cervello intelligente a 360°:

Rappresentazione di liste collegate di adiacenza

Nella rappresentazione della lista concatenata di adiacenza, possiamo attraversare direttamente l'immagine originale GGGL'elenco delle adiacenze di ciascun nodo viene quindi aggiunto al nuovo grafico dopo aver invertito la direzione di ciascun bordo. Buono a sapersiGTsul nodo corrispondente.

Vai all'implementazione del codice della lingua:
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
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
Analisi della complessità temporale:
  • Attraversa ciascun nodo nel grafico originale: O ( ∣ V ∣ ) O(|V|)Lo(E)
  • Attraversa la lista di adiacenza di ciascun nodo: O ( ∣ E ∣ ) O(|E|)Lo(E)

Pertanto, la complessità temporale totale è O ( ∣ V ∣ + ∣ E ∣ ) O(|V| + |E|)Lo(E+E)

Notazione delle matrici di adiacenza

Nella notazione della matrice di adiacenza, possiamo creare una nuova matrice di adiacenza e quindi attraversare l'immagine originale GGGmatrice di adiacenza, ogni elemento della matrice (io, j) (io, j)(ioooo,J)assegnato alla nuova matrice (j, io) (j, io)(J,ioooo)posizione, completando così l'inversione del bordo.

Vai all'implementazione del codice della lingua:
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
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
Analisi della complessità temporale:
  • Crea una nuova matrice di adiacenza: O( ∣ V ∣ 2 ) O(|V|^2)Lo(E2)
  • Attraversa la matrice di adiacenza dell'immagine originale: O( ∣ V ∣ 2 ) O(|V|^2)Lo(E2)

Pertanto, la complessità temporale totale è O( ∣ V ∣ 2 ) O(|V|^2)Lo(E2)

Riassumere

Per la rappresentazione della lista concatenata di adiacenza, la complessità temporale dell'algoritmo di trasposizione è O ( ∣ V ∣ + ∣ E ∣ ) O(|V| + |E|)Lo(E+E), e per la rappresentazione della matrice di adiacenza, la complessità temporale dell'algoritmo di trasposizione è O( ∣ V ∣ 2 ) O(|V|^2)Lo(E2) .Nelle applicazioni pratiche, se il grafico è relativamente scarno (es. ∣ E ∣ |E|Emolto più piccolo di ∣ V ∣ 2 |V|^2E2 ), sarebbe più efficiente utilizzare la rappresentazione della lista concatenata di adiacenza.Se il grafico è denso (es. ∣ E ∣ |E|Evicino ∣ V ∣ 2 |V|^2E2), allora la rappresentazione della matrice di adiacenza potrebbe essere più appropriata.

Spettro di saggezza parole chiare:

Nella rappresentazione grafica, gli elenchi collegati di adiacenza e le matrici di adiacenza sono entrambi metodi comunemente usati. Le liste collegate di adiacenza vengono utilizzate per rappresentare i grafi non orientati e diretti, mentre le matrici di adiacenza vengono solitamente utilizzate per rappresentare i grafi non orientati. Per la trasposizione di un grafo orientato possiamo operare separatamente sulla lista concatenata di adiacenza e sulla matrice di adiacenza.

Trasposizione di liste collegate di adiacenza

Per un grafo diretto rappresentato da una lista concatenata di adiacenza, la trasposizione del grafo può essere ottenuta attraversando ciascun vertice del grafo originale e modificando i bordi in uscita del grafo originale in bordi in entrata.

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)
		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

Trasposizione della matrice di adiacenza

Per un grafo diretto rappresentato da una matrice di adiacenza, la trasposizione del grafo può essere ottenuta trasformando ciascuna riga del grafo originale nella colonna corrispondente del nuovo grafo.

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)
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

Analisi del tempo di esecuzione dell'algoritmo

  1. Per la trasposizione di una lista concatenata di adiacenza, la complessità temporale dell'algoritmo è O(E), dove E è il numero di archi nel grafico. Questo perché ogni bordo deve essere attraversato una volta.

  2. Per la trasposizione della matrice di adiacenza, la complessità temporale dell'algoritmo è O(V^2), dove V è il numero di vertici nel grafico. Questo perché ogni elemento della matrice deve essere attraversato una volta e la dimensione della matrice è V×V.
    Questi algoritmi sono tutti efficienti e funzionano

Tiangong:

Implementare un algoritmo per calcolare un grafo orientato GGG trasposizione di Buono a sapersiGT , possiamo elaborare rispettivamente le due rappresentazioni della lista concatenata di adiacenza e della matrice di adiacenza. Di seguito descriverò rispettivamente gli algoritmi per questi due casi e fornirò esempi di codice in linguaggio Go.

Rappresentazione di liste collegate di adiacenza

Passaggi dell'algoritmo:
  1. Crea un nuovo elenco di adiacenze newAdjList Utilizzato per memorizzare il grafico trasposto.
  2. Attraversa l'elenco collegato di adiacenza dell'immagine originale adjList
  3. per ciascun bordo (u, v), aggiungilo a newAdjList[v] mezzo.
  4. Restituisce la nuova lista di adiacenze newAdjList
Vai ad esempio di codice della lingua:
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
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
Analisi del tempo di esecuzione:

Il tempo di esecuzione di questo algoritmo è O(|V| + |E|), dove |V| è il numero di vertici e |E| è il numero di archi. Questo perché dobbiamo attraversare tutti i vertici e i bordi una volta.

Notazione delle matrici di adiacenza

Passaggi dell'algoritmo:
  1. Crea una nuova matrice di adiacenza newAdjMatrix Utilizzato per memorizzare il grafico trasposto.
  2. Attraversa la matrice di adiacenza dell'immagine originale adjMatrix
  3. per ciascun elemento adjMatrix[i][j], assegnalo a newAdjMatrix[j][i]
  4. Restituisce la nuova matrice di adiacenza newAdjMatrix
Vai ad esempio di codice della lingua:
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
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
Analisi del tempo di esecuzione:

Il tempo di esecuzione di questo algoritmo è O(|V|^2), dove |V| è il numero di vertici. Questo perché dobbiamo attraversare l'intera matrice di adiacenza e la dimensione della matrice di adiacenza è |V|

L'esempio di codice sopra è solo la parte principale dell'algoritmo. Nelle applicazioni reali, potrebbe essere necessario aggiungere altre funzioni come la gestione degli errori, l'input e l'output. Inoltre, per semplificare il codice, si assume che non vi siano archi ripetuti nel grafico e che i numeri dei vertici siano numerati consecutivamente a partire da 0.

chattando:

Quello che segue è un algoritmo scritto in linguaggio Go per calcolare G ^ T dal grafico G, e vengono forniti anche i corrispondenti metodi di rappresentazione della lista concatenata di adiacenza e della matrice di adiacenza:

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)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164

La complessità temporale di questo algoritmo è O(V + E), dove V è il numero di vertici ed E è il numero di archi. Il processo di costruzione del grafo trasposto richiede l'attraversamento di tutti gli spigoli del grafo originale e l'aggiunta degli stessi al grafo trasposto al contrario, quindi la complessità temporale totale è proporzionale al numero di vertici e spigoli.

Kimi:

I grafi trasposti di grafi diretti possono essere rappresentati da due strutture dati principali: liste collegate di adiacenza e matrici di adiacenza. Di seguito presenterò rispettivamente gli algoritmi in questi due casi e fornirò codice di esempio in linguaggio Go.

Rappresentazione di liste collegate di adiacenza

Per un grafico rappresentato da una lista concatenata di adiacenza, possiamo trasporre il grafico attraversando la lista di adiacenza di ciascun vertice e quindi aggiungendo un bordo inverso a ciascun punto di adiacenza. La complessità temporale di questo metodo è O(V + E), dove V è il numero di vertici ed E è il numero di spigoli.

Vai al codice di esempio della lingua:
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
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

Rappresentazione della matrice di adiacenza

Per un grafico rappresentato da una matrice di adiacenza, possiamo implementare la trasposizione scambiando le righe e le colonne della matrice. La complessità temporale di questo metodo è O(V^2).

Vai al codice di esempio della lingua:
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
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Analisi degli algoritmi

  • lista di adiacenze : L'algoritmo deve attraversare la lista di adiacenze di ciascun vertice e, per ciascun bordo, è necessario aggiungere un bordo inverso alla lista di adiacenze del punto adiacente. Se la lunghezza media della lista dei vicini è k, la complessità temporale dell'algoritmo è O(V + E * k). Nel peggiore dei casi, k può essere vicino a V e la complessità temporale è vicina a O(V^2). Nel migliore dei casi, k è vicino a 1 e la complessità temporale è vicina a O(E).
  • matrice di adiacenza : L'algoritmo deve esaminare ciascun elemento della matrice e scambiare righe e colonne. Poiché la matrice è VxV, la complessità temporale è O(V^2).

Nelle applicazioni pratiche, quale algoritmo scegliere dipende dalla scarsità del grafico e dalla memoria disponibile. Per i grafi sparsi, le liste collegate di adiacenza possono essere più efficienti in termini di memoria; per i grafi densi, le matrici di adiacenza possono essere più efficienti.

Hunyuan:

Calcolare un grafico orientato G = ( V , E ) G=(V,E)G=(E,E) trasposizione di GT = ( V , ET ) G^T=(V,E^T)GT=(E,ET), possiamo fornire algoritmi corrispondenti per i due metodi di rappresentazione rispettivamente della lista concatenata di adiacenza e della matrice di adiacenza, e analizzare il loro tempo di esecuzione.

Rappresentazione di liste collegate di adiacenza

Descrizione dell'algoritmo
  1. Inizializza un elenco di adiacenze vuoto per memorizzare gli spigoli del grafico trasposto.
  2. Attraversa l'immagine originale GGG di tutti i nodi.
  3. per ciascun nodo uuio, attraversa tutti i nodi vicini nella sua lista di adiacenza vvla
  4. Aggiungi un nuovo elenco di adiacenze da vvla arrivare uuio lato.
  5. Dopo aver completato la traversata, la nuova lista concatenata di adiacenza è il grafo trasposto Buono a sapersiGT
Analisi del tempo di esecuzione
  • complessità temporale: O ( ∣ E ∣ ) O(|E|)Lo(E),In ∣ E ∣ |E|E è il numero di lati dell'immagine originale. Perché dobbiamo attraversare ogni bordo due volte (una volta per leggere e una volta per scrivere).

Notazione delle matrici di adiacenza

Descrizione dell'algoritmo
  1. Inizializza una matrice di adiacenza della stessa dimensione del grafico originale per memorizzare i bordi del grafico trasposto.
  2. Attraversa l'immagine originale GGG matrice di adiacenza.
  3. Per ogni elemento diverso da zero nella matrice (cioè c'è un bordo ( u , v ) ( u , v )(io,la)), posizione corrispondente nella matrice di adiacenza del grafo trasposto ( v , u ) ( v , u )(la,io) Impostato su un elemento diverso da zero.
  4. Dopo aver completato la traversata, la nuova matrice di adiacenza è il grafo trasposto Buono a sapersiGT
Analisi del tempo di esecuzione
  • complessità temporale: O( ∣ V ∣ 2 ) O(|V|^2)Lo(E2),In ∣ V ∣ |V|E è il numero di nodi nel grafico originale. Perché dobbiamo attraversare l'intera matrice di adiacenza.

Implementazione del linguaggio Go (rappresentazione dell'elenco collegato adiacente)

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()
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

In questo codice definiamo a Edge struttura per rappresentare i bordi e aAdjacencyList Struttura per rappresentare una lista collegata di adiacenza.TransposeGraph La funzione accetta aAdjacencyList parametro di tipo e restituisce una rappresentazione di lista concatenata di adiacenza del suo grafico trasposto.esisteremain funzione, creiamo un grafico di esempio, calcoliamo e stampiamo il suo grafico trasposto.