JAVA关于图数据结构的通用类实现

图是一种较为复杂的数据结构,并且在地理信息系统,游戏等领域的开发中的应用非常广泛。但其实现起来较为复杂,故将图常用的实现方式和图操作的基本方法封装了起来以求作为基础,并在基础之上拓展延伸出图的更为复杂的操作,由于时间有限,只有有向图的实现,而无向图需要对其中的某些代码加以增加,另外算法功力着实有限,并不能保证所有算法均为最优,在邻接矩阵的实现 中添加了当超出数量上限时自动扩大数组范围的功能,但不能保证这对性能的影响是最小的。发布出来 全且当作与大家共同学习探讨的媒介,望各位大侠不吝赐教。

1.图通用类的接口的设计:

package com.dk.javaSTL;

import java.util.ArrayList;

public interface GraphSet<T> {
    public static final byte unDigraph = 0;//无向图标志
    public static final byte Digraph = 1;//有向图标志
    public static final byte Matrix = 0;//邻接矩阵实现
    public static final byte AdjList = 1;//邻接表实现

    public boolean isNULLGraph() throws Exception; //判断为空的方法

    public void MakeNULLGraph();//图置空

    public GraphNode<T> firstVertex();//获得图的首节点

    public ArrayList<GraphNode<T>> nextVertex(GraphNode<T> node);//获得已知节点的下一个节点

    public ArrayList<GraphNode<T>> searchVertex(int[] val, int count);//搜索节点

    public boolean addVertex(T val);//添加顶点

    public boolean deleteVertex(int num);//删除定点

    public boolean addEdge(int vnum1, int vnum2);//两点之间添加弧 参数为定点标号

    public boolean deleteEdge(int vnum1, int vnum2);//删除两点之间的弧

    public boolean EdgeExists(int vnum1, int vnum2);//判断两点之间的弧是否存在
}

2.顶点 以及 弧 的数据结构

package com.dk.javaSTL;

public class GraphNode<T> {
    private int num;
    private T data;
    private GraphEdge edgeList;
    private GraphNode<T> nextVertex;

    public GraphNode(int num, T data) {
        this.setNum(num);
        this.setData(data);
        this.setEdgeList(null);
        this.setNextVertex(null);
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public T getData() {
        return data;
    }

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

    public GraphEdge getEdgeList() {
        return edgeList;
    }

    public void setEdgeList(GraphEdge edgeList) {
        this.edgeList = edgeList;
    }

    public GraphNode<T> getNextVertex() {
        return nextVertex;
    }

    public void setNextVertex(GraphNode<T> nextVertex) {
        this.nextVertex = nextVertex;
    }
}

package com.dk.javaSTL;

public class GraphEdge {
    private int endvex;
    private int weight;
    private GraphEdge nextEdge;

    public GraphEdge(int ev, int weight, GraphEdge next) {
        this.setEndvex(ev);
        this.setWeight(weight);
        this.setNextEdge(next);
    }

    public int getEndvex() {
        return endvex;
    }

    public void setEndvex(int endvex) {
        this.endvex = endvex;
    }

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    public GraphEdge getNextEdge() {
        return nextEdge;
    }

    public void setNextEdge(GraphEdge nextEdge) {
        this.nextEdge = nextEdge;
    }
}

3.Graph通用类实现

package com.dk.javaSTL;

import java.util.ArrayList;

public class Graph<T> implements GraphSet<T> {
    private byte directionType;
    private byte Method;
    private int VertexSize;
    private int MatrixMaxVertex;
    private GraphNode<T>[] Vertexs;
    private int[][] EdgesMatrix;
    private int[] temp;
    private GraphNode<T> headptr;
    private GraphNode<T> tailptr;

    public byte getDirectionType() {
        return directionType;
    }

    public void setDirectionType(byte directionType) {
        this.directionType = directionType;
    }

    public byte getMethod() {
        return Method;
    }

    public void setMethod(byte method) {
        Method = method;
    }

    public int getVertexSize() {
        return VertexSize;
    }

    public void setVertexSize(int i) {
        this.VertexSize = i;
    }

    public GraphNode<T> getHeadptr() {
        return headptr;
    }

    public void setHeadptr(GraphNode<T> headptr) {
        this.headptr = headptr;
    }

    public GraphNode<T>[] getVertexs() {
        return Vertexs;
    }

    public void setVertexs(GraphNode<T>[] vertex) {
        Vertexs = vertex;
    }

    public int[][] getEdgesMatrix() {
        return EdgesMatrix;
    }

    public void setEdgesMatrix(int[][] edges) {
        EdgesMatrix = edges;
    }

    public int getMatrixMaxVertex() {
        return MatrixMaxVertex;
    }

    public void setMatrixMaxVertex(int matrixMaxVertex) {
        MatrixMaxVertex = matrixMaxVertex;
    }

    public int[] getTemp() {
        return temp;
    }

    public void setTemp(int[] temp) {
        this.temp = temp;
    }

    public GraphNode<T> getTailptr() {
        return tailptr;
    }

