내 연락처 정보
우편메소피아@프로톤메일.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
인접 연결 리스트 표현에서는 각 정점이 부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)
}
}
시간 복잡도:
인접 행렬 표현에서는 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函数
시간 복잡도:
인접 목록으로 표현되는 유향 그래프의 경우 각 정점의 인접 목록을 순회하여 각 정점의 인접 정점을 새 그래프의 전치된 정점의 인접 목록에 추가할 수 있습니다. 구체적인 단계는 다음과 같습니다:
시간 복잡도 분석: 원본 그래프의 각 꼭지점을 순회하려면 다음이 필요합니다. V는 0과 1 사이의 정수입니다.영형(∣V∣) 각 정점의 인접 목록을 순회하는 데 필요한 시간은 다음과 같습니다. O ( ∣ E ∣ ) O(|E|)영형(∣이자형∣) 시간이므로 총 시간 복잡도는 O ( ∣ V ∣ + ∣ E ∣ ) O(|V| + |E|)영형(∣V∣+∣이자형∣)。
인접 행렬로 표현되는 유방향 그래프의 경우 원본 그래프의 인접 행렬을 전치하여 새 그래프의 인접 행렬을 얻을 수 있습니다. 구체적인 단계는 다음과 같습니다:
시간 복잡도 분석: 원본 그래프의 인접 행렬을 탐색하려면 다음이 필요합니다. V는 0보다 크거나 같고, V는 0보다 작다.영형(∣V∣2) 시간이므로 총 시간 복잡도는 V는 0보다 크거나 같고, V는 0보다 작다.영형(∣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
}
인접 연결 리스트 표현에서는 원본 이미지를 직접 탐색할 수 있습니다. GGG그런 다음 각 노드의 인접 목록은 각 모서리의 방향을 반전시킨 후 새 그래프에 추가됩니다. 감사합니다G티해당 노드에서.
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∣+∣이자형∣)。
인접 행렬 표기법에서는 새로운 인접 행렬을 생성한 다음 원본 이미지를 탐색할 수 있습니다. GGG인접 행렬, 행렬의 각 요소 (나, 제이) (나, 제이)(나,제이)새로운 매트릭스에 할당됨 (제이, 나) (제이, 나)(제이,나)위치를 지정하여 가장자리 반전을 완료합니다.
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
}
따라서 총 시간복잡도는 V는 0보다 크거나 같고, V는 0보다 작다.영형(∣V∣2)。
인접 연결 리스트 표현의 경우 전치 알고리즘의 시간 복잡도는 다음과 같습니다. O ( ∣ V ∣ + ∣ E ∣ ) O(|V| + |E|)영형(∣V∣+∣이자형∣), 인접 행렬 표현의 경우 전치 알고리즘의 시간 복잡도는 다음과 같습니다. V는 0보다 크거나 같고, V는 0보다 작다.영형(∣V∣2) .실제 응용 프로그램에서 그래프가 상대적으로 희박한 경우(예: ∣ E ∣ |E|∣이자형∣보다 훨씬 작다 ∣ V ∣ 2 |V|^2∣V∣2 ), 인접 연결 리스트 표현을 사용하는 것이 더 효율적입니다.그래프가 조밀한 경우(예: ∣ E ∣ |E|∣이자형∣가까운 ∣ V ∣ 2 |V|^2∣V∣2), 인접 행렬 표현이 더 적절할 수 있습니다.
그래프 표현에서는 인접 연결 목록(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)
}
}
}
인접 행렬로 표현되는 유향 그래프의 경우 원본 그래프의 각 행을 새 그래프의 해당 열로 변환하여 그래프를 전치할 수 있습니다.
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이기 때문입니다.
이러한 알고리즘은 모두 효율적이고 실행됩니다.
방향성 그래프를 계산하는 알고리즘을 구현하려면 GGG 전치 감사합니다G티 , 인접 연결 리스트와 인접 행렬의 두 가지 표현을 각각 처리할 수 있습니다. 아래에서는 이 두 가지 경우에 대한 알고리즘을 각각 설명하고 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부터 연속적으로 번호가 매겨져 있습니다.
다음은 그래프 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)
}
이 알고리즘의 시간 복잡도는 O(V + E)입니다. 여기서 V는 정점 수이고 E는 가장자리 수입니다. 전치 그래프를 구성하는 과정에서는 원본 그래프의 모든 변을 순회하고 이를 역으로 전치 그래프에 추가해야 하므로 총 시간 복잡도는 꼭지점과 간선의 수에 비례합니다.
유향 그래프의 전치 그래프는 인접 연결 목록과 인접 행렬이라는 두 가지 주요 데이터 구조로 표현될 수 있습니다. 아래에서는 이 두 가지 경우의 알고리즘을 각각 소개하고 Go 언어로 작성된 샘플 코드를 제공하겠습니다.
인접 연결 리스트(Adjacency Linked List)로 표현되는 그래프의 경우, 각 꼭지점의 인접 리스트를 순회한 다음 각 인접 점에 역방향 간선을 추가하여 그래프를 전치할 수 있습니다. 이 방법의 시간 복잡도는 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 )G=(V,이자형) 전치 GT = ( V , E ) G^T = ( V , E ^ T )G티=(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
함수를 사용하여 예제 그래프를 만들고 전치된 그래프를 계산하고 인쇄합니다.