数据结构之图(Java实现)

29 篇文章 0 订阅

数据结构之图

各算法的思想在之前的文章中有详解,下述只是用Java重新编程了一遍,对用到的算法不理解的,可以参考下面的文章
数据结构之图论算法(邻接矩阵)
Java代码实现:

class Graph {
    private int[][] Matrix;
    private String[] Vert;
    private int vertnum;
    private int edgenum;
    private final static Integer INF = Integer.MAX_VALUE;

    public Graph() {
    }

    public int[] Locate(String s1, String s2) {
        int m = 0;
        int n = 0;
        for (int i = 0; i < vertnum; ++i) {
            if (s1.equals(Vert[i]))
                m = i;
            if (s2.equals(Vert[i]))
                n = i;
        }
        int[] arr = new int[2];
        arr[0] = m;
        arr[1] = n;
        return arr;
    }

    public void createGraph() {
        Scanner input = new Scanner(System.in);
        System.out.print("请输入顶点数:");
        vertnum = input.nextInt();
        Matrix = new int[vertnum][vertnum];
        Vert = new String[vertnum];
        for (int i = 0; i < vertnum; ++i) {
            for (int j = 0; j < vertnum; ++j)
                Matrix[i][j] = INF;
            Matrix[i][i] = 0;
            input = new Scanner(System.in);
            System.out.print("请输入第" + (i + 1) + "个顶点信息:");
            Vert[i] = input.nextLine();
        }
        System.out.print("请输入边数:");
        edgenum = input.nextInt();
        String s1 = null;
        String s2 = null;
        int distance = 0;
        for (int i = 0; i < edgenum; ++i) {
            System.out.print("请输入起点:");
            input = new Scanner(System.in);
            s1 = input.nextLine();
            System.out.print("请输入终点:");
            input = new Scanner(System.in);
            s2 = input.nextLine();
            System.out.print("请输入距离:");
            distance = input.nextInt();
            int[] arr = Locate(s1, s2);
            Matrix[arr[0]][arr[1]] = distance;
            //Matrix[arr[1]][arr[0]]=distance;
        }
    }

    public void Print() {
        System.out.print(String.format("%-5s", " "));
        for (int i = 0; i < vertnum; ++i)
            System.out.print(String.format("%-5s", Vert[i]));
        System.out.println();
        for (int i = 0; i < vertnum; ++i) {
            System.out.print(String.format("%-5s", Vert[i]));
            for (int j = 0; j < vertnum; ++j) {
                if (Matrix[i][j] == INF)
                    System.out.print(String.format("%-5s", "oo"));
                else
                    System.out.print(String.format("%-5d", Matrix[i][j]));
            }
            System.out.println();
        }
    }

    public void TologySort() {
        int[] In = new int[vertnum];
        for (int i = 0; i < vertnum; ++i)
            In[i] = 0;
        for (int i = 0; i < vertnum; ++i) {
            for (int j = 0; j < vertnum; ++j) {
                if (Matrix[i][j] != INF && Matrix[i][j] != 0)
                    ++In[j];
            }
        }
        Queue<Integer> queue = new LinkedList<>();
        for (int i = 0; i < vertnum; ++i) {
            if (In[i] == 0)
                queue.offer(i);
        }
        while (!queue.isEmpty()) {
            int top = queue.peek();
            queue.poll();
            System.out.print(Vert[top] + " ");
            for (int i = 0; i < vertnum; ++i) {
                if (Matrix[top][i] != 0 && Matrix[top][i] != INF) {
                    --In[i];
                    if (In[i] == 0)
                        queue.offer(i);
                }
            }
        }
        System.out.println();
    }

    public void printPath(int[] parent, int root) {
        if (parent[root] == -1) {
            System.out.print(Vert[root] + " ");
            return;
        }
        printPath(parent, parent[root]);
        System.out.print(Vert[root] + " ");
    }

