算法(第四版)-图

一般只会写代码,以后用来给自己参考的demo
(数据结构与算法c++描述也太难看懂了。。。说的是人话吗。。还是这个亲切)
(前面几章demo写本地了,有时间再发吧。。)

  1. 无向图(邻接表实现。。又像拉链法。。。Bag)
public class Graph
Graph( int v ) 创建一个含有v个顶点但不含边的图
Graph( In in) 读入一个图
int V() 顶点
int E() 边数
void addEdge( int v, int w) 加边
Iterable adj( int v)和v相邻的顶点
String toString() 对象的字符串表示
public class Graph
{
    private final int V;
    private int E;
    private Bag<Integer>[] adj;
    public Graph( int V )
    {
         this.V = V;
         this.E = 0;
         adj = (Bag<Integer>[]) new Bag[V];
         for( int v = 0 ; v < V ; ++v)
             adj[v] = new Bag<Integer>();
    }
    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);
         }
    }

    public int V()
    {
         return V;
    }
    
    public int E()
    {
         return E;
    }
   
    public void addEdge( int v, int w)
    {
          adj[v].add(w);
          adj[w].add(j);
          E++;
    }

     public Iterable<Integer> adj( int v)
     {
           return adj[v];
     }


 }
public class DFS
{
     private boolean[] marked;
     private int count;
    
    public DFS(Graph G ,int s)
    {
          marked = new boolean[G.V()];
          dfs(G,s);
    }
    
    private void dfs(Graph G, int v)
    {
            marked[v] = true;
            count++;
            for(int w : G.adj(v))
                if( !marked[w]) dfs(G,w);
    }
   
   public boolean marked( int w)
   {
          return marked[w];
   }
    
   public int count()
   { return count;}
}
使用dfs查找路径
public class DFP
{
       private boolean[] marked;
       private int[] edgeTo;
       private final int s;
      
       public DFP(Graph G, int s)
       {
              marked = new boolean[G.V()];
              edgeTo = new int[G.V()];
              this.s = s;
              dfs(G,s);
       }

       private void dfs(Graph G,int v)
       {
             markedp[v] = true;
             for( int w : G.adj(v))
                if( !marked[w])
                   {
                        edgeTo[w] = v;
                        dfs(G,w);
                   }
       }
   
       public boolean hasPathTo( int v)
     {
           return marked[v];
     }

    public Iterable<Integer>pathTo( int v)
    {
          if( !hasPathTo(v)) return null;
          Stack<Integer> path = new Stack<Integer>();
          for( int i=v ; i != s ; i = edgeTo[i])
             path.push(x);
          path.push(s);
          return path;  
   }
    
}
//用队列了 自己实现 java只提供接口
public class BFP
{
       private boolean[] marked;
       private int[] edgeTo;
       private int s;
   
        public BFP(Graph G, int s)
        {
             marked = new boolean[G.V()];
             edgeTo = new int[G.V()];
             this.s = s;
             bfs(G,s); 
        }
         private void bfs(Graph G , int s)
         {
                 Queen<Integer> queen = new Queen<Integer>();
                 marked[s] = true;
                 queen.enqueue(s);
                 while(!queen.isEmpty())
                 {
                      int v=queen.dequeen();
                      for( int i : queen.adj(v))
                      {
                            queen.enqueue(i);
                            edgeTo[i] = v;
                            marked[i] = true;
                      }
                 }
         }
    public boolean hasPathTo(int v)
    {
       return marked[v];
    }
  
   public Iterable<Integer> pathTo(int v)
   {
      Stack<Integer> path = new Stack<Integer>();
      for( int i = v ; i != s ; i = edgeTo[i] )
         path.push(i);
      path.push(s);
      return path;
   }
}
//连通分量
public class CC
{
     private boolean[] marked;
     private int[] id;
     private int count;
     public CC(Graph G)
     {
           marked = new boolean[G.V()];
           id = new int[G.V()];
           for( int i=0 ; i < G.V(); ++i)
                 if( !marked[i])
                 {
                      dfs(G,i);
                      count++;
                 }
      }

      private void dfs(Graph G, int v)
      {
      marked[v] = true;
      id[v] = count;
      for( int w : G.adj(v))
      {
           if( ! marked[w])
           dfs(G,w);
      }
            
      }
   
      public boolean connected(int v, int w)
      {
          return id[v] == id[w];
      }
  
      public int id( int v)
      {
         return id[v];
      }

