Technology Sharing

Wenxinyiyan VS iFlytek Spark VS chatgpt (300) -- Introduction to Algorithms 22.1 4 questions

2024-07-12

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

4. Given multiple images G = ( V , E ) G=(V,E) G=(V,E)(A multigraph is a graph that allows repeated edges and self-loop edges). Please give a time O ( V + E ) O(V+E) O(V+E)An algorithm is used to calculate the "equivalent" undirected graph of this graph G ′ = ( V , E ′ ) G^{'}=(V,E^{'}) G=(V,E)Here E ′ E^{'} EYes E E EThe remaining edges after deleting the redundant edges and self-loop edges in . Deleting the remaining edges means replacing multiple edges between two nodes with one edge. If you want to write code, please use the Go language.

Wen Xin Yi Yan:

Adjacency list representation

In the adjacency list representation, each vertex v v v There is a linked list, each node in the linked list represents a v v v The starting edge. In order to calculate G T G^T GT, we need to traverse G G G , and reverse the direction of the edge, adding G T G^T GT in the corresponding linked list.

Go language implementation

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

time complexity

  • The time complexity of traversing each edge is O ( E ) O(E) O(E),in E E E is the number of edges.
  • For each edge, we perform a constant-time operation (adding to the adjacency list of the other graph).
  • Therefore, the total time complexity is O ( E ) O(E) O(E)

Adjacency Matrix Representation

In the adjacency matrix representation, we use a two-dimensional array to store edge information, where matrix[u][v] Indicates whether there is a u u u arrive v v v In order to calculate G T G^T GT, we traverse the upper triangle of the matrix (or lower triangle, depending on your matrix representation habits) and reverse the direction of the edges, that is, matrix[u][v] The value ofmatrixT[v][u]

Go language implementation(Simplified version, only considering existence, not edge weights):

// 假设使用二维布尔切片表示邻接矩阵
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

time complexity

  • Iterating over each element of the matrix requires O ( V 2 ) O(V^2) O(V2) Time, of which V V V is the number of vertices.
  • Therefore, the total time complexity is O ( V 2 ) O(V^2) O(V2). This may not be the most efficient when the number of vertices is much larger than the number of edges.

insert image description here

insert image description here

insert image description here

insert image description here

iFlytek Spark:

For a directed graph represented by an adjacency list, we can traverse the adjacency list of each vertex and add the adjacent vertices of each vertex to the adjacency list of the transposed vertex of the new graph. The specific steps are as follows:

  1. Create a new adjacency list G T G^{T} GT, initialized to empty.
  2. Traverse the original image G G G Each vertex of v v v
  3. Traversing vertices v v v The adjacency list of each adjacent vertex u u u Add to new diagram G T G^{T} GT Midpoint v v v in the adjacency linked list.
  4. Return to new image G T G^{T} GT

Time complexity analysis: traversing each vertex of the original graph requires O ( ∣ V ∣ ) O(|V|) O(V) time, it takes to traverse the adjacency list of each vertex O ( ∣ E ∣ ) O(|E|) O(E) time, so the total time complexity is O ( ∣ V ∣ + ∣ E ∣ ) O(|V| + |E|) O(V+E)

For a directed graph represented by an adjacency matrix, we can obtain the adjacency matrix of the new graph by transposing the adjacency matrix of the original graph. The specific steps are as follows:

  1. Create a new size ∣ V ∣ × ∣ V ∣ |V| times |V| V×V The matrix G T G^{T} GT, initialized to an all-zero matrix.
  2. Traverse the adjacency matrix of the original graph G G G,Will G [ i ] [ j ] G[i][j] G[i][j] The value of G T [ j ] [ i ] G^{T}[j][i] GT[j][i]
  3. Returns the adjacency matrix of the new graph G T G^{T} GT

Time complexity analysis: Traversing the adjacency matrix of the original graph requires O ( ∣ V ∣ 2 ) O(|V|^2) O(V2) time, so the total time complexity is O ( ∣ V ∣ 2 ) O(|V|^2) O(V2)

The following is the code implemented in Go language:

// 邻接链表表示的有向图转置
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

360 Smart Brain:

Adjacency List Representation

In the adjacency list representation, we can directly traverse the original graph G G GThe adjacency list of each node is then reversed and added to the new graph. G T G^{T} GTon the corresponding node.

Go language code implementation:
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
Time complexity analysis:
  • Traverse each node in the original graph: O ( ∣ V ∣ ) O(|V|) O(V)
  • Traverse the adjacency list of each node: O ( ∣ E ∣ ) O(|E|) O(E)

Therefore, the total time complexity is O ( ∣ V ∣ + ∣ E ∣ ) O(|V| + |E|) O(V+E)

Adjacency Matrix Representation

In adjacency matrix representation, we can create a new adjacency matrix and then traverse the original graph G G GThe adjacency matrix of ( i , j ) (i, j) (i,j)Assign to the new matrix ( j , i ) (j, i) (j,i)position, thus completing the reversal of the edge.

Go language code implementation:
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
Time complexity analysis:
  • Create a new adjacency matrix: O ( ∣ V ∣ 2 ) O(|V|^2) O(V2)
  • Traverse the adjacency matrix of the original graph: O ( ∣ V ∣ 2 ) O(|V|^2) O(V2)

Therefore, the total time complexity is O ( ∣ V ∣ 2 ) O(|V|^2) O(V2)

Summarize

For the adjacency list representation, the time complexity of the transposition algorithm is O ( ∣ V ∣ + ∣ E ∣ ) O(|V| + |E|) O(V+E), while for the adjacency matrix representation, the time complexity of the transposition algorithm is O ( ∣ V ∣ 2 ) O(|V|^2) O(V2)In practical applications, if the graph is sparse (i.e. ∣ E ∣ |E| EMuch smaller than ∣ V ∣ 2 |V|^2 V2), it is more efficient to use the adjacency list representation. If the graph is dense (i.e. ∣ E ∣ |E| Enear ∣ V ∣ 2 |V|^2 V2), then the adjacency matrix representation may be more appropriate.

Zhipu Qingyan:

In the representation of graphs, adjacency lists and adjacency matrices are both commonly used methods. Adjacency lists are used to represent undirected graphs and directed graphs, while adjacency matrices are usually used to represent undirected graphs. For the transpose of a directed graph, we can operate on the adjacency list and adjacency matrix respectively.

Transpose of adjacency list

For a directed graph represented by an adjacency list, the transposed graph can be realized by traversing each vertex of the original graph and modifying the outgoing edges of the original graph into incoming edges.

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

Transpose of the adjacency matrix

For a directed graph represented by an adjacency matrix, the transposed graph can be achieved by converting each row of the original graph into the corresponding column of the new graph.

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

Algorithm running time analysis

  1. For the transpose of an adjacency list, the algorithm has a time complexity of O(E), where E is the number of edges in the graph. This is because each edge needs to be traversed once.

  2. For the transpose of the adjacency matrix, the time complexity of the algorithm is O(V^2), where V is the number of vertices in the graph. This is because each matrix element needs to be traversed once, and the size of the matrix is ​​V×V.
    These algorithms are all valid and run

Heavenly craftsmanship:

To implement an algorithm to calculate the directed graph G G G Transpose G T G^{T} GT, we can handle the two representations separately, the adjacency list and the adjacency matrix. Below I will describe the algorithms for both cases and provide code examples in Go.

Adjacency List Representation

Algorithm steps:
  1. Create a new adjacency list newAdjList Used to store the transposed graph.
  2. Traverse the adjacency list of the original graph adjList
  3. For each edge (u, v), add it to newAdjList[v] middle.
  4. Returns a new adjacency list newAdjList
Go language code example:
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
Run time analysis:

The running time of this algorithm is O(|V| + |E|), where |V| is the number of vertices and |E| is the number of edges. This is because we need to traverse all vertices and edges exactly once.

Adjacency Matrix Representation

Algorithm steps:
  1. Create a new adjacency matrix newAdjMatrix Used to store the transposed graph.
  2. Traverse the adjacency matrix of the original graph adjMatrix
  3. For each element adjMatrix[i][j], assign it to newAdjMatrix[j][i]
  4. Returns the new adjacency matrix newAdjMatrix
Go language code example:
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
Run time analysis:

The running time of this algorithm is O(|V|^2), where |V| is the number of vertices. This is because we need to traverse the entire adjacency matrix, and the size of the adjacency matrix is ​​|V| x |V|.

The above code examples are only the core part of the algorithm. In actual applications, you may need to add other functions such as error handling, input and output. In addition, to simplify the code, it is assumed that there are no repeated edges in the graph and the vertex numbers are numbered consecutively starting from 0.

chatgpt:

The following is an algorithm written in Go language to calculate G^T from graph G, and the corresponding adjacency list and adjacency matrix representation methods are also given:

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

The time complexity of this algorithm is O(V + E), where V is the number of vertices and E is the number of edges. The construction process of the transposed graph requires traversing all the edges of the original graph and adding them in reverse to the transposed graph, so the total time complexity is proportional to the number of vertices and edges.

kimi:

The transposed graph of a directed graph can be represented by two main data structures: an adjacency list and an adjacency matrix. Below I will introduce the algorithms for both cases and provide example code in Go.

Adjacency list representation

For a graph represented by an adjacency list, we can transpose the graph by traversing the adjacency list of each vertex and then adding a reverse edge to each adjacent vertex. The time complexity of this method is O(V + E), where V is the number of vertices and E is the number of edges.

Go language sample code:
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

Adjacency Matrix Representation

For a graph represented by an adjacency matrix, we can perform the transposition by swapping the rows and columns of the matrix. The time complexity of this method is O(V^2).

Go language sample code:
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

Analysis of Algorithms

  • Adjacency List:The algorithm needs to traverse the adjacency list of each vertex, and for each edge, it needs to add the reverse edge to the adjacency list of the adjacent vertex. If the average length of the adjacency list is k, the time complexity of the algorithm is O(V + E * k). In the worst case, k can be close to V, and the time complexity is close to O(V^2). In the best case, k is close to 1, and the time complexity is close to O(E).
  • Adjacency Matrix: The algorithm needs to traverse each element of the matrix and swap the rows and columns. Since the matrix is ​​VxV, the time complexity is O(V^2).

In practice, the choice of algorithm depends on the sparsity of the graph and the available memory. For sparse graphs, an adjacency list may be more memory-efficient, while for dense graphs, an adjacency matrix may be more efficient.

Mixed:

To calculate the directed graph G = ( V , E ) G=(V,E) G=(V,E) Transpose G T = ( V , E T ) G^T=(V,E^T) GT=(V,ET), we can give corresponding algorithms for the two representation methods of adjacency list and adjacency matrix respectively, and analyze their running time.

Adjacency List Representation

Algorithm Description
  1. Initialize an empty adjacency list to store the edges of the transposed graph.
  2. Traverse the original image G G G All nodes.
  3. For each node u u u, traverse all neighbor nodes in its adjacency list v v v
  4. Add a new adjacency list from v v v arrive u u u edge.
  5. After the traversal is completed, the new adjacency list is the transposed graph G T G^T GT
Run time analysis
  • time complexity: O ( ∣ E ∣ ) O(|E|) O(E),in ∣ E ∣ |E| E is the number of edges in the original graph. Because we need to traverse each edge twice (once to read and once to write).

Adjacency Matrix Representation

Algorithm Description
  1. Initialize an adjacency matrix of the same size as the original graph to store the edges of the transposed graph.
  2. Traverse the original image G G G The adjacency matrix of .
  3. For every non-zero element in the matrix (i.e., there is an edge ( u , v ) (u, v) (u,v)), corresponding to the position in the adjacency matrix of the transposed graph ( v , u ) (v, u) (v,u) Set to non-zero elements.
  4. After the traversal is completed, the new adjacency matrix is ​​the transposed graph G T G^T GT
Run time analysis
  • time complexity: O ( ∣ V ∣ 2 ) O(|V|^2) O(V2),in ∣ V ∣ |V| V is the number of nodes in the original graph. Because we need to traverse the entire adjacency matrix.

Go language implementation (adjacency list representation)

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 this code, we define a Edge structures to represent edges, and aAdjacencyList Structure to represent adjacency linked list.TransposeGraph The function accepts aAdjacencyList Type argument and returns an adjacency list representation of its transposed graph.main In the function, we create a sample graph and calculate and print its transposed graph.