기술나눔

Wen Xin Yi Yan VS iFlytek Spark VS chatgpt (300) -- 알고리즘 22.1 소개 4개의 질문

2024-07-12

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

4. 여러 장의 사진이 주어졌습니다. G = ( V , E ) G = ( V , E )G=(V,이자형)인접 연결 목록(다중 그래프는 반복되는 가장자리와 자체 순환 가장자리를 허용하는 그래프입니다), 잠시 시간을 주세요. 오(V+E) 오(V+E)영형(V+이자형)그래프의 "등가" 무방향 그래프를 계산하는 데 사용되는 알고리즘 G′=(V,E′)G^{'}=(V,E^{'})G=(V,이자형) 인접 연결 리스트로 표현됩니다.여기 이다.이자형그것은 될 것이다 전자이자형 자체 루프 모서리를 삭제한 후의 나머지 모서리와 중복된 모서리입니다. 나머지 가장자리를 제거한다는 것은 두 노드 사이의 여러 가장자리를 하나의 가장자리로 바꾸는 것을 의미합니다. 코드를 작성하려면 go 언어를 사용하세요.

원신의 말:

인접 연결 리스트 표현

인접 연결 리스트 표현에서는 각 정점이 V 연결리스트가 있고, 연결리스트의 각 노드는 슬레이브를 나타냅니다.V 시작 가장자리.계산하기 위해 감사합니다^TG, 우리는 횡단해야 GGG 의 각 모서리에 대해 모서리의 방향을 반전시켜 에 추가합니다. 감사합니다^TG 해당 연결리스트에

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)
    }
}
  • 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

시간 복잡도

  • 각 간선을 통과하는 시간 복잡도는 다음과 같습니다. 오(오)오(오)영형(이자형),안에 전자이자형 모서리의 수입니다.
  • 각 간선에 대해 상수 시간 작업(다른 그래프의 인접 목록에 추가)을 수행합니다.
  • 따라서 총 시간복잡도는 오(오)오(오)영형(이자형)

인접 행렬 표현

인접 행렬 표현에서는 2차원 배열을 사용하여 가장자리 정보를 저장합니다. matrix[u][v] 다음 줄이 있는지 여부를 나타냅니다. 유우 도착하다V 옆.계산하기 위해 감사합니다^TG, 행렬의 위쪽 삼각형(또는 행렬 표현 습관에 따라 아래쪽 삼각형)을 순회하고 가장자리의 방향을 바꿉니다. 즉, 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函数
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

시간 복잡도

  • 행렬의 각 요소를 반복하려면 다음이 필요합니다. V^2는 O(V2)이다.영형(V2) 그 중 시간 브이V 정점의 수입니다.
  • 따라서 총 시간복잡도는 V^2는 O(V2)이다.영형(V2) . 꼭짓점 수가 가장자리 수보다 훨씬 많은 경우 이는 가장 효율적이지 않을 수 있습니다.

여기에 이미지 설명을 삽입하세요.

여기에 이미지 설명을 삽입하세요.

여기에 이미지 설명을 삽입하세요.

여기에 이미지 설명을 삽입하세요.

아이플라이텍 스파크:

인접 목록으로 표현되는 유향 그래프의 경우 각 정점의 인접 목록을 순회하여 각 정점의 인접 정점을 새 그래프의 전치된 정점의 인접 목록에 추가할 수 있습니다. 구체적인 단계는 다음과 같습니다:

  1. 새 인접 목록 만들기 감사합니다G, 비어 있도록 초기화되었습니다.
  2. 원본 이미지 탐색 GGG 모든 정점V
  3. 정점 횡단 V 인접 연결 리스트, 각 인접 정점 유우 새 이미지에 추가 감사합니다G 중간 꼭지점V 인접 연결 리스트에 있습니다.
  4. 새 사진으로 돌아가기 감사합니다G

시간 복잡도 분석: 원본 그래프의 각 꼭지점을 순회하려면 다음이 필요합니다. V는 0과 1 사이의 정수입니다.영형(V) 각 정점의 인접 목록을 순회하는 데 필요한 시간은 다음과 같습니다. O ( ∣ E ∣ ) O(|E|)영형(이자형) 시간이므로 총 시간 복잡도는 O ( ∣ V ∣ + ∣ E ∣ ) O(|V| + |E|)영형(V+이자형)

