IDDFS(Iterative deepening depth-first search)的Java实现

        IDDFS,本人译作迭代深度的深度优先搜索。其实上就是深度优先搜索,只不过它对搜索深度进行了限制,使得在搜索到限制深度后必须开始新的搜索路径。以至于看上去像是广搜(总是先完成第n的所有节点的搜索,再开始第n+1的节点的搜索。放在这里的话,n指的就是当前的限制深度)。代码如下:

package com.wly.algorithmbase.search;

import com.wly.algorithmbase.datastructure.ArrayStack;

/**
 * Iterative deepening depth-first search
 * 整体是等同BFS,内存开销是等同DFS
 * 通常广搜用队列实现,深搜用栈实现,有点复杂哈
 * @author wly
 *
 */
public class IDDFS {
	
	
	public static ArrayStack stack;
	
	//3节点子树模型: 
	//     n
	//2n+1   2n+2
	
	//用数组表示的树结构,想要"米"观一些,费了老大劲了
	public static int[] tree = {
						    45,
				  23,		          67,
			 11,	  33,        55,	   89,
		   5,  15,  28,  40,  49,  60,   81,  101
	};
	
	public static boolean[] visitedFlag = new boolean[15];
	
	public static void main(String[] args) {
		
		stack = new ArrayStack();
		for(int i=0;i<4;i++) {
			System.out.println("============层数:" + i);
			DFS(i);
		}
		
	}
	
	/**
	 * 基于深度限制h的深度优先搜索
	 * @param h
	 */
	public static void DFS(int h) {
		int index = 0;
		
		if(h < 0) {
			System.out.println("错误,检索深度不能小于0!");
			return ;
		}
		
		initVisitedFlag();//初始化访问标记数组
		stack.push(tree[index]); //将起点放入到栈中
		visitedFlag[index] = true;
		int n = 0;
		while(!stack.isEmpty()) {
			stack.printElems();

			if((2*index + 1) < tree.length &&
					!visitedFlag[2*index+1] && n < h) {//检查左子节点,对应的是2*n+1
				stack.push(tree[2*index+1]);
				visitedFlag[2*index+1] = true;
				index = 2*index+1;
				n ++;		
			} else if((2*index + 2) < tree.length &&
					!visitedFlag[2*index+2] && n < h){//检查右子节点,对应的是2*n+2
				stack.push(tree[2*index+2]);
				visitedFlag[2*index+2] = true;
				index = 2*index+2;
				n ++;		
			} else {
				stack.pop();
				n --;
				index = (int)Math.ceil(((index-2)/2.0)); //向上取整,注意为double,否则容易出错
			}
		}
	}
	
	/**
	 * 设置访问标记为false
	 */
	public static void initVisitedFlag() {
		for(int i=0;i<visitedFlag.length;i++) {
			visitedFlag[i] = false;
		}
	}
}

       自定义类ArrayStack代码:

package com.wly.algorithmbase.datastructure;

/**
 * 使用数组实现栈结构
 * @author wly
 *
 */
public class ArrayStack {

	private int[] tArray; 
	private int topIndex = -1; //表示当前栈顶元素的索引位置
	private int CAPACITY_STEP = 12; //数组容量扩展步长
	
	
	public ArrayStack() {
		/***创建泛型数组的一种方法***/
		tArray = new int[CAPACITY_STEP]; 
	}
	
	/**
	 * 弹出栈顶元素方法
	 * @return
	 */
	public int pop() {
		if(isEmpty()) {
			System.out.println("错误,栈中元素为空,不能pop");
			return 0;
		} else {
			int i = tArray[topIndex];
			tArray[topIndex--] = 0; //擦除pop元素
			return i;
		}
	}
	
	/**
	 * 向栈中插入一个元素
	 * @param t
	 */
	public void push(int t) {
		//检查栈是否已满
		if(topIndex == (tArray.length-1)) {
			//扩展容量
			int[] tempArray = new int[tArray.length + CAPACITY_STEP];
			for(int i=0;i<tArray.length;i++) {
				tempArray[i] = tArray[i];
			}
			tArray = tempArray;
			tempArray = null;
		} else {
			topIndex ++;
			tArray[topIndex] = t;
		}
	}
	
	/**
	 * 得到栈顶元素,但不弹出
	 * @return
	 */
	public int peek() {
		if(isEmpty()) {
			System.out.println("错误,栈中元素为空,不能peek");
			return -1;
		} else {
			return tArray[topIndex];
		}
	}
	
	/**
	 * 判断当前栈是否为空
	 * @return
	 */
	public boolean isEmpty() {
		return (topIndex < 0);
	}
	
	/**
	 * 打印栈中元素
	 */
	public void printElems() {
		for(int i=0;i<=topIndex;i++) {
			System.out.print(tArray[i] + " ");
		}
		System.out.println();
	}	
}

       运行结果:

============层数:0
45 
============层数:1
45 
45 23 
45 
45 67 
45 
============层数:2
45 
45 23 
45 23 11 
45 23 
45 23 33 
45 23 
45 
45 67 
45 67 55 
45 67 
45 67 89 
45 67 
45 
============层数:3
45 
45 23 
45 23 11 
45 23 11 5 
45 23 11 
45 23 11 15 
45 23 11 
45 23 
45 23 33 
45 23 33 28 
45 23 33 
45 23 33 40 
45 23 33 
45 23 
45 
45 67 
45 67 55 
45 67 55 49 
45 67 55 
45 67 55 60 
45 67 55 
45 67 
45 67 89 
45 67 89 81 
45 67 89 
45 67 89 101 
45 67 89 
45 67 
45 

       好了,先到这里,,

       谢谢!!

    原文作者:DFS
    原文地址: https://blog.csdn.net/u011638883/article/details/17370607
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