    public void setTailptr(GraphNode<T> tailptr) {
        this.tailptr = tailptr;
    }

    public Graph(byte dtype, byte method) {
        this.setDirectionType(dtype);
        this.setMethod(method);
        this.setVertexSize(0);
        this.setHeadptr(null);
        this.setTailptr(null);
        if (method == GraphSet.Matrix) {
            Vertexs = new GraphNode[this.getMatrixMaxVertex()];
            EdgesMatrix = new int[this.getMatrixMaxVertex()][this
                    .getMatrixMaxVertex()];
        }
    }

    public Graph(byte dtype, byte method, int size) {
        this.setDirectionType(dtype);
        this.setMethod(method);
        this.setVertexSize(0);
        this.setMatrixMaxVertex(size);
        this.setHeadptr(null);
        this.setTailptr(null);
        if (method == GraphSet.Matrix) {
            Vertexs = new GraphNode[this.getMatrixMaxVertex()];
            EdgesMatrix = new int[this.getMatrixMaxVertex()][this
                    .getMatrixMaxVertex()];
        }
    }

    // ok
    @Override
    public boolean isNULLGraph() throws Exception {
        if (this.getVertexSize() == 0 || this.getHeadptr() == null)
            return true;
        return false;
    }

    // ok
    @Override
    public void MakeNULLGraph() {
        this.setHeadptr(null);
        this.setVertexSize(0);
        this.setVertexs(null);
        Runtime.getRuntime().gc();
    }

    // ok
    @Override
    public GraphNode<T> firstVertex() {
        if (this.getMethod() == GraphSet.Matrix)
            return this.getVertexs()[0];
        else if (this.getMethod() == GraphSet.AdjList)
            return this.getHeadptr();
        return null;
    }

    // ok
    @Override
    public ArrayList<GraphNode<T>> nextVertex(GraphNode<T> node) {
        assert (node != null);
        int count = 0;
        temp = new int[this.getVertexSize()];
        for (int i = 0; i < this.VertexSize; i++)
            this.temp[i] = -1;
        ArrayList<GraphNode<T>> Sequence = null;
        if (this.getMethod() == GraphSet.Matrix) {
            int index = node.getNum();
            for (int i = 0; i < this.getEdgesMatrix()[index].length; i++)
                if (this.getEdgesMatrix()[index][i] != 0)
                    temp[count++] = i;
        } else if (this.getMethod() == GraphSet.AdjList) {
            GraphEdge edge = node.getEdgeList();
            assert (edge != null);
            while (edge != null) {
                temp[count++] = edge.getEndvex();
                edge = edge.getNextEdge();
            }
        } else
            return null;
        Sequence = this.searchVertex(temp, count);
        return Sequence;
    }

    // ok
    @Override
    public ArrayList<GraphNode<T>> searchVertex(int[] val, int count) {
        assert (val != null);
        if (count == 0)
            return null;
        ArrayList<GraphNode<T>> Sequence = new ArrayList<GraphNode<T>>();
        if (this.getMethod() == GraphSet.Matrix) {
            GraphNode<T>[] node = this.getVertexs();
            for (int i = 0; i < this.getVertexs().length; i++)
                for (int j = 0; j < val.length; j++)
                    if (node[i].getNum() == val[j])
                        Sequence.add(node[i]);
        } else if (this.getMethod() == GraphSet.AdjList) {
            GraphNode<T> node = this.getHeadptr();
            while (node != null) {
                for (int i = 0; i < val.length; i++)
                    if (node.getNum() == val[i])
                        Sequence.add(node);
                node = node.getNextVertex();
            }
        } else
            return null;
        return Sequence;
    }

    // ok
    @Override
    public boolean addVertex(T val) {
        assert (val != null);
        if (this.getMethod() == GraphSet.Matrix) {
            if (this.getVertexSize() == this.getMatrixMaxVertex()) {
                int count = 0;
                GraphNode<T>[] vsource = this.getVertexs();
                GraphNode<T>[] vtarget = new GraphNode[this.MatrixMaxVertex *= 2];
                int[][] esource = this.getEdgesMatrix();
                int[][] etarget = new int[this.getMatrixMaxVertex()][this
                        .getMatrixMaxVertex()];// noted
                while (count < this.VertexSize) {
                    vtarget[count] = vsource[count];
                    count++;
                }
                vtarget[count] = new GraphNode<T>(this.VertexSize++, val);
                for (int i = 0; i < this.VertexSize; i++)
                    for (int j = 0; j < this.VertexSize; j++)
                        if (i == this.VertexSize - 1
                                || j == this.VertexSize - 1)
                            etarget[i][j] = 0;
                this.setVertexs(vtarget);
                this.setEdgesMatrix(etarget);
                Runtime.getRuntime().gc();
            } else
                this.getVertexs()[this.VertexSize] = new GraphNode<T>(
                        this.VertexSize++, val);
        } else if (this.getMethod() == GraphSet.AdjList) {
            GraphNode<T> workptr = new GraphNode<T>(this.VertexSize, val);
            if (this.VertexSize == 0)
                this.headptr = workptr;
            else
                this.tailptr.setNextVertex(workptr);
            this.tailptr = workptr;
            this.VertexSize++;
        } else
            return false;
        return true;
    }

