图论基本知识

图的基本概念

图示一个复杂的结构,节点之间的关系可以是任意的,图中的任意两个元素之间都可能相关。

图分为有向图和无向图,无向图为两个节点之间互相可以到达,有向图只能根据箭头所指的方向到达另一个节点。上图中(a)为有向图,(b)为无向图

有时边或者弧具有与它相关的数,这种数字叫做权,这种带权的图常常称为网。

回路:第一个顶点和最后一个顶点相同的路径称之为回路或者环,路径中顶点不重复出现为简单路径,回路中无重复顶点为简单回路。

连通:如果两个顶点之间有路径,则称这两个顶点是连通的,如果图中的任意一点都可以到其他的所有顶点,则称这个图为连通图。

连通分量:无向图中的极大连通子图(N个顶点构成一个连通图),连通图必然有连通分量,有连通分量不一定为连通图,两者无必然联系。

有向图的连通图成为强连通图和强连通子图,概念和无向图的相同

图的存储结构

邻接矩阵

用矩阵来存储图的结构

0表示两个顶点之间无联系,1表示有联系(无向图中由于没有方向所以V3可以到达V2 V2也可以到达V3)

构建邻接矩阵

import java.util.Scanner;
public class UDN {
    String vex[] = new String[100];  // 邻接矩阵
    int a[][];   // 顶点存储数组

    // 创建邻接矩阵
    public void createChart() {
        int i = 0;
        int t = 0;
        Scanner in = new Scanner(System.in);
        System.out.println("请输入顶点");
        String str = in.nextLine();
        while (str.length() != 0) {
            vex[t] = str;
            t++;
            str = in.nextLine();
        }
        System.out.println(t);
        a = new int[t][t]; // 邻接矩阵
        for (i = 0; i < t; i++) {
            System.out.println("请输入一条边的依附顶点");
            String d1 = in.nextLine();
            String d2 = in.nextLine();
            int d1Index = findLine(d1);
            int d2Index = findLine(d2);
            a[d2Index][d1Index] = 1;
            a[d1Index][d2Index] = 1;
        }
    }

    // 输出
    public void print() {

        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < a.length; j++) {
                System.out.print(a[i][j] + " ");
            }
            System.out.println();
        }
    }

    // 查找输入顶点对应的下标
    public int findLine(String d1) {
        int i = 0;

        for (int t = 0; t < vex.length; t++) {
            if (vex[t].equals(d1)) {
                i = t;
                break;
            }
        }
        return i;
    }

    public static void main(String[] args) {
        UDN i = new UDN();
        i.createChart();
        i.print();
    }

}

邻接表存储

邻接表是一种链式的存储结构,存储结构示意图(a):

数组中存储的为节点,每个节点后面为此节点邻接节点的下标

头节点
public class VNode {
    private String data; // 该弧的顶点信息
    private ArcNode firstArc; // 第一条弧

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public ArcNode getFirstArc() {
        return firstArc;
    }

    public void setFirstArc(ArcNode firstArc) {
        this.firstArc = firstArc;
    }

}

表节点

public class VNode {
    private String data; // 该弧的顶点信息
    private ArcNode firstArc; // 第一条弧

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public ArcNode getFirstArc() {
        return firstArc;
    }

    public void setFirstArc(ArcNode firstArc) {
        this.firstArc = firstArc;
    }

}

图的信息

public class AlGraph {
    private VNode nodeList[];
    private int vexnum, arcnum; // 图的定点数和弧数
    private int kind; // 弧的种类

    public VNode[] getNodeList() {
        return nodeList;
    }

    public void setNodeList(VNode[] nodeList) {
        this.nodeList = nodeList;
    }

    public int getVexnum() {
        return vexnum;
    }

    public void setVexnum(int vexnum) {
        this.vexnum = vexnum;
    }

    public int getArcnum() {
        return arcnum;
    }

    public void setArcnum(int arcnum) {
        this.arcnum = arcnum;
    }

    public int getKind() {
        return kind;
    }

    public void setKind(int kind) {
        this.kind = kind;
    }

}

构建

public class AdjancecyListDemo {
    AlGraph alGraph = new AlGraph();

    public void createAdjancency() {
        Scanner in = new Scanner(System.in);
        System.out.println("请输入顶点数");

        int n = in.nextInt(); // 表内容初始化
        alGraph.setNodeList(new VNode[n]);
        alGraph.setVexnum(n);
        System.out.println("请输入弧数");
        alGraph.setArcnum(in.nextInt());

        VNode[] list = alGraph.getNodeList(); // 头结点初始化
        System.out.println(list.length);
        System.out.println("input Node:");
        for (int i = 0; i < list.length; i++) {
            VNode node = new VNode();
            node.setData(in.next());
            list[i] = node;
        }

        for (int i = 0; i < alGraph.getArcnum(); i++) {
            System.out.println("请输入弧依附的两个顶点"); // 构建邻接表
            String begin = in.next();
            String end = in.next();
            int ii = findIndex(begin);
            int jj = findIndex(end);
            if (ii == -1 || jj == -1) {
                System.out.println("输入的节点不存在");
                return;
            }
            ArcNode arcNode = new ArcNode();
            addArcNode(ii, jj, end);
            addArcNode(jj, ii, begin);
        }
    }

    public void prinfAlGralph() {  // 输出

        VNode[] list = alGraph.getNodeList();
        for (int i = 0; i < list.length; i++) {
            System.out.print(i + "-" + list[i].getData() + " : ");
            ArcNode arc = list[i].getFirstArc();
            while (arc != null) {
                System.out.print(arc.getAdjVex() + " | ");
                arc = arc.getNextArc();
            }
            System.out.println();
        }
    }

    public void addArcNode(int index, int end, String info) { // 添加表结点
        VNode[] list = alGraph.getNodeList();
        ArcNode tempArc = list[index].getFirstArc();
        ArcNode arcNode = new ArcNode();
        if (tempArc == null) {
            arcNode.setAdjVex(end);
            arcNode.setInfo(info);
            list[index].setFirstArc(arcNode);
        } else {
            while (tempArc.getNextArc() != null) {
                tempArc = tempArc.getNextArc();
            }
            arcNode.setAdjVex(end);
            arcNode.setInfo(info);
            tempArc.setNextArc(arcNode);
        }
    }

    public int findIndex(String node) {     // 查找给定节点的下标
        VNode[] list = alGraph.getNodeList();
        for (int i = 0; i < list.length; i++) {
            if (list[i].getData().equals(node)) {
                return i;
            }
        }

        return -1;
    }

    public static void main(String[] args) {
        AdjancecyListDemo demo = new AdjancecyListDemo();
        demo.createAdjancency();
        demo.prinfAlGralph();
    }
}

posted @ 2017-11-01 20:59  cccc_hi  阅读(555)  评论(0编辑  收藏  举报