      public int count()
      {
          return count;
      }
   
      
}
符号表
public class symbolGraph
{
       private ST<String,Integer> st;//treemap
       private String[] Keys;
       private Graph;
       public symbolGraph(String stream, String sp)
       {
           st = new ST<String,Integer>();
           In in = new In(stream);
           while(in.hasNextLine())
           {
                 String[] a = in.readLine().split(sp);
                 for( int i = 0 ; i < a.length ; ++i)
                       if(!st.contains(a[i]))
                           st.put(a[i],st.size());
           }
       

        keys = new String[st.size()];
        for( String name : st.keys())
        keys[st.get(name)] = name;
        G = new Graph(st.size());
        in = new In(stream);
        while(in.hasNextLine())
        {
              String[] a = in.readLine().split(sp);
              int v = st.get(a[0]);
              for( int i = 1 ; i < a.length ; ++i)
                  G.addEdge(v,st.get(a[i]));
        }
      }
   
     public boolean contains(String s)
     {
         return st.contains(s);
     }
   
     public int index(String s) { return st.get(s);}
     
}
  1. 有向图
public class Digraph
{
        private final int V;
        private int E;
        private Bag<Integer>[] adj;

        public Digraph( int V )
        {
               this.V = V;
               this.E = 0;
               adj = (Bag<Integer>[]) new Bag[V];
               for( int i = 0 ; i < V ; ++i)
               adj[i] = new Bag<Integer>();
        } 
  
        public int V()
        {
             return V;
        }
   
        public int E()
        {
              return E;
        }
  
         public void addEdge( int v, int w)
         {
               adj[v].add(w);
               E++;
         }
         
         public Iterable<Integer>adj( int v)
         {
              return adj[v];
         }

         public Digraph reverse()
         {
               Digraph R = new Digraph(V);
               for( int v = 0; v < V; ++v)
                  for( int w : adj(v))
                       R.addEdge(w,v);
               return R;
         }
        
}
public class DirectedDFS
{
     private boolean marked[];
     public DirectDFS(Digraph G, int s)
     {
               marked = new boolean[G.V()];
               dfs(G,s);
     }
  
     public DirectedDFS(Digraph G,Iterable<Integer> sources)
     {
               marked = new boolean[G.V()];
               for( int s : sources)
                    if(!marked[s]) dfs(G,s);
     }

      private void dfs(Digraph G, int v)
      {
              marked[v] = true;
              for( int w : G.adj(v))
                   if( !marked[w]) dfs(G,w);
         
      }
     
     public boolean marked(int v)
     {
           return marked[v]; 
     }
}
public class DrectedCycle
{
      private boolean[] marked;
      private int[] edgeTo;
      private Stack<Integer> cycle;
      private boolean[] onStack;

      public DirectedCycle (Digraph G)
      {
         onStack = new boolean[G.V()];
         edgeTo  = new int[G.V()];
         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 v)
      {
            onStack[v] = true;
            marked[v] = true;
            for( int w : G.adj(v))
                if( this.hasCycle()) return;
                else if ( !marked[v] ) 
                      {
                       edgeTo[v] = w;
                       dfs(G,w);
                     } 
                else if( onStack[v])
                      {
                         cycle = new Stack<Integer>();
                         for( int x = v; x != w ; x = edgeTo[x])
                                cycle.push(x);
                         cycle.push(w);
                         cycle.push(v);
                      }
              onStack[v] = false;           
      }
 
     public boolean hasCycle()
         { 
             return cycle != null;
         }
    
