0%

图的遍历

代码实现

/**
 * 无向图
 */
public class NoDirectionGraph {
 
    private int mMaxSize; //图中包含的最大顶点数
    private GraphVertex[] vertexList; //顶点数组
    private int[][] indicatorMat; //指示顶点之间的连通关系的邻接矩阵
    private int nVertex; //当前实际保存的顶点数目
    
    
    public NoDirectionGraph(int maxSize) {
        mMaxSize = maxSize;
        vertexList = new GraphVertex[mMaxSize];
        indicatorMat = new int[mMaxSize][mMaxSize];
        nVertex = 0;
        //初始化邻接矩阵元素为0
        for(int j=0;j<mMaxSize;j++) {
            for(int k=0;k<mMaxSize;k++) {
                indicatorMat[j][k] = 0;
            }
        }
    }
    
    
    public void addVertex(GraphVertex v) {
        if(nVertex < mMaxSize) {
            vertexList[nVertex++] = v;
            
        } else {
            System.out.println("---插入失败,顶点数量已达上限!");
        }
    }
    
    /**
     * 修改邻接矩阵,添加新的边
     * @param start
     * @param end
     */
    public void addEdge(int start,int end) {
        indicatorMat[start][end] = 1;
        indicatorMat[end][start] = 1;
    }
    
    /**
     * 打印邻接矩阵
     */
    public void printIndicatorMat() {
        
        for(int[] line:indicatorMat) {
            for(int i:line) {
                System.out.print(i + " ");
            }
            System.out.println();
        }
    }
    
    /**
     * 深度优先遍历
     * @param vertexIndex 表示要遍历的起点,即图的邻接矩阵中的行数
     */
    public void DFS(int vertexIndex) {
        ArrayStack stack = new ArrayStack();
        //1.添加检索元素到栈中
        vertexList[vertexIndex].setVisited(true);
        stack.push(vertexIndex);
        int nextVertexIndex = getNextVertexIndex(vertexIndex);
        while(!stack.isEmpty()) { //不断地压栈、出栈,直到栈为空(检索元素也没弹出了栈)为止
            if(nextVertexIndex != -1) {
                vertexList[nextVertexIndex].setVisited(true);
                stack.push(nextVertexIndex);
                stack.printElems();
            } else {
                stack.pop();
            }
            //检索当前栈顶元素是否包含其他未遍历过的节点
            if(!stack.isEmpty()) {
                nextVertexIndex = getNextVertexIndex(stack.peek()); 
            }
        }
    }
    
    /**
     * 得到当前顶点的下一个顶点所在行
     * @param column
     * @return
     */
    public int getNextVertexIndex(int column) {
        for(int i=0;i<indicatorMat[column].length;i++) {
            if(indicatorMat[column][i] == 1 && !vertexList[i].isVisited()) {
                return i;
            }
        }
        return -1;
    }
    
    /**
     * 广度优先遍历
     * @param vertexIndex 表示要遍历的起点,即图的邻接矩阵中的行数
     */
    public void BFS(int vertexIndex) {
        ChainQueue queue = new ChainQueue();
        vertexList[vertexIndex].setVisited(true);
        queue.insert(new QueueNode(vertexIndex));
        int nextVertexIndex = getNextVertexIndex(vertexIndex);
        while(!queue.isEmpty()) {
            if(nextVertexIndex != -1) {
                vertexList[nextVertexIndex].setVisited(true);
                queue.insert(new QueueNode(nextVertexIndex));
            } else {
                queue.remove();
            }
            if(!queue.isEmpty()) {
                nextVertexIndex = getNextVertexIndex(queue.peek().data);
                queue.printElems();
            }
        }
    }
}



 
/**
 * 使用数组实现栈结构
 */
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 -1;
        } else {
            int i = tArray[topIndex];
            tArray[topIndex--] = -1; //擦除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();
    }
}


/**
 * 使用链表实现队列
 */
public class ChainQueue {
    private QueueNode head; // 指向队列头节点
    private QueueNode tail; // 指向队列尾节点
    private int size = 0; // 队列尺寸
 
    public ChainQueue() {
 
    }
 
    /**
     * 插入新节点到队列尾
     */
    public void insert(QueueNode node) {
 
        // 当然也可以这么写,添加tail.prev = node
        if (head == null) {
            head = node;
            tail = head;
        } else {
            node.next = tail;
            tail.prev = node; // 双向连接,确保head.prev不为空
            tail = node;
        }
        size++;
    }
 
    /**
     * 移除队列首节点
     */
    public QueueNode remove() {
        if (!isEmpty()) {
            QueueNode temp = head;
            head = head.prev;
            size--;
            return temp;
        } else {
            System.out.println("异常操作,当前队列为空!");
            return null;
        }
    }
 
    /**
     * 队列是否为空
     * 
     * @return
     */
    public boolean isEmpty() {
        if (size > 0) {
            return false;
        } else {
            return true;
        }
    }
 
    /**
     * 返回队列首节点,但不移除
     */
    public QueueNode peek() {
        if (!isEmpty()) {
            return head;
        } else {
            System.out.println();
            System.out.println("异常操作,当前队列为空!");
            return null;
        }
    }
 
    /**
     * 返回队列大小
     * 
     * @return
     */
    public int size() {
        return size;
    }
    
    /**
     * 打印队列中的元素
     */
    public void printElems() {
        QueueNode tempNode = head;
        while(tempNode != null) {
            System.out.print(tempNode.data + " ");
            tempNode = tempNode.prev;
        }
        System.out.println();
    }
}
 
/**
 * 节点类
 * 
 * @author wly
 * 
 */
class QueueNode {
    QueueNode prev;
    QueueNode next;
 
    int data;
 
    public QueueNode(int data) {
        this.data = data;
    }
 
    public int getData() {
        return data;
    }
 
    public void setData(int data) {
        this.data = data;
    }
 
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        super.toString();
        return data + "";
    }
}