数据结构——图的遍历

代码实现

package 数据结构练习.图的遍历;

import java.util.Scanner;

/**
 * 遍历
 *
 * @param <T>
 */
class SequenceQueue<T> {
    static final int defaultSize = 10;
    T[] queueArray;
    int front;
    int rear;

    /**
     * 基本操作的成员方法
     *
     * @param size
     */
    public SequenceQueue(int size) { //构造大小为size的空队列
        queueArray = (T[]) new Object[size];
        front = rear = 0;
    }

    public SequenceQueue() {
        this(defaultSize);
    } //构造默认大小的空队列

    public void enQueue(T x) {//向循环队列的队尾加入一个元素 x
        if ((rear + 1) % queueArray.length == front) //追加空间
        {
            T[] p = (T[]) new Object[queueArray.length * 2];
            int j = 0;
            for (int i = this.front; i != this.rear; i = (i + 1) % queueArray.length)
                p[j++] = queueArray[i];
            queueArray = p;
            this.front = 0;
            this.rear = j;
        }
        queueArray[rear] = x;
        rear = (rear + 1) % queueArray.length;
    }

    public T deQueue() { //队列不空,删除循环队列 Q 的队头元素并返回其值,否则返回null
        if (this.front == this.rear)
            return null; //队列空
        T x = queueArray[front];
        front = (front + 1) % queueArray.length;
        return x;
    } // DeQueue

    public boolean isEmpty() {
        return front == rear;
    }
}

/**
 * 边的类定义
 *
 * @param <T>
 */
class Edge<T> {
    T v1;
    T v2;

    public Edge(T v1, T v2) {
        this.v1 = v1;
        this.v2 = v2;
    } //无权图的边
}

/**
 * 邻接矩阵表示的带权图类
 *
 * @param <T>
 */
class AMGraph<T> {        //定义泛型类
    static final int maxVexNum = 20;  //最大顶点数
    T[] vexs; //顶点数组
    int[][] arcs;    //邻接矩阵
    int vexNum;        //顶点数
    int arcNum;        //边数

    /**
     * 无参构造方法
     */
    public AMGraph() {
        vexs = (T[]) new Object[maxVexNum]; //根据最大顶点数构造顶点数组
        arcs = new int[maxVexNum][maxVexNum]; //根据最大顶点数构造边数组
        this.vexNum = 0; //实际顶点数为0
        this.arcNum = 0; //实际边数为0
        for (int i = 0; i < maxVexNum; i++) { //初始化邻接矩阵为∞,对角线上为0
            for (int j = 0; j < maxVexNum; j++) {
                arcs[i][j] = 0;
            }
        }
    }

    /**
     * 建立无向图
     *
     * @param vertex
     * @param e
     */
    public AMGraph(T[] vertex, Edge[] e) {//根据顶点数组和边数组,建立无向网
        vexs = (T[]) new Object[vertex.length * 2]; //分配顶点数组最大空间
        arcs = new int[maxVexNum][maxVexNum]; //分配邻接矩阵最大空间
        this.vexNum = vertex.length; //实际顶点数
        this.arcNum = e.length; //实际边数
        for (int i = 0; i < this.vexNum; i++) { //复制顶点至顶点数组
            this.vexs[i] = vertex[i];
        }
        for (int i = 0; i < maxVexNum; i++) { //初始化邻接矩阵为∞,对角线上为0
            for (int j = 0; j < maxVexNum; j++) {
                arcs[i][j] = 0;
            }
        }
        for (int k = 0; k < this.arcNum; k++) { //设置边
            int i = locateVex((T) e[k].v1); //获取第i条边第一个顶点v1的下标
            int j = locateVex((T) e[k].v2); //获取第i条边第二个顶点v2的下标
            if (i == -1 || j == -1)
                throw new IndexOutOfBoundsException("非法边");
            this.arcs[i][j] = 1;  //邻接矩阵i行j列值1
            this.arcs[j][i] = this.arcs[i][j]; //无向图,对称位置赋值
        }
    }

    /**
     * locateVex方法
     *
     * @param v
     * @return
     */
    public int locateVex(T v) {
        for (int i = 0; i < vexNum; i++)
            if (vexs[i].equals(v))
                return i;
        return -1;
    }

    /**
     * 深度优先遍历的构造方法
     */
    private boolean[] visited;

    public void dFS(int v) {
        System.out.print(vexs[v] + " ");
        visited[v] = true;
        for (int j = 0; j < vexNum; j++) {
            if (arcs[v][j] == 1 && visited[j] == false)
                dFS(j);
        }
    }

    public void DFSTraverse() {
        visited = new boolean[vexNum];
        for (int v = 0; v < vexNum; v++) {
            visited[v] = false;
        }
        for (int v = 0; v < vexNum; v++) {
            if (visited[v] == false)
                dFS(v);
        }
    }

    /**
     * 广度优先遍历的构造方法
     */
    public void bFS(int v) {
        SequenceQueue<Integer> q = new SequenceQueue<Integer>();
        System.out.print(this.vexs[v] + " ");
        visited[v] = true;
        q.enQueue(v); //v入队
        while (q.isEmpty() == false) {
            int w = q.deQueue();   //删除队首元素
            for (int j = 0; j < this.vexNum; j++) {
                if (this.arcs[w][j] == 1 && !visited[j])
                    System.out.print(this.vexs[j] + " ");
                visited[j] = true;
                q.enQueue(j);
            }
        }
    }

    public void BFSTraverse() {
        visited = new boolean[vexNum];
        for (int v = 0; v < vexNum; v++) {
            visited[v] = false;
        }
        for (int v = 0; v < vexNum; v++) {
            if (visited[v] == false)
                bFS(v);
        }
    }
}

/**
 * 测试类
 */
public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入顶点数n:");
        int n = sc.nextInt();
        System.out.println("请输入边数en:");
        int en = sc.nextInt();
        String[] vertex = new String[n];
        System.out.println("请输入" + n + "个顶点");
        for (int i = 0; i < n; i++) {
            vertex[i] = sc.next();
        }
        Edge[] e = new Edge[en];
        System.out.println("请输入" + en + "条边");
        for (int i = 0; i < en; i++) {
            String v1 = sc.next();
            String v2 = sc.next();
            e[i] = new Edge<String>(v1, v2);
        }
        AMGraph<String> G = new AMGraph(vertex, e);
        System.out.println("深度优先遍历序列为:");
        G.DFSTraverse();
        System.out.println();
        System.out.println("广度优先遍历序列为:");
        G.BFSTraverse();
    }

}

深度优先搜索

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

广度优先搜索

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值