моя контактная информация
Почтамезофия@protonmail.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
В представлении связанного списка смежности каждая вершина ввв Существует связанный список, и каждый узел в связанном списке представляет собой подчиненное устройство. ввв Стартовый край.чтобы вычислить ГТГ^ТгТ, нам нужно пересечь ГАРАНТИРОВАННАЯ ПОБЕДАг для каждого ребра и, изменив направление ребра, прибавьте к ГТГ^ТгТ в соответствующем связанном списке.
Реализация языка 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]
Указывает, есть ли линия от ууты приезжать ввв сторона.чтобы вычислить ГТГ^ТгТ, мы пересекаем верхний треугольник (или нижний треугольник, в зависимости от ваших привычек к представлению матрицы) матрицы и меняем направление ребер, то есть: 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 ∣ ) О(|V|)О(∣В∣) Время, необходимое для обхода списка смежности каждой вершины, равно О ( ∣ Е ∣ ) О(|Е|)О(∣Э∣) время, поэтому общая временная сложность равна О ( ∣ V ∣ + ∣ E ∣ ) О(|V| + |E|)О(∣В∣+∣Э∣)。
Для ориентированного графа, представленного матрицей смежности, мы можем получить матрицу смежности нового графа, транспонировав матрицу смежности исходного графа. Конкретные шаги заключаются в следующем:
Анализ временной сложности: для обхода матрицы смежности исходного графа требуется О ( ∣ V ∣ 2 ) О(|V|^2)О(∣В∣2) время, поэтому общая временная сложность равна О ( ∣ V ∣ 2 ) О(|V|^2)О(∣В∣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
}
В представлении связанного списка смежности мы можем напрямую перемещаться по исходному изображению. ГАРАНТИРОВАННАЯ ПОБЕДАгСписок смежности каждого узла затем добавляется в новый граф после изменения направления каждого ребра на противоположное. ГТГ^{Т}гТна соответствующем узле.
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
}
Следовательно, общая временная сложность равна О ( ∣ V ∣ + ∣ E ∣ ) О(|V| + |E|)О(∣В∣+∣Э∣)。
В обозначении матрицы смежности мы можем создать новую матрицу смежности, а затем пройти по исходному изображению. ГАРАНТИРОВАННАЯ ПОБЕДАгматрица смежности, каждый элемент матрицы ( я , дж ) ( я , дж )(я,дж)присвоено новой матрице ( дж , я ) (дж, я)(дж,я)положение, тем самым завершая инверсию края.
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 ∣ 2 ) О(|V|^2)О(∣В∣2)。
Для представления связанного списка смежности временная сложность алгоритма транспонирования равна О ( ∣ V ∣ + ∣ E ∣ ) О(|V| + |E|)О(∣В∣+∣Э∣), а для представления матрицы смежности временная сложность алгоритма транспонирования равна О ( ∣ V ∣ 2 ) О(|V|^2)О(∣В∣2) .В практических приложениях, если граф относительно разрежен (т. ∣ Е ∣ |Е|∣Э∣намного меньше, чем ∣ В ∣ 2 |В|^2∣В∣2 ), было бы более эффективно использовать представление связанного списка смежности.Если граф плотный (т. ∣ Е ∣ |Е|∣Э∣около ∣ В ∣ 2 |В|^2∣В∣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.
Все эти алгоритмы эффективны и работают.
Чтобы реализовать алгоритм вычисления ориентированного графа ГАРАНТИРОВАННАЯ ПОБЕДАг транспозиция ГТГ^{Т}гТ , мы можем обработать два представления связанного списка смежности и матрицы смежности соответственно. Ниже я опишу алгоритмы для этих двух случаев соответственно и приведу примеры кода на языке 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
}
В практических приложениях выбор алгоритма зависит от разреженности графа и доступной памяти. Для разреженных графов связанные списки смежности могут быть более эффективными с точки зрения использования памяти; для плотных графов более эффективными могут быть матрицы смежности;
Чтобы вычислить ориентированный граф Г = ( В , Э ) Г=(В,Э)г=(В,Э) транспозиция GT = ( V , ET ) G^T=(V,E^T)гТ=(В,ЭТ), мы можем предоставить соответствующие алгоритмы для двух методов представления связного списка смежности и матрицы смежности соответственно и проанализировать время их работы.
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
type и возвращает представление связанного списка смежности транспонированного графа.существоватьmain
функции мы создаем пример графика, вычисляем и печатаем его транспонированный график.