    public void NoWeight() {
        int[] visit = new int[vertnum];
        int[] parent = new int[vertnum];
        int[] dist = new int[vertnum];
        for (int i = 0; i < vertnum; ++i) {
            visit[i] = 0;
            parent[i] = -1;
            dist[i] = INF;
        }
        System.out.println("请输入起点:");
        Scanner input = new Scanner(System.in);
        String start = input.nextLine();
        Queue<Integer> queue = new LinkedList<>();
        for (int i = 0; i < vertnum; ++i) {
            if (Vert[i].equals(start)) {
                visit[i] = 0;
                dist[i] = 0;
                queue.offer(i);
                break;
            }
        }
        while (!queue.isEmpty()) {
            int top = queue.peek();
            queue.poll();
            for (int i = 0; i < vertnum; ++i) {
                if (Matrix[top][i] != 0 && Matrix[top][i] != INF) {
                    if (visit[i] == 0) {
                        visit[i] = 1;
                        dist[i] = dist[top] + 1;
                        parent[i] = top;
                        queue.offer(i);
                    }
                }
            }
        }
        System.out.println(String.format("%-5s %-5s %-5s", "value", "dist", "path"));
        for (int i = 0; i < vertnum; ++i) {
            System.out.print(String.format("%-5s", Vert[i]) + " ");
            System.out.print(String.format("%-5d", dist[i]) + " ");
            printPath(parent, i);
            System.out.println();
        }
    }

    public void Dijkstra() {
        int[] dist = new int[vertnum];
        int[] parent = new int[vertnum];
        int[] visit = new int[vertnum];
        for (int i = 0; i < vertnum; ++i) {
            parent[i] = -1;
            dist[i] = INF;
            visit[i] = 0;
        }
        System.out.print("请输入起点:");
        Scanner input = new Scanner(System.in);
        String start = input.nextLine();
        int top = 0;
        int current = 0;
        for (int i = 0; i < vertnum; ++i) {
            if (Vert[i].equals(start)) {
                dist[i] = 0;
                top = i;
                visit[i] = 1;
                ++current;
                break;
            }
        }
        while (current < vertnum) {
            for (int i = 0; i < vertnum; ++i) {
                if (Matrix[top][i] != INF && Matrix[top][i] != 0) {
                    if (Matrix[top][i] + dist[top] < dist[i]) {
                        dist[i] = dist[top] + Matrix[top][i];
                        parent[i] = top;
                    }
                }
            }
            int minz = INF;
            int nextpos = -1;
            for (int i = 0; i < vertnum; ++i) {
                if (visit[i] == 0 && dist[i] < minz) {
                    minz = dist[i];
                    nextpos = i;
                }
            }
            visit[nextpos] = 1;
            top = nextpos;
            ++current;
        }
        System.out.println(String.format("%-5s %-5s %-5s", "value", "dist", "path"));
        for (int i = 0; i < vertnum; ++i) {
            System.out.print(String.format("%-5s", Vert[i]) + " ");
            System.out.print(String.format("%-5d", dist[i]) + " ");
            printPath(parent, i);
            System.out.println();
        }
    }

