队列

队列

      • 队列的概念
      • 循环队列
      • 链式队列
      • 电路布线
      • 优先级队列
      • 双端队列

队列的概念

队列是一种限定存取位置的线性表。它只允许在表的一端插入,在另一端删除。

循环队列

循环队列有两个指针,一个front和一个rear指针,当front=rear时队列为空,当(rear + 1) % maxSize = front时,队列满。

链式队列

队列的队头指针指向单链表的第一个结点,队尾指针指向单链表的最后一个结点。用单链表表示的链式队列特别适合于数据元素变动比较大的情形,而且不存在队列满而产生溢出的情况。

电路布线

public class FindPath {

    private int[][] grid;

    private int m;

    class Position {
        private int row;
        private int col;
    }

    /**
     * 寻找从start到finish的最短路径。
     *
     * @param start
     * @param finish
     * @param pathLen
     * @param path
     * @return
     */
    public boolean findPath(Position start, Position finish, int pathLen, Position[] path) {
        if (start.row == finish.row && start.col == finish.col) {
            pathLen = 0;
            return true;
        }

        int numOfNbrs = 4, i, j;
        // 初始化网格外围墙
        for (i = 0; i <= m + 1; i++) {
            grid[0][i] = grid[m + 1][i] = 1;
            grid[i][0] = grid[i][m + 1] = 1;
        }
        Position[] offsets = new Position[4];
        // 右
        offsets[0].row = 0;
        offsets[0].col = 1;
        // 下
        offsets[1].row = 1;
        offsets[1].col = 0;
        // 左
        offsets[2].row = 0;
        offsets[2].col = -1;
        // 上
        offsets[3].row = -1;
        offsets[3].col = 0;

        Position here = new Position();
        Position nbr = new Position();
        here.row = start.row;
        here.col = start.col;
        // 因为0和1代表空白位置和封锁
        // 所以从2开始标记
        grid[start.row][start.col] = 2;
        Queue<Position> queue = new ArrayDeque<>();
        do {
            // 向外开始标记
            for (i = 0; i < numOfNbrs; i++) {
                nbr.row = here.row + offsets[i].row;
                nbr.col = here.col + offsets[i].col;
                // 该位置没有标记,标记它
                if (grid[nbr.row][nbr.col] == 0) {
                    grid[nbr.row][nbr.col] = grid[here.row][here.col] + 1;
                }
                if(nbr.row == finish.row && nbr.col == finish.col) {
                    break;
                }
                queue.offer(nbr);
            }
            if (nbr.row == finish.row && nbr.col == finish.col) {
                break;
            }
            if (queue.isEmpty()) {
                return false;
            }
            // 取一个位置向外扩展
            here = queue.poll();
        } while (true);
        pathLen = grid[nbr.row][nbr.col] - 2;
        path = new Position[pathLen];
        // 从终点回溯,查找路径
        here = finish;
        for (j = pathLen - 1; j >= 0; j--) {
            path[j] = here;
            for (i = 0; i < numOfNbrs; i++) {
                nbr.row = here.row + offsets[i].row;
                nbr.col = here.col + offsets[i].col;
                if (grid[nbr.row][nbr.col] == j + 2) {
                    break;
                }
            }
            here = nbr;
        }
        return true;
    }
}

优先级队列

每次从队列取出的应是具有最高优先权的元素,这种队列就是优先级队列。

双端队列

双端队列支持在队列的两端进行插入和删除操作。

你可能感兴趣的:(数据结构与算法,队列)