인접 행렬로 표현되는 유방향 그래프의 경우 원본 그래프의 인접 행렬을 전치하여 새 그래프의 인접 행렬을 얻을 수 있습니다. 구체적인 단계는 다음과 같습니다:

  1. 크기가 있는 새 항목 만들기 ∣ V ∣ × ∣ V ∣ |V| 배 |V|V×V 행렬 감사합니다G, 모두 0인 행렬로 초기화되었습니다.
  2. 원본 이미지의 인접 행렬을 탐색합니다. GGG,할 것이다 G [ i ] [ j ] G[i][j]G[][제이] 값은 다음에 할당됩니다. GT [ j ] [ i ] G^{T}[j][i]G[제이][]
  3. 새 그래프의 인접 행렬을 반환합니다. 감사합니다G

시간 복잡도 분석: 원본 그래프의 인접 행렬을 탐색하려면 다음이 필요합니다. V는 0보다 크거나 같고, V는 0보다 작다.영형(V2) 시간이므로 총 시간 복잡도는 V는 0보다 크거나 같고, V는 0보다 작다.영형(V2)

다음은 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

360 지능형 두뇌:

인접 연결 리스트 표현

인접 연결 리스트 표현에서는 원본 이미지를 직접 탐색할 수 있습니다. GGG그런 다음 각 노드의 인접 목록은 각 모서리의 방향을 반전시킨 후 새 그래프에 추가됩니다. 감사합니다G해당 노드에서.

Go 언어 코드 구현:
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
시간 복잡도 분석:
  • 원본 그래프의 각 노드를 탐색합니다. V는 0과 1 사이의 정수입니다.영형(V)
  • 각 노드의 인접 목록을 탐색합니다. O ( ∣ E ∣ ) O(|E|)영형(이자형)

따라서 총 시간복잡도는 O ( ∣ V ∣ + ∣ E ∣ ) O(|V| + |E|)영형(V+이자형)

인접 행렬 표기법

인접 행렬 표기법에서는 새로운 인접 행렬을 생성한 다음 원본 이미지를 탐색할 수 있습니다. GGG인접 행렬, 행렬의 각 요소 (나, 제이) (나, 제이)(,제이)새로운 매트릭스에 할당됨 (제이, 나) (제이, 나)(제이,)위치를 지정하여 가장자리 반전을 완료합니다.

Go 언어 코드 구현:
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
시간 복잡도 분석:
  • 새 인접 행렬을 만듭니다. V는 0보다 크거나 같고, V는 0보다 작다.영형(V2)
  • 원본 이미지의 인접 행렬을 탐색합니다. V는 0보다 크거나 같고, V는 0보다 작다.영형(V2)

따라서 총 시간복잡도는 V는 0보다 크거나 같고, V는 0보다 작다.영형(V2)

요약하다

인접 연결 리스트 표현의 경우 전치 알고리즘의 시간 복잡도는 다음과 같습니다. O ( ∣ V ∣ + ∣ E ∣ ) O(|V| + |E|)영형(V+이자형), 인접 행렬 표현의 경우 전치 알고리즘의 시간 복잡도는 다음과 같습니다. V는 0보다 크거나 같고, V는 0보다 작다.영형(V2) .실제 응용 프로그램에서 그래프가 상대적으로 희박한 경우(예: ∣ E ∣ |E|이자형보다 훨씬 작다 ∣ V ∣ 2 |V|^2V2 ), 인접 연결 리스트 표현을 사용하는 것이 더 효율적입니다.그래프가 조밀한 경우(예: ∣ E ∣ |E|이자형가까운 ∣ V ∣ 2 |V|^2V2), 인접 행렬 표현이 더 적절할 수 있습니다.

지혜 스펙트럼 명확한 단어:

그래프 표현에서는 인접 연결 목록(Adjacency Linked List)과 인접 행렬(Adjacency Matrix)이 모두 일반적으로 사용되는 방법입니다. 인접 연결 리스트는 방향이 없는 그래프와 방향이 있는 그래프를 나타내는 데 사용되는 반면, 인접 행렬은 일반적으로 방향이 없는 그래프를 나타내는 데 사용됩니다. 유향 그래프의 전치를 위해 인접 연결 리스트와 인접 행렬을 별도로 조작할 수 있습니다.

인접 연결 리스트의 전치

인접 연결 리스트(Adjacency Linked List)로 표현되는 유방향 그래프의 경우, 원본 그래프의 각 꼭지점을 순회하고 원본 그래프의 나가는 가장자리를 들어오는 가장자리로 수정하여 그래프를 전치할 수 있습니다.

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

