深度优先搜索和广度优先搜索(1)

来源:互联网 发布:linux 全站 备份 编辑:程序博客网 时间:2024/06/05 22:46

一、深度优先搜索 
    深度优先搜索就是在搜索树的每一层始终先只扩展一个子节点,不断地向纵深前进直到不能再前进(到达叶子节点或受到深度限制)时,才从当前节点返回到上一级节点,沿另一方向又继续前进。这种方法的搜索树是从树根开始一枝一枝逐渐形成的。

      深度优先搜索亦称为纵向搜索。由于一个有解的问题树可能含有无穷分枝,深度优先搜索如果误入无穷分枝(即深度无限),则不可能找到目标节点。所以,深度优先搜索策略是不完备的。另外,应用此策略得到的解不一定是最佳解(最短路径)。

二、    重排九宫问题游戏
在一个3乘3的九宫中有1-8的8个数及一个空格随机摆放在其中的格子里。如下面左图所示。现在要求实现这样的问题:将该九宫调整为如下图右图所示的形式。调整规则是:每次只能将与空格(上,下或左,右)相临的一个数字平移到空格中。试编程实现。

| 2 | 8  | 3 |                |1 | 2 | 3 |
-
| 1|    | 4 |                |8 |    | 4|

| 7 |  | 5|                | 7 | 6 | 5 |

深度优先搜索的路径示意图:


http://zzg810314.javaeye.com/blog/80545 


 

三、广度优先搜索

    在深度优先搜索算法中,是深度越大的结点越先得到扩展。如果在搜索中把算法改为按结点的层次进行搜索,本层的结点没有搜索处理完时,不能对下层结点进行处理,即深度越小的结点越先得到扩展,也就是说先产生的结点先得以扩展处理,这种搜索算法称为广度优先搜索法。

广度优先搜索路径示意图:

 

四、航班问题(来自《The Art of Java》)
    一位顾客要预定一张从NewYork到Los Angeles的航班机票,下面是航班线路,请你为顾客找一种购票方案。

航班
距离
New York到Chicago
900英里
Chicago到Denver
1000英里
New York到Toronto
500英里
New York到Denver
1800英里
Toronto到Calgary
1700英里
Toronto到Los Angeles
2500英里
Toronto到Chicago
500英里
Denver到Urbana
1000英里
Denver到Houston
1000英里
Houston到Los Angeles
1500英里
Denver到Los Angeles
1000英里

下面是用深度优先搜索求解的程序:

// Find connections using a depth-first search.import java.util.*;import java.io.*;// Flight information.class FlightInfo {  String from;  String to;  int distance;  boolean skip; // used in backtracking  FlightInfo(String f, String t, int d) {    from = f;    to = t;    distance = d;    skip = false;  }}class Depth {  final int MAX = 100;  // This array holds the flight information.  FlightInfo flights[] = new FlightInfo[MAX];   int numFlights = 0; // number of entries in flight array  Stack btStack = new Stack(); // backtrack stack  public static void main(String args[])  {        String to, from;    Depth ob = new Depth();    BufferedReader br = new       BufferedReader(new InputStreamReader(System.in));      ob.setup();      try {       System.out.print("From? ");      from = br.readLine();       System.out.print("To? ");      to = br.readLine();       ob.isflight(from, to);      if(ob.btStack.size() != 0)        ob.route(to);    } catch (IOException exc) {       System.out.println("Error on input.");    }  }    // Initialize the flight database.  void setup()  {    addFlight("New York", "Chicago", 900);    addFlight("Chicago", "Denver", 1000);    addFlight("New York", "Toronto", 500);    addFlight("New York", "Denver", 1800);    addFlight("Toronto", "Calgary", 1700);    addFlight("Toronto", "Los Angeles", 2500);    addFlight("Toronto", "Chicago", 500);    addFlight("Denver", "Urbana", 1000);    addFlight("Denver", "Houston", 1000);    addFlight("Houston", "Los Angeles", 1500);    addFlight("Denver", "Los Angeles", 1000);  }    // Put flights into the database.  void addFlight(String from, String to, int dist)  {      if(numFlights < MAX) {      flights[numFlights] =        new FlightInfo(from, to, dist);      numFlights++;    }    else System.out.println("Flight database full.\n");  }  // Show the route and total distance.  void route(String to)  {    Stack rev = new Stack();    int dist = 0;    FlightInfo f;    int num = btStack.size();    // Reverse the stack to display route.    for(int i=0; i < num; i++)       rev.push(btStack.pop());    for(int i=0; i < num; i++) {      f = (FlightInfo) rev.pop();      System.out.print(f.from + " to ");      dist += f.distance;    }    System.out.println(to);    System.out.println("Distance is " + dist);  }    int match(String from, String to)  {    for(int i=numFlights-1; i > -1; i--) {      if(flights[i].from.equals(from) &&         flights[i].to.equals(to) &&         !flights[i].skip)      {        flights[i].skip = true; // prevent reuse        return flights[i].distance;      }    }    return 0; // not found   }    // Given from, find any connection.  FlightInfo find(String from)  {    for(int i=0; i < numFlights; i++) {      if(flights[i].from.equals(from) &&         !flights[i].skip)      {        FlightInfo f = new FlightInfo(flights[i].from,                             flights[i].to,                             flights[i].distance);        flights[i].skip = true; // prevent reuse        return f;      }    }    return null;  }    // Determine if there is a route between from and to.   void isflight(String from, String to)  {    int dist;    FlightInfo f;    // See if at destination.    dist = match(from, to);    if(dist != 0) {      btStack.push(new FlightInfo(from, to, dist));      return;    }    // Try another connection.    f = find(from);    if(f != null) {      btStack.push(new FlightInfo(from, to, f.distance));      isflight(f.to, to);    }    else if(btStack.size() > 0) {      // Backtrack and try another connection.      f = (FlightInfo) btStack.pop();      isflight(f.from, f.to);    }  }}