有向图

有向图与无向图类似。一幅有向图是由一组顶点和一组有方向的边组成的。每条有方向的边都连接着有序的一对顶点。

拓扑排序

给定一幅有向图,将所有的顶点排序,使得所有有向边均从排在前面的元素指向排在后面的元素。
拓扑排序的实际含义是解决有优先级限制的调度问题。不过该有向图必须是无环的,若存在一个x-y-z的环,代表x必须在y前完成,y又必须在z前完成,z又要在x前完成。显然这三个限制条件不可能被同时满足。因此在构造拓扑排序的图之后,首要任务是检查这个图是否存在环。
检查是否有环并保存存在的环

public static class DirectedCycle{   //判断图是否存在环
        private boolean[] marked;
        private int[] edgeto;
        private Stack<Integer> stack;
        private boolean[] on_stack;
        public DirectedCycle(diGraph d)
        {
            this.on_stack = new boolean[d.V()];
            this.edgeto = new int[d.V()];
            this.marked = new boolean[d.V()];
            for(int i=0;i<d.V();i++)
                if(!marked[i])
                    dfs(d, i);
        }
        private void dfs(diGraph g,int s)
        {
            on_stack[s]=true;
            marked[s]=true;
            Node n=g.adj.get(s);
            int temp = n.value;;
            while(n.next!=null)
            {
                n=n.next;
                if(!this.stack.isEmpty())
                    return;
                else if(!marked[n.value]) {
                    edgeto[n.value] = temp;
                    dfs(g, n.value);
                }
                else if(on_stack[n.value])
                {
                    stack = new Stack<>();
                    for(int i=temp;i!= n.value;i=edgeto[i] )
                        stack.push(i);
                    stack.push(n.value);
                    stack.push(temp);
                }
            }
            on_stack[s] = false;
        }
        }

和直接进行dfs相比,多了一个布尔数组on_stack用来保存现在递归的栈上存在的所有顶点;一个stack数组保存成环的顶点。判断成环条件就是当前顶点通向的下一顶点已经被标记遍历。
dfs的三种遍历方法

public static class DepthFirstOrder{  //三种遍历dfs的方法
        private boolean[] marked;
        private Queue<Integer> pre;//遍历顺序
        private Queue<Integer> post;//顶点遍历完成的顺序
        private Stack<Integer> reversePost;//实际就是拓扑排序的顺序
        public DepthFirstOrder(diGraph g)
        {
            pre = new LinkedList<>();
            post = new LinkedList<>();
            reversePost = new Stack<>();
            marked = new boolean[g.V()];
            for(int v=0;v<g.V;v++)
                if(!marked[v])
                    dfs(g,v);
        }
        private void dfs(diGraph g,int s)
        {
            pre.add(s);
            marked[s] = true;
            Node n = g.adj.get(s);
            int temp=n.value;
            while(n.next!=null) {
                n = n.next;
                if(!marked[n.value])
                dfs(g, n.value);
            }
            post.add(s);
            reversePost.push(s);
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值