    public void Floyd() {
        int[][] capacity = new int[vertnum][vertnum];
        for (int i = 0; i < vertnum; ++i) {
            for (int j = 0; j < vertnum; ++j)
                capacity[i][j] = Matrix[i][j];
        }
        for (int k = 0; k < vertnum; ++k) {
            for (int i = 0; i < vertnum; ++i) {
                for (int j = 0; j < vertnum; ++j) {
                    if (capacity[i][k] != INF && capacity[k][j] != INF) {
                        if (capacity[i][k] + capacity[k][j] < capacity[i][j]) {
                            capacity[i][j] = capacity[i][k] + capacity[k][j];
                        }
                    }
                }
            }
        }
        System.out.print(String.format("%-5s", " "));
        for (int i = 0; i < vertnum; ++i)
            System.out.print(String.format("%-5s", Vert[i]));
        System.out.println();
        for (int i = 0; i < vertnum; ++i) {
            System.out.print(String.format("%-5s", Vert[i]));
            for (int j = 0; j < vertnum; ++j) {
                if (capacity[i][j] == INF)
                    System.out.print(String.format("%-5s", "oo"));
                else
                    System.out.print(String.format("%-5d", capacity[i][j]));
            }
            System.out.println();
        }
    }
    public void Bellman_Ford(){
        int[]dist=new int[vertnum];
        int[]parent=new int[vertnum];
        for(int i=0;i<vertnum;++i)
        {
            dist[i]=INF;
            parent[i]=-1;
        }
        System.out.print("请输入起点:");
        Scanner input=new Scanner(System.in);
        String start=input.nextLine();
        for(int i=0;i<vertnum;++i)
        {
            if(Vert[i].equals(start))
            {
                dist[i]=0;
                break;
            }
        }
        for(int k=0;k<vertnum;++k)
        {
            for(int i=0;i<vertnum;++i)
            {
                for(int j=0;j<vertnum;++j)
                {
                    if(dist[i]!=INF&&Matrix[i][j]!=INF&&dist[i]+Matrix[i][j]<dist[j]){
                        dist[j]=dist[i]+Matrix[i][j];
                        parent[j]=i;
                    }
                }
            }
        }
        boolean flag=false;
        for(int i=0;i<vertnum;++i)
        {
            for(int j=0;j<vertnum;++j)
            {
                if(dist[i]!=INF&&Matrix[i][j]!=INF&&dist[i]+Matrix[i][j]<dist[j]){
                   flag=true;
                   break;
                }
            }
            if(flag)
                break;
        }
        if(flag)
        {
            System.out.println("存在负环路");
        }
        else
        {
            System.out.println(String.format("%-5s %-5s %-5s", "value", "dist", "path"));
            for (int i = 0; i < vertnum; ++i) {
                System.out.print(String.format("%-5s", Vert[i]) + " ");
                System.out.print(String.format("%-5d", dist[i]) + " ");
                printPath(parent, i);
                System.out.println();
            }
        }
    }
    public void SPFA(){
        int[]dist=new int[vertnum];
        int[]parent=new int[vertnum];
        int[]count=new int[vertnum];
        for(int i=0;i<vertnum;++i)
        {
            dist[i]=INF;
            parent[i]=-1;
            count[i]=0;
        }
        Queue<Integer>queue=new LinkedList<>();
        System.out.print("请输入起点:");
        Scanner input=new Scanner(System.in);
        String start=input.nextLine();
        for(int i=0;i<vertnum;++i)
        {
            if(Vert[i].equals(start)){
                dist[i]=0;
                queue.offer(i);
                count[i]=1;
                break;
            }
        }
        boolean flag=false;
        while(!queue.isEmpty()){
            int top=queue.peek();
            queue.poll();
            for(int i=0;i<vertnum;++i)
            {
                if(dist[top]!=INF&&Matrix[top][i]!=INF&&dist[top]+Matrix[top][i]<dist[i]){
                    dist[i]=dist[top]+Matrix[top][i];
                    parent[i]=top;
                    count[i]++;
                    if(count[i]==vertnum)
                    {
                        flag=true;
                        break;
                    }
                    queue.offer(i);
                }
            }
            if(flag)
                break;
        }
        if(flag)
        {
            System.out.println("存在负环路");
        }
        else
        {
            System.out.println(String.format("%-5s %-5s %-5s", "value", "dist", "path"));
            for (int i = 0; i < vertnum; ++i) {
                System.out.print(String.format("%-5s", Vert[i]) + " ");
                System.out.print(String.format("%-5d", dist[i]) + " ");
                printPath(parent, i);
                System.out.println();
            }
        }
    }
    public void Prim(){
        int[]dist=new int[vertnum];
        int[]parent=new int[vertnum];
        for(int i=0;i<vertnum;++i)
        {
            dist[i]=INF;
            parent[i]=-1;
        }
        int ans=0;
        System.out.print("请输入起点:");
        Scanner input=new Scanner(System.in);
        String start=input.nextLine();
        int top=0;
        int count=0;
        for(int i=0;i<vertnum;++i)
        {
            if(Vert[i].equals(start)){
                top=i;
                dist[i]=-1;
                count=1;
                break;
            }
        }
        while(count<vertnum)
        {
            for(int i=0;i<vertnum;++i)
            {
                if(dist[i]!=-1&&Matrix[top][i]!=0&&Matrix[top][i]<dist[i]){
                    dist[i]=Matrix[top][i];
                    parent[i]=top;
                }
            }
            int minz=INF;
            int nextpos=0;
            for(int i=0;i<vertnum;++i)
            {
                if(dist[i]!=-1&&dist[i]<minz)
                {
                    minz=dist[i];
                    nextpos=i;
                }
            }
            ++count;
            System.out.println(Vert[parent[nextpos]]+"--"+Vert[nextpos]+":"+minz);
            ans+=minz;
            top=nextpos;
            dist[top]=-1;
        }
        System.out.println(ans);
    }
    public int Find(int[]parent,int root)
    {
        if(parent[root]==-1)
            return root;
        return Find(parent,parent[root]);
    }
    public boolean Union(int[]parent,int root1,int root2){
        root1=Find(parent,root1);
        root2=Find(parent,root2);
        if(root1==root2)
            return false;
        parent[root1]=root2;
        return true;
    }
    private class node
    {
        private int from;
        private int to;
        private int distance;
        public node(int from,int to,int distance){
            this.from=from;
            this.to=to;
            this.distance=distance;
        }
    }
    private Comparator<node>distComparator=new Comparator<node>(){
        @Override
        public int compare(node o1,node o2){
            return (o1.distance-o2.distance);
        }
    };
    public void Kruskal(){
        Queue<node>priorityqueue=new PriorityQueue<>(distComparator);
        for(int i=0;i<vertnum;++i)
        {
            for(int j=0;j<vertnum;++j)
            {
                if(Matrix[i][j]!=0&&Matrix[i][j]!=INF)
                {
                    node nn=new node(i,j,Matrix[i][j]);
                    priorityqueue.add(nn);
                }
            }
        }
        int count=0;
        int[]visit=new int[vertnum];
        int[]parent=new int[vertnum];
        for(int i=0;i<vertnum;++i)
        {
            visit[i]=0;
            parent[i]=-1;
        }
        int ans=0;
        while(count<vertnum)
        {
            node temp=priorityqueue.peek();
            priorityqueue.poll();
            if(Union(parent,temp.from,temp.to))
            {
                ans+=temp.distance;
                if(visit[temp.from]==0)
                {
                    visit[temp.from]=1;
                    ++count;
                }
                if(visit[temp.to]==0)
                {
                    visit[temp.to]=1;
                    ++count;
                }
                System.out.println(Vert[temp.from]+"--"+Vert[temp.to]+":"+temp.distance);
            }
        }
        System.out.println(ans);
    }
    public void DFS(){
        System.out.print("请输入起点:");
        Scanner input=new Scanner(System.in);
        String start=input.nextLine();
        int[]visit=new int[vertnum];
        for(int i=0;i<vertnum;++i)
            visit[i]=0;
        Stack<Integer>stack=new Stack<>();
        for(int i=0;i<vertnum;++i)
        {
            if(Vert[i].equals(start))
            {
                stack.add(i);
                visit[i]=1;
                System.out.print(Vert[i]+" ");
                break;
            }
        }
        while(!stack.isEmpty()){
            int top=stack.peek();
            for(int i=0;i<vertnum;++i)
            {
                if(visit[i]==0&&Matrix[top][i]!=0&&Matrix[top][i]!=INF)
                {
                    visit[i]=1;
                    stack.add(i);
                    System.out.print(Vert[i]+" ");
                    break;
                }
            }
            if(top==stack.peek())
                stack.pop();
        }
        System.out.println();
    }
    public void dfs(int[]visit,int top){
        for(int i=0;i<vertnum;++i)
        {
            if(visit[i]==0&&Matrix[top][i]!=0&&Matrix[top][i]!=INF)
            {
                visit[i]=1;
                System.out.print(Vert[i]+" ");
                dfs(visit,i);
            }
        }
    }
    public void DFS1()
    {
        System.out.print("请输入起点:");
        Scanner input=new Scanner(System.in);
        String start=input.nextLine();
        int[]visit=new int[vertnum];
        for(int i=0;i<vertnum;++i)
            visit[i]=0;
        for(int i=0;i<vertnum;++i)
        {
            if(Vert[i].equals(start))
            {
                visit[i]=1;
                System.out.print(Vert[i]+" ");
                dfs(visit,i);
                break;
            }
        }
        for(int i=0;i<vertnum;++i)
        {
            if(visit[i]==0)
            {
                visit[i]=1;
                System.out.print(Vert[i]+" ");
                dfs(visit,i);
            }
        }
    }
    public int bfs(int[][]capacity,int[]pre,int[]flow,int start,int end){
        for(int i=0;i<vertnum;++i)
        {
            pre[i]=-1;
            flow[i]=INF;
        }
        pre[start]=start;
        Queue<Integer>queue=new LinkedList<>();
        queue.offer(start);
        while(!queue.isEmpty()){
            int top=queue.peek();
            queue.poll();
            if(top==end)
                break;
            for(int i=0;i<vertnum;++i)
            {
                if(pre[i]==-1&&capacity[top][i]!=INF&&capacity[top][i]!=0)
                {
                    flow[i]=Math.min(flow[top],capacity[top][i]);
                    pre[i]=top;
                    queue.offer(i);
                }
            }
        }
        if(pre[end]==-1)
            return -1;
        return flow[end];
    }
    public void EK(){
        System.out.print("请输入起点和终点:");
        Scanner input=new Scanner(System.in);
        String start=input.nextLine();
        input=new Scanner(System.in);
        String end=input.nextLine();
        int[][]capacity=new int[vertnum][vertnum];
        int[]flow=new int[vertnum];
        int[]pre=new int[vertnum];
        for(int i=0;i<vertnum;++i)
        {
            flow[i]=INF;
            pre[i]=-1;
            for(int j=0;j<vertnum;++j){
                capacity[i][j]=Matrix[i][j];
            }
        }
        int ans=0;
        int[]arr=Locate(start,end);
        while(true)
        {
            int offset=bfs(capacity,pre,flow,arr[0],arr[1]);
            if(offset==-1)
                break;
            ans+=offset;
           int j=arr[1];
           while(j!=arr[0])
           {
               int k=pre[j];
               capacity[k][j]-=offset;
               capacity[j][k]+=offset;
               j=k;
           }
        }
        System.out.println(ans);
    }
    public boolean bfs(int[][]capacity,int[]dist,int start,int end)
    {
        for(int i=0;i<vertnum;++i)
            dist[i]=-1;
        dist[start]=0;
        Queue<Integer>queue=new LinkedList<>();
        queue.offer(start);
        while(!queue.isEmpty()){
            int top=queue.peek();
            queue.poll();
            for(int i=0;i<vertnum;++i)
            {
                if(dist[i]==-1&&capacity[top][i]!=0&&capacity[top][i]!=INF){
                    dist[i]=dist[top]+1;
                    queue.offer(i);
                }
            }
        }
        if(dist[end]!=-1)
            return true;
        return false;
    }
    public int dfs(int[][]capacity,int[]dist,int now,int end,int value){
        if(now==end)
            return value;
        int minz=INF;
        for(int i=0;i<vertnum;++i)
        {
            if(dist[i]==dist[now]+1&&capacity[now][i]!=INF&capacity[now][i]!=0)
            {
                if((minz=dfs(capacity,dist,i,end,Math.min(value,capacity[now][i])))!=0)
                {
                    capacity[now][i]-=minz;
                    capacity[i][now]+=minz;
                    return minz;
                }
            }
        }
        return 0;
    }
    public void Dinic(){
        System.out.print("请输入起点和终点:");
        Scanner input=new Scanner(System.in);
        String start=input.nextLine();
        String end=input.nextLine();
        int[][]capacity=new int[vertnum][vertnum];
        int[]dist=new int[vertnum];
        for(int i=0;i<vertnum;++i)
        {
            dist[i]=-1;
            for(int j=0;j<vertnum;++j)
            {
                capacity[i][j]=Matrix[i][j];
            }
        }
        int[]arr=Locate(start,end);
        int ans=0;
        while(bfs(capacity,dist,arr[0],arr[1])){
            ans+=dfs(capacity,dist,arr[0],arr[1],INF);
        }
        System.out.println(ans);
    }
    public void SAP(){
        int[][]capacity=new int[vertnum][vertnum];
        int[]gap=new int[vertnum];
        int[]flow=new int[vertnum];
        int[]pre=new int[vertnum];
        int[]dist=new int[vertnum];
        for(int i=0;i<vertnum;++i)
        {
            gap[i]=0;
            pre[i]=-1;
            dist[i]=-1;
            flow[i]=INF;
            for(int j=0;j<vertnum;++j){
                capacity[i][j]=Matrix[i][j];
            }
        }
        Scanner input=new Scanner(System.in);
        String start=input.nextLine();
        input=new Scanner(System.in);
        String end=input.nextLine();
        int[]arr=Locate(start,end);
        dist[arr[1]]=0;
        gap[0]=1;
        Queue<Integer>queue=new LinkedList<>();
        queue.offer(arr[1]);
        while(!queue.isEmpty()){
            int top=queue.peek();
            queue.poll();
            for(int i=0;i<vertnum;++i)
            {
                if(dist[i]==-1&&capacity[i][top]!=0&&capacity[i][top]!=INF)
                {
                    dist[i]=dist[top]+1;
                    gap[dist[i]]++;
                    queue.offer(i);
                }
            }
        }
        if(dist[arr[0]]==-1)
            return;
        int ans=0;
        int top=arr[0];
        int i,j;
        while(dist[arr[0]]<vertnum){
            boolean flag=false;
            flow[arr[0]]=INF;
            for(i=0;i<vertnum;++i)
            {
                if(dist[top]==dist[i]+1&&dist[i]>=0&&capacity[top][i]!=0
                &&capacity[top][i]!=INF)
                {
                    flag=true;
                    break;
                }
            }
            if(flag)
            {
                flow[i]=Math.min(flow[top],capacity[top][i]);
                pre[i]=top;
                top=i;
                if(top==arr[1])
                {
                    ans+=flow[arr[1]];
                    int k=arr[1];
                    while(k!=arr[0])
                    {
                        capacity[pre[k]][k]-=flow[arr[1]];
                        capacity[k][pre[k]]+=flow[arr[1]];
                        k=pre[k];
                    }
                    top=arr[0];
                    for(j=0;j<vertnum;++j)
                        flow[j]=INF;
                }
            }
            else
            {
                int minz=INF;
                for(j=0;j<vertnum;++j)
                {
                    if(dist[j]+1<minz&&dist[j]>=0&&
                            capacity[top][j]!=0&&capacity[top][j]!=INF)
                        minz=dist[j]+1;
                }
                gap[dist[top]]--;
                if(gap[dist[top]]==0)
                    break;
                dist[top]=minz;
                gap[minz]++;
                if(top!=arr[0])
                    top=pre[top];
            }
        }
        System.out.println(ans);
    }
}
public class test{
    public static void main(String[]args)throws Exception {
        Graph graph=new Graph();
        graph.createGraph();
        graph.Print();
        //graph.TologySort();
        //graph.NoWeight();
        //graph.Dijkstra();
        //graph.Floyd();
        //graph.Bellman_Ford();
        //graph.SPFA();
        //graph.Prim();
        //graph.Kruskal();
        //graph.DFS();
        //graph.DFS1();
        //graph.EK();
        //graph.Dinic();
        //graph.SAP();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值