     public Iterable<Integer> cycle()
      { return cycle;}
      
}
public class DepthFirstOrder
{
         private boolean[] marked;
         private Queue<Integer> pre;
         private Queue<Integer> post;
         private Stack<Integer> reversePost;
         public DepthFirstOrder(Digraph G)
         {
             pre        = new Queue<Integer>();
             post       = new Queue<Integer>();
             reversepost= new Stack<Integer>();
             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 v)
         { 
              pre.enqueue(v);
              
              marked[v] = true;
              for( int w : G.adj(v))
                  if( !marked[w])
                      dfs(G,w);

             post.enqueue(v);
             reversePost.push(v); 
         }
         public Iterable<Integer>pre()
         {
             return pre;
         }
         public Iterable<Integer> post()
         {
            return post;
         }
         public Iterable<Integer> reversePost()
         {
            return reversePost;
         }
}
public class Topological
{
      private Iterable<Integer> order;
      public Topological(Digraph G)
      {
              DirectedCycle cyclefinder = new DirectedCycle(G);
              if ( !cyclefinder.hasCycle())
                {
                     DepthFirstOrder dfs = new DepthFirstOrder(G);

                     order = dfs.reversePost();
                }
              
      }
}
public class KosarajuSCC
{
      private booleanp[ marked;
      private int id;
      private int count;
 
     public KosarajuSCC(Digraph G)
     {
           marked = new boolean[G.V()];
           id = new int[G.V()];
           DepthFirstOrder order = new DepthFirstOrder(G.reverse());
           for( int s : order.reversePost())
                   if(!marked[s)
                   {
                     dfs(G,s);
                     count++;
                   }
     }
    
     
     private void dfs(Digraph G, int v)
     {
          marked[v] = true;
          id[v] = count;
          for( int w  : G.adj(v))
                if(!marked[w])
                     dfs(G,w);
     }
   
     public boolean stronglyconnected(int v , int w)
     {
        return id[v] == id[w];
     ]
   
     public int id(int v)
     {
           return id[v];
     }
     public int count()
     {
           return count;
     }
}
  1. 最小生成树
public class Edge implements Comparable<Edge>
{
          private final int v;
          private final int w;
          private final double weight;
 
           public Edge( int v, int w, double weight)
           {
               this.v = v;
               this.w = w;
              this.weight = weight;
           }
           public double weight()
           {
              return weight;
           }
           public int either()
           {
               return v;
           }
           public int other( int vertex)
           {
                  if      ( vertex == v ) return w;
                  else if ( vertex == w ) return v;
                   
           }
           public int compareTo(Edge that)
           {
                  if      (this.weight() < that.weight()) return -1;
                  else if (this.weight() > that.weight()) return 1;
                  else                                    return 0;
           }
           public String toString()
           {
                 return String.format("%d-%d %.2f",v,w,weight);
           }

}
public class EdgrWeightedGraphIn 
{
      private final int V;
      private int E;
      private Bag<Edge>[] adj;

      public EdgeWeightedGraph( int V)
      {
           this.V = V;
           this.E = 0;
           adj = (Bag<Edge>[]) new Bag[V];
           for( int i = 0 ; i < V ; ++i)
           {
           adj[i] = new Bag<Edge>();
           }
      }
      public EdgeWeightedGraph( In in)
      {
         int v= in.readInt();
         this(v);
         int e = in.readInt();
         for( int i = 0 ; i < e ; ++i)
         { 
           int g = in.readInt();
           int w = in.readInt();
            double weight = in.readdouble();
            Edge tmp = new Edge(g,w,weight);
            addEdge(tmp);
            
         }
         
      }
      public int V()
      {
           return  V;
      }
 
       public int E()
       {
           return E;
       }
 
       public void addEdge(Edge e)
       {
           int v = e.either;
           int w = e.other(v);
           adj[v].add(e);
           adj[w].add(e);
           E++;
       } 
       public Iterable<Edge> adj(int v)
       {
           return adj[v];
       }
       public Iterable<Edge> edges()
       {
           Bag<Edge> b = new Bag<Edge>();
           for( int v = 0 ; v < V ; ++v)
                for( Edge e : adj[v])
                      if( e.other(v) > v) b.add(e);
           return b;
       }
}
public class PrimMST
{
      private Edge[] edgeTo;
      private double[] distTo;
      private boolean[] marked;
      private IndexMinPQ<Double> pq;

      public PrimMST(EdgeWeightedGraph G)
      {
             edgeTo = new Edge[G.V()];
             distTo = new double[G.V()];
             marked = new boolean[G.V()];
             for( int v = 0 ; v < G.V() ; ++v)
             {
                   distTo[v] = Double.PSITIVE_INFINTY;
             }
             pq = new IndexMinPQ<Double>(G.V());

             distTo[0] = 0.0;
             pq.insert(0,0.0);
             while(!pq.isEmpty())
                visit(G,pq.delMin());
      }

     private void visit(EdgeWeightedGraph G, int v)
     {
              marked[v] = true;
              for( Edge e : G.adj(v))
              {
                   int w  = e.other(v);
                   if( marked[w]) continue;
                   if(e.weight() < disTo[w] )
                   {
                        edgeTo[w] = e;
                        disTO[w] = e.weight;
                        if(pq.contains(w)) pq.change(w,disTo[w]);
                        else               pq.insert(w,disTo[w]);
                   }
                   
              }
              
     }
}
public class kruskalMST
{
        private Queue<Edge> mst;
        public KruskalMST(EdgeWeightedGraph G)
        {
             mst = new Queue<Edge>();
             MinPQ<Edge> pq = new MinPQ<Edge>();
             for( Edge e : G.edges()) pq.iEdge nsert(e);
             UF uf = new UF(G.V());
             while(!pq.empty() && mst.size() < G.V()-1)
             {
                  Edge tmp = pq.delmin();
                  int v = tmp.either();
                  int w = tmp.other(v);
                  if(uf.connected(v,w)) continue;
                  uf.union(v,w);
                  mst.enqueue(tmp);
             }
        }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值