인접 행렬의 전치

인접 행렬로 표현되는 유향 그래프의 경우 원본 그래프의 각 행을 새 그래프의 해당 열로 변환하여 그래프를 전치할 수 있습니다.

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

알고리즘 실행 시간 분석

  1. 인접 연결 리스트의 전치의 경우 알고리즘의 시간 복잡도는 O(E)입니다. 여기서 E는 그래프의 간선 수입니다. 이는 각 모서리를 한 번씩 통과해야 하기 때문입니다.

  2. 인접 행렬의 전치의 경우 알고리즘의 시간 복잡도는 O(V^2)입니다. 여기서 V는 그래프의 정점 수입니다. 이는 각 행렬 요소를 한 번씩 순회해야 하며 행렬의 크기가 V×V이기 때문입니다.
    이러한 알고리즘은 모두 효율적이고 실행됩니다.

천궁:

방향성 그래프를 계산하는 알고리즘을 구현하려면 GGG 전치 감사합니다G , 인접 연결 리스트와 인접 행렬의 두 가지 표현을 각각 처리할 수 있습니다. 아래에서는 이 두 가지 경우에 대한 알고리즘을 각각 설명하고 Go 언어로 된 코드 예제를 제공합니다.

인접 연결 리스트 표현

알고리즘 단계:
  1. 새 인접 목록 만들기 newAdjList 전치된 그래프를 저장하는데 사용됩니다.
  2. 원본 이미지의 인접 연결 리스트를 탐색합니다. adjList
  3. 각 모서리마다 (u, v), 다음에 추가하세요 newAdjList[v] 가운데.
  4. 새로운 인접 목록을 반환합니다. newAdjList
Go 언어 코드 예:
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
런타임 분석:

이 알고리즘의 실행 시간은 O(|V| + |E|)입니다. 여기서 |V|는 정점 수이고 |E|는 가장자리 수입니다. 모든 정점과 가장자리를 한 번만 통과해야 하기 때문입니다.

인접 행렬 표기법

알고리즘 단계:
  1. 새로운 인접 행렬 생성 newAdjMatrix 전치된 그래프를 저장하는데 사용됩니다.
  2. 원본 이미지의 인접 행렬을 탐색합니다. adjMatrix
  3. 각 요소마다 adjMatrix[i][j], 할당 newAdjMatrix[j][i]
  4. 새로운 인접 행렬을 반환합니다. newAdjMatrix
Go 언어 코드 예:
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
런타임 분석:

이 알고리즘의 실행 시간은 O(|V|^2)입니다. 여기서 |V|는 정점 수입니다. 전체 인접 행렬을 순회해야 하는데 인접 행렬의 크기가 ​|V x |V|이기 때문입니다.

위 코드 예제는 알고리즘의 핵심 부분일 뿐이며, 실제 응용에서는 오류 처리, 입력 및 출력과 같은 다른 기능을 추가해야 할 수도 있습니다. 또한, 코드를 단순화하기 위해 그래프에 반복되는 간선이 없다고 가정하고 정점 번호는 0부터 연속적으로 번호가 매겨져 있습니다.

채팅gpt:

다음은 그래프 G로부터 G^T를 계산하기 위해 Go 언어로 작성된 알고리즘이며, 해당 인접 연결 리스트와 인접 행렬 표현 방법도 제공됩니다.

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

이 알고리즘의 시간 복잡도는 O(V + E)입니다. 여기서 V는 정점 수이고 E는 가장자리 수입니다. 전치 그래프를 구성하는 과정에서는 원본 그래프의 모든 변을 순회하고 이를 역으로 전치 그래프에 추가해야 하므로 총 시간 복잡도는 꼭지점과 간선의 수에 비례합니다.

키미:

유향 그래프의 전치 그래프는 인접 연결 목록과 인접 행렬이라는 두 가지 주요 데이터 구조로 표현될 수 있습니다. 아래에서는 이 두 가지 경우의 알고리즘을 각각 소개하고 Go 언어로 작성된 샘플 코드를 제공하겠습니다.

인접 연결 리스트 표현