    // ok
    @Override
    public boolean deleteVertex(int num) {
        assert (num >= 0);
        if (this.VertexSize == 0)
            return false;
        if (this.getMethod() == GraphSet.Matrix) {
            int index = -1;
            for (int i = 0; i < this.VertexSize; i++)
                if (this.getVertexs()[i].getNum() == num) {
                    index = i;
                    break;
                }
            if (index == -1)
                return false;
            for (int i = index; i < this.VertexSize-1; i++)
                this.Vertexs[i] = this.Vertexs[i+1];
            for (int i = index; i < this.VertexSize-1; i++)
                for (int j = 0; j < this.VertexSize; j++)
                    this.EdgesMatrix[i][j] = this.EdgesMatrix[i+1][j];
            for (int i = 0; i < this.VertexSize; i++)
                for (int j = index; j < this.VertexSize-1; j++)
                    this.EdgesMatrix[i][j] = this.EdgesMatrix[i][j+1];
            this.Vertexs[this.VertexSize - 1] = null;
            Runtime.getRuntime().gc();
        } else if (this.getMethod() == GraphSet.AdjList) {
            if (this.headptr.getNum() == num) {
                this.headptr = this.headptr.getNextVertex();
                this.VertexSize--;
                return true;
            }
            GraphNode<T> workptr = this.getHeadptr();
            GraphNode<T> helpptr = this.getHeadptr();
            while (workptr != null) {
                if (workptr.getNum() == num)
                    break;
                helpptr = workptr;
                workptr = workptr.getNextVertex();
            }
            if (workptr == null)
                return false;
            helpptr.setNextVertex(workptr.getNextVertex());
            workptr.setNextVertex(null);
            Runtime.getRuntime().gc();
        } else
            return false;
        this.VertexSize--;
        return true;
    }

    // ok
    @Override
    public boolean addEdge(int vnum1, int vnum2) {
        assert (vnum1 > 0 && vnum2 > 0 && vnum1 != vnum2);
        if (this.getMethod() == GraphSet.Matrix)
            this.EdgesMatrix[vnum1][vnum2] = 1;
        else if (this.getMethod() == GraphSet.AdjList) {
            GraphNode<T> workptr1 = this.headptr;
            while (workptr1 != null)
                if (workptr1.getNum() == vnum1) {
                    if (workptr1.getEdgeList() == null) {
                        workptr1.setEdgeList(new GraphEdge(vnum2, 1, null));
                        return true;
                    }
                    GraphEdge workptr2 = workptr1.getEdgeList();
                    while (workptr2.getNextEdge() != null)
                        workptr2 = workptr2.getNextEdge();
                    workptr2.setNextEdge(new GraphEdge(vnum2, 1, null));
                    break;
                } else
                    workptr1 = workptr1.getNextVertex();
        } else
            return false;
        return true;
    }

    // ok
    @Override
    public boolean deleteEdge(int vnum1, int vnum2) {
        assert (vnum1 > 0 && vnum2 > 0 && vnum1 != vnum2);
        if (this.getMethod() == GraphSet.Matrix)
            this.EdgesMatrix[vnum1][vnum2] = 0;
        else if (this.getMethod() == GraphSet.AdjList) {
            GraphNode<T> workptr = this.headptr;
            while (workptr != null)
                if (workptr.getNum() == vnum1) {
                    if (workptr.getEdgeList().getEndvex() == vnum2) {
                        workptr.setEdgeList(workptr.getEdgeList().getNextEdge());
                        break;
                    }
                    GraphEdge workptr1 = workptr.getEdgeList();
                    GraphEdge workptr2 = workptr.getEdgeList();
                    while (workptr1.getEndvex() != vnum2) {
                        workptr2 = workptr1;
                        workptr1 = workptr1.getNextEdge();
                    }
                    workptr2.setNextEdge(workptr1.getNextEdge());
                    workptr1.setNextEdge(null);
                    break;
                } else
                    workptr = workptr.getNextVertex();
        } else
            return false;
        Runtime.getRuntime().gc();
        return true;
    }

    // ok
    @Override
    public boolean EdgeExists(int vnum1, int vnum2) {
        assert (vnum1 >= 0 && vnum2 >= 0 && vnum1 != vnum2);
        if (this.getMethod() == GraphSet.Matrix)
            return (this.getEdgesMatrix()[vnum1][vnum2] == 0 ? false : true);
        else if (this.getMethod() == GraphSet.AdjList) {
            GraphNode<T> workptr = this.headptr;
            while (workptr != null) {
                if (workptr.getNum() == vnum1) {
                    GraphEdge workptr1 = workptr.getEdgeList();
                    while (workptr1 != null)
                        if (workptr1.getEndvex() == vnum2)
                            return true;
                        else
                            workptr1 = workptr1.getNextEdge();
                }
                workptr = workptr.getNextVertex();
            }
        } else
            return false;
        return false;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值