稀疏数组和队列

一、稀疏数组

1,定义

  当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。

2,转换

        

3,代码实现

源码: 稀疏数组

数组压缩

/**
 * 压缩为稀疏数组
 * @param cherryArray   原始数组
 */
private static int[][] toSparseArray(int[][] cherryArray) {
    //定义稀疏数组为固定3列 行数根据有值的sum+1
    int sum = 0;
    for (int[] ints : cherryArray) {
        for (int anInt : ints) {
            if (anInt != 0) {
                sum++;
            }
        }
    }
    int[][] sparseArray = new int[sum + 1][3];
    //获取稀疏数组第一行的数据
    sparseArray[0][0] = cherryArray.length;
    sparseArray[0][1] = cherryArray[0].length;
    sparseArray[0][2] = sum;
    //定义稀疏数组的行数指针
    int count = 0;
    for (int i = 0; i < cherryArray.length; i++) {
        for (int j = 0; j < cherryArray[i].length; j++) {
            if (cherryArray[i][j] != 0) {
                count++;
                sparseArray[count][0] = i;
                sparseArray[count][1] = j;
                sparseArray[count][2] = cherryArray[i][j];
            }
        }
    }
}

数组解压

/**
 * 解压缩为原始数组
 * @param sparseArray    稀疏数组
 */
private static void parseCherryArray(int[][] sparseArray) {
    int[][] parseArray = new int[sparseArray[0][0]][sparseArray[0][1]];
    //记录解析的指针
    int count = 1;
    int sum = sparseArray[0][2];
    for (int i = 0; i < sparseArray.length; i++) {
        for (int j = 0; j < sparseArray[i].length; j++) {
            //判断值的个数应该小于等于总个数sum,以防止索引越界
            if (count <= sum) {
                parseArray[sparseArray[count][0]][sparseArray[count][1]] = sparseArray[count][2];
                count++;
            }
        }
    }
}

二、队列

1,简介

  1) 队列是一个有序列表,可以用数组或是链表来实现。
  2) 遵循先入先出的原则。即:先存入队列的数据,要先取出。后存入的要后取出
  3) 示意图:(使用数组模拟队列示意图)

            

2,简单队列

  源码: 简单队列

  1)实现思路

rear初始为-1,表示尾部数据的前一个
front初始为-1,表示头部数据的前一个
maxSize最大值,数组的大小
队列的操作
a)往队列中插入数据时:
  判读队列是否为满: rear == maxSize - 1 [满]
  不满,则将rear指针后移,并往数组中添加数据。
b)从队列中取数据
  判断队列是否空: front == rear [空]
  不空,则将front前移,并获取当前数据

  2)代码实现

class ArrayQueue {

    private int maxSize;
    private int rear;
    private int front;
    private int[] arr;

    /**
     * 数组初始化
     */
    public ArrayQueue(int maxSize) {
        this.maxSize = maxSize;  //定义数据的长度
        arr = new int[maxSize];  //初始化数组
        rear = -1;               //定义尾部元素的指针
        front = -1;              //定义数组的第一个元素的前一个元素
    }

    /**
     * 获取头元素
     */
    public int head() {
        return arr[front + 1];
    }

    /**
     * 往队列中添加元素
     */
    public void add(int num) {
        //如果队列为满
        if (isFull()) {
            throw new RuntimeException("队列满,不能再添加!!!");
        }
        rear++; //当前元素上移
        arr[rear] = num;
    }

    /**
     * 从队列中获取元素
     */
    public int get() {
        if (isEmpty()) {
            throw new RuntimeException("队列空,不能再获取!!!");
        }
        front++;
        return arr[front];
    }

    /**
     * 遍历队列
     */
    public void show() {
        if (isEmpty()) {
            System.out.println("[]");
        }
        for (int i = front+1; i < rear+1; i++) {
            System.out.printf("arr[%d] = %d
", i, arr[i]);
        }
    }

    /**
     * 判断队列是否为空
     */
    public boolean isEmpty() {
        return rear == front;
    }

    /**
     * 判断队列是否满
     */
    public boolean isFull() {
        return rear == maxSize - 1;
    }
}

3,环形队列

  源码: 环形队列

  1)实现思路

rear最后元素的索引,初始值为0
front头元素的索引,初始值为0
maxSize队列的大小(实际要空一个出来)
a)添加数据
    判断满,(rear + 1) % maxSize == front
    如果不满,arr[rear]=num当前值
    rear移动:rear = (rear + 1) % maxSize
b)取数据
    判断空,rear == front
    如果不空,arr[front]为需要取出的值
    front移动:front = (front + 1) % maxSize
c)获取有效数据个数
    (rear  + maxSize - front) % maxSize 
d)遍历队列
    for (int i = front; i < front + valiable(); i++) {
       System.out.printf("a[%d] = %d
", i % maxSize, arr[i % maxSize]);
    }

  2)代码实现

/**
 * 定义环形队列
 */
class CircleQueue {
    //队列的大小
    private int maxSize;
    //队列的头元素的索引 初始值为0
    private int front;
    //队列的最后元素的索引 初始值为0
    private int rear;
    //队列的存储
    private int[] arr;

    /**
     * 初始构造
     */
    public CircleQueue(int maxSize) {
        this.maxSize = maxSize;
        this.arr = new int[maxSize];
    }

    /**
     * 插入数据
     */
    public void add(int num) {
        if (isFull()) {
            throw new RuntimeException("队列满,不能再添加!!!!!");
        }
        arr[rear] = num;
        //当前如果达到maxSize就从0开始继续加
        rear = (rear + 1) % maxSize;
    }

    /**
     * 显示队列
     */
    public void show() {
        //遍历的数据为从
        for (int i = front; i < front + valiable(); i++) {
            System.out.printf("a[%d] = %d
", i % maxSize, arr[i % maxSize]);
        }
    }

    /**
     * 获取有效元素的个数
     */
    public int valiable() {
        return (rear  + maxSize - front) % maxSize;
    }

    /**
     * 获取数据
     */
    public int get() {
        if (isEmpty()) {
            throw new RuntimeException("队列空,不能再获取数据!!!!!");
        }
        int num = arr[front];
        //当前如果达到maxSize就从0开始继续加
        front = (front + 1) % maxSize;
        return num;
    }

    /**
     * 获取头元素
     */
    public int head() {
        if (isEmpty()) {
            throw new RuntimeException("队列空,不能再获取数据!!!!!");
        }
        return arr[front];
    }

    /**
     * 判断队列是否满
     */
    public boolean isFull() {
        //如果队列长度为3 当前rear为2 front为0 则是满队列
        return (rear + maxSize + 1) % maxSize == front;
    }

    /**
     * 判断队列空
     */
    public boolean isEmpty() {
        return rear == front;
    }

}
原文地址:https://www.cnblogs.com/bbgs-xc/p/13985232.html