인접 연결 리스트(Adjacency Linked List)로 표현되는 그래프의 경우, 각 꼭지점의 인접 리스트를 순회한 다음 각 인접 점에 역방향 간선을 추가하여 그래프를 전치할 수 있습니다. 이 방법의 시간 복잡도는 O(V + E)입니다. 여기서 V는 정점 수이고 E는 가장자리 수입니다.

Go 언어 샘플 코드:
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

인접 행렬 표현

인접 행렬로 표현되는 그래프의 경우 행렬의 행과 열을 교환하여 전치를 구현할 수 있습니다. 이 방법의 시간 복잡도는 O(V^2)입니다.

Go 언어 샘플 코드:
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

알고리즘 분석

  • 인접 목록 : 알고리즘은 각 정점의 인접 목록을 순회해야 하며, 각 가장자리에 대해 인접 지점의 인접 목록에 역방향 가장자리를 추가해야 합니다. 이웃 목록의 평균 길이가 k라면 알고리즘의 시간 복잡도는 O(V + E * k)입니다. 최악의 경우 k는 V에 가까울 수 있고, 시간복잡도는 O(V^2)에 가까울 수 있습니다. 최선의 경우 k는 1에 가깝고 시간 복잡도는 O(E)에 가깝습니다.
  • 인접 행렬 : 알고리즘은 행렬의 각 요소를 살펴보고 행과 열을 교환해야 합니다. 행렬이 VxV이므로 시간 복잡도는 O(V^2)입니다.

실제 응용 프로그램에서 어떤 알고리즘을 선택할지는 그래프의 희소성과 사용 가능한 메모리에 따라 달라집니다. 희소 그래프의 경우 인접 연결 목록이 메모리 효율성이 더 높을 수 있고, 조밀한 그래프의 경우 인접 행렬이 더 효율적일 수 있습니다.

훈위안:

유향 그래프를 계산하려면 G = ( V , E ) G = ( V , E )G=(V,이자형) 전치 GT = ( V , E ) G^T = ( V , E ^ T )G=(V,이자형), 인접 연결 리스트와 인접 행렬의 두 가지 표현 방법에 대해 각각 해당 알고리즘을 제공하고 실행 시간을 분석할 수 있습니다.

인접 연결 리스트 표현

알고리즘 설명
  1. 전치된 그래프의 가장자리를 저장하기 위해 빈 인접 목록을 초기화합니다.
  2. 원본 이미지 탐색 GGG 모든 노드의.
  3. 각 노드마다 유우, 인접 목록에 있는 모든 이웃 노드를 탐색합니다. V
  4. 다음에서 새 인접 목록을 추가합니다. V 도착하다 유우 옆.
  5. 순회가 완료된 후 새로운 인접 연결 목록은 전치된 그래프입니다. 감사합니다^TG
런타임 분석
  • 시간 복잡도: O ( ∣ E ∣ ) O(|E|)영형(이자형),안에 ∣ E ∣ |E|이자형 원본 이미지의 면 수입니다. 각 가장자리를 두 번(읽기 위해 한 번, 쓰기 위해 한 번) 순회해야 하기 때문입니다.

인접 행렬 표기법

알고리즘 설명
  1. 전치된 그래프의 가장자리를 저장하기 위해 원본 그래프와 동일한 크기의 인접 행렬을 초기화합니다.
  2. 원본 이미지 탐색 GGG 인접 행렬.
  3. 행렬의 0이 아닌 모든 요소에 대해(즉, 가장자리가 있습니다) ( 유, 브 ) ( 유, 브)(,V)), 전치된 그래프의 인접 행렬의 해당 위치 ( v , u ) ( v , u )(V,) 0이 아닌 요소로 설정합니다.
  4. 순회가 완료된 후 새로운 인접 행렬은 전치된 그래프입니다 감사합니다^TG
런타임 분석
  • 시간 복잡도: V는 0보다 크거나 같고, V는 0보다 작다.영형(V2),안에 ∣ V ∣ |V|V 원래 그래프의 노드 수입니다. 전체 인접 행렬을 순회해야 하기 때문입니다.

Go 언어 구현(인접 연결 목록 표현)

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

이 코드에서는 Edge 가장자리를 나타내는 구조 및AdjacencyList 인접 연결 리스트를 나타내는 구조입니다.TransposeGraph 이 함수는AdjacencyList 유형 매개변수를 입력하고 전치된 그래프의 인접 연결 목록 표현을 반환합니다.존재하다main 함수를 사용하여 예제 그래프를 만들고 전치된 그래프를 계산하고 인쇄합니다.