`
sunwinner
  • 浏览: 203085 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

基础数据结构和算法十三:Undirected Graphs

阅读更多

A graph is a set of vertices and a collection of edges that each connect a pair of vertices. Vertex names are not important to the definition, but we need a way to refer to vertices. By convention, we use the names 0 through V-1 for the vertices in a V-vertex graph. 

 

Glossary

A substantial amount of nomenclature is associated with graphs. Most of the terms have straightforward definitions, and, for reference, we consider them in one place: here.

When there is an edge connecting two vertices, we say that the vertices are adjacent to one another and that the edge is incident to both vertices. The degree of a vertex is the number of edges incident to it. A subgraph is a subset of a graph’s edges (and associated vertices) that constitutes a graph. Many computational tasks involve identifying subgraphs of various types. Of particular interest are edges that take us through a sequence of vertices in a graph.

 

A path in a graph is a sequence of vertices connected by edges. A simple path is one with no repeated vertices. A cycle is a path with at least one edge whose first and last vertices are the same. A simple cycle is a cycle with no repeated edges or vertices (except the requisite repetition of the first and last vertices). The length of a path or a cycle is its number of edges.

 

A graph is connected if there is a path from every vertex to everyother vertex in the graph. A graph that is not connected consists of a set of connected components, which are maximal connected subgraphs.

 

An acyclic graph is a graph with no cycles. Several of the algorithms that we consider are concerned with finding acyclic subgraphs of a given graph that satisfy certain properties. We need additional terminology to refer to these structures: A tree is an acyclic connected graph. A disjoint set of trees is called a forest. A spanning tree of a connected graph is a subgraph that contains all of that graph’s vertices and is a single tree. A spanning forest of a graph is the union of spanning trees of its connected components.

 

This definition of tree is quite general: with suitable refine- ments it embraces the trees that we typically use to model pro- gram behavior (function-call hierarchies) and data structures (BSTs, 2-3 trees, and so forth). A graph G with V vertices is a tree if and only if it satisfies any of the following five conditions:

■ G has V - 1 edges and no cycles.

■ G has V - 1 edges and is connected.

■ G is connected, but removing any edge disconnects it.

■ G is acyclic, but adding any edge creates a cycle.

■ Exactly one simple path connects each pair of vertices in G.

 

Several of the algorithms that we consider find spanning trees and forests, and these properties play an important role in their analysis and implementation.

 

The density of a graph is the proportion of possible pairs of vertices that are connected by edges. A sparse graph has relatively few of the possible edges present; a dense graph has relatively few of the possible edges missing. Generally, we think of a graph as being sparse if its number of different edges is within a small constant factor of V and as being dense otherwise.

 

A bipartite graph is a graph whose vertices we can divide into two sets such that all edges connect a vertex in one set with a vertex in the other set. The figure below gives an example of a bipartite graph, where one set of vertices is colored red and the other set of vertices is colored black. Bipartite graphs arise in a natural way in many situations.

 

 

Undirected graph data type

 

Representation alternatives.

■ An adjacency matrix, where we maintain a V-by-V boolean array, with the entry in row v and column w defined

to be true if there is an edge adjacent 0 to both vertex v and vertex w in the graph, and to be false otherwise. This representation fails on the first count -- graphs with millions of vertices are common and the space cost for the V 2 boolean values needed is prohibitive.

■ An array of edges, using an Edge class with two instance variables of type int. This direct representation is simple, but it fails on the second count -- implementing adj() would involve examining all the edges in the graph.

■ An array of adjacency lists, where we maintain a vertex-indexed array of lists of the vertices adjacent to each vertex. This data structure satisfies both requirements for typical applications and is the one that we will use throughout this chapter.

 

Beyond these performance objectives, a detailed examination reveals other considerations that can be important in some applications. For example, allowing parallel edges precludes the use of an adjacency matrix, since the adjacency matrix has no way to represent them.

 

public class Graph {
    private final int V;
    private int E;
    private Bag<Integer>[] adj;

    /**
     * Create an empty graph with V vertices.
     *
     * @throws java.lang.IllegalArgumentException if V < 0
     */
    public Graph(int V) {
        if (V < 0) throw new IllegalArgumentException("Number of vertices must be nonnegative");
        this.V = V;
        this.E = 0;
        adj = (Bag<Integer>[]) new Bag[V];
        for (int v = 0; v < V; v++) {
            adj[v] = new Bag<Integer>();
        }
    }

    /**
     * Create a random graph with V vertices and E edges.
     * Expected running time is proportional to V + E.
     *
     * @throws java.lang.IllegalArgumentException if either V < 0 or E < 0
     */
    public Graph(int V, int E) {
        this(V);
        if (E < 0) throw new IllegalArgumentException("Number of edges must be nonnegative");
        for (int i = 0; i < E; i++) {
            int v = (int) (Math.random() * V);
            int w = (int) (Math.random() * V);
            addEdge(v, w);
        }
    }

    /**
     * Create a digraph from input stream.
     */
    public Graph(In in) {
        this(in.readInt());
        int E = in.readInt();
        for (int i = 0; i < E; i++) {
            int v = in.readInt();
            int w = in.readInt();
            addEdge(v, w);
        }
    }

    /**
     * Copy constructor.
     */
    public Graph(Graph G) {
        this(G.V());
        this.E = G.E();
        for (int v = 0; v < G.V(); v++) {
            // reverse so that adjacency list is in same order as original
            Stack<Integer> reverse = new Stack<Integer>();
            for (int w : G.adj[v]) {
                reverse.push(w);
            }
            for (int w : reverse) {
                adj[v].add(w);
            }
        }
    }

    /**
     * Return the number of vertices in the graph.
     */
    public int V() {
        return V;
    }

    /**
     * Return the number of edges in the graph.
     */
    public int E() {
        return E;
    }


    /**
     * Add the undirected edge v-w to graph.
     *
     * @throws java.lang.IndexOutOfBoundsException unless both 0 <= v < V and 0 <= w < V
     */
    public void addEdge(int v, int w) {
        if (v < 0 || v >= V) throw new IndexOutOfBoundsException();
        if (w < 0 || w >= V) throw new IndexOutOfBoundsException();
        E++;
        adj[v].add(w);
        adj[w].add(v);
    }


    /**
     * Return the list of neighbors of vertex v as in Iterable.
     *
     * @throws java.lang.IndexOutOfBoundsException unless 0 <= v < V
     */
    public Iterable<Integer> adj(int v) {
        if (v < 0 || v >= V) throw new IndexOutOfBoundsException();
        return adj[v];
    }


    /**
     * Return a string representation of the graph.
     */
    public String toString() {
        StringBuilder s = new StringBuilder();
        String NEWLINE = System.getProperty("line.separator");
        s.append(V + " vertices, " + E + " edges " + NEWLINE);
        for (int v = 0; v < V; v++) {
            s.append(v + ": ");
            for (int w : adj[v]) {
                s.append(w + " ");
            }
            s.append(NEWLINE);
        }
        return s.toString();
    }
}

 

Adjacency-lists data structure.

The standard graph representation for graphs that are not dense is called the adjacency-lists data structure, where we keep track of all the vertices adjacent to each vertex on a linked list that is associated with that vertex. This Graph implementation achieves the following performance characteristics:

■ Space usage proportional to V + E

■ Constant time to add an edge

■ Time proportional to the degree of v to iterate through vertices adjacent to v (constant time per adjacent vertex processed)



 

  • 大小: 28.2 KB
  • 大小: 47 KB
分享到:
评论

相关推荐

    Undirected Graphs

    无向图(Undirected Graphs)是一种基本的数据结构,在计算机科学和离散数学中占有重要地位。图由一组顶点(vertices)和连接这些顶点的边(edges)组成。在无向图中,边没有方向性,即如果一条边连接了顶点A和顶点B...

    AN ALGORITHMFORDRAWINGGENERAL UNDIRECTED GRAPHS

    无向图是由顶点(节点)和连接这些顶点的无向边组成的图形数据结构。与有向图不同,无向图中的边不指明方向。在计算机科学和数学中,无向图被广泛用于表示各种结构,例如社交网络、分子结构或任何其他需要通过图形来...

    图论算法及应用_matlab算法实例源码.rar

    6. **图的矩阵表示**:邻接矩阵和邻接表是图的两种常见数据结构,MATLAB中可以方便地处理这两种结构,进行图的构建和操作。 7. **图的剪枝和生成**:如生成树的剪枝操作,以及Euler图和Hamilton图的生成。 8. **...

    ACM_算法模板集.pdf

    根据给定文件的信息,我们可以将主要内容分为以下几个部分:数学与公式、大数处理与字符读入、数论...这些知识点涵盖了从数学公式到复杂数据结构和算法的广泛领域,对于深入理解计算机科学中的算法设计和分析至关重要。

    《算法导论》完整的课件下载

    ### 《算法导论》完整课件下载:深入解析图算法与贪心算法 #### 图的概念及表示方法 在《算法导论》这门课程中,图...对于学习计算机科学与算法的学生来说,这些内容至关重要,有助于理解更复杂的算法和数据结构。

    directed_undirected_graphs:有向图和无向图的实现

    在计算机科学中,图是一种非常重要的数据结构,用于表示对象之间的关系。本主题将深入探讨两种基本类型的图:有向图(Directed Graph)和无向图(Undirected Graph),并结合Python语言介绍它们的实现方法。 有向图...

    MIT高级算法4

    在计算机科学领域,图是一种非常重要的数据结构,被广泛应用于各种实际问题的建模与解决。 #### 二、图的基本定义 ##### 1.1 简单图 简单图(simple graph)是由两个集合组成的有序对\( (V, E) \),其中: - \( V \...

    吉大acm模板

    #### 三、数据结构(Data Structures) ##### 3.1 求某天是星期几(Weekday Calculation) - **定义**: 根据给定日期计算对应的星期几。 - **应用场景**: 日历程序、时间管理等。 - **算法步骤**: - 使用Zeller公式或...

    python networkX包最新参考文档

    NetworkX库提供了多种基础的图(Graphs)类型,包括无向图(Undirected graphs)、有向图(Directed graphs)、多重图(Multigraphs)以及多重有向图(Multidirected graphs)等。用户可以根据需要选择最适合的图...

    networkx_pdf

    它提供了数据结构来表示各种类型的图(graph)以及用于图分析的标准算法。NetworkX 的设计目的是为了促进可读性、清晰度以及模块化。 #### 二、NetworkX用户群体 1. **科研人员**:在社会学、生物学、物理学等领域的...

    graphs

    在IT领域,图(Graphs)是一种非常重要的数据结构,广泛应用于各种算法设计和问题解决。标题中的"graphs"指的是这个主题,而描述虽然简洁,但暗示我们将探讨与图相关的概念和技术。标签“C”表明我们将从C语言的角度...

    Graphs-and-Trees

    在IT领域,图和树是数据结构与算法中极为重要的概念,它们广泛应用于网络设计、数据库索引、操作系统、人工智能等多个方面。在这个“Graphs-and-Trees”项目中,我们很可能会探讨C++语言实现图和树的相关知识。C++是...

    petgraph:Rust的图形数据结构库

    宠物图(PetGraph)是Rust编程语言中的一个开源库,专门用于处理和操作图形数据结构。这个库为开发者提供了创建、操作...在实际项目中,这个库不仅简化了图形数据结构的实现,还为高效、可靠的图算法提供了坚实的基础。

    grapho:图论算法的 Go 实现

    grapho 是图论数据结构和算法的 Go 实现。 完整的文档可以在找到 图表 有向图和无向图都是使用Graph结构创建的: graph := grapho.NewGraph(false) // true for directed Graphs, false for undirected Nodes ...

    Weighted-Undirected-Graphs-and-Minimum-Spanning-Trees:加州大学伯克利分校 CS-61B 项目 3

    加权无向图和最小生成树是图论中的核心概念,它们在计算机科学,特别是算法设计和数据结构中占有重要地位。在这个加州大学伯克利分校的CS-61B项目中,学生将深入理解并实践这两个概念。下面将详细阐述它们的原理以及...

    图与离散图

    在计算机科学中,离散数学是分析和表达算法复杂性、数据结构、计算机程序设计语言和计算理论的基础。 4. 组合数学 组合数学主要研究离散对象的组合性质,例如,组合计数(如排列和组合)、生成函数、递归关系、图的...

    Python图论算法实现工具——NetworkX(3)有向图、多图等图生成器及图的可视化1

    总结,NetworkX是Python中强大的图论算法实现工具,提供了丰富的数据结构和算法,能够方便地处理有向图、多图以及进行各种图操作和可视化。通过深入理解和熟练使用这些功能,我们可以解决各种复杂的问题,如社交网络...

    Graph-theoretic algorithms

    - **PQ树(PQ-Trees)**:一种数据结构,用于存储和操作间隔图中的区间信息。 - **使用PQ树识别间隔图(Recognizing Interval Graphs with PQ-Trees)**:详细解释了如何利用PQ树来判断一个图是否为间隔图。 **其他...

    Graph Theory III(Springer Verlag).rar

    1. **树(Tree)**:无环连通图称为树,是图论中的基础结构,有着广泛应用,如网络设计、数据结构等。书中可能会讨论生成树、最小生成树(如Prim算法和Kruskal算法)、树的遍历等。 2. **哈密顿回路(Hamiltonian ...

    GraphLibrary

    GraphLibrary 是一个基于 C# 编程语言的图形库,专为处理图数据结构和算法而设计。在软件工程、计算机科学以及许多其他领域,图是表示对象间关系的常见工具,例如网络、社交关系、计算机硬件架构等。GraphLibrary ...

Global site tag (gtag.js) - Google Analytics