稀疏数组和队列

一、稀疏数组

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

稀疏数组(sparsearray)的处理方式

  1. 记录数组一共有几行几列,有多少个不同的值
  2. 把具有不同值的元素的行列以及值记录在一个小规模的数组中,从而缩小程序的规模。

二维数组转稀疏数组的思路

  1. 遍历原始的二维数组,得到有效数据(不同的值的数据)的个数sum
  2. 根据sum可以创建稀疏数组sparseArray int[sum+1][3]
  3. 将二维数组的行列以及sum写入数组的第一行。然后将二维数组的有效数据存入到稀疏数组。

代码实现:

 /**
     * 将二维数组转为稀疏数组
     * @param twoDimensional
     */
    private static int[][] twoDimensionalToSparseArray(int[][] twoDimensional){
        if(twoDimensional.length == 0){
            return null;
        }
        //遍历得到二维数组一共有多少不同的值
        int sum = 0;
        for(int[] array : twoDimensional){
            for(int value : array){
                if(value != 0){
                    sum++;
                }
            }
        }

        //创建稀疏数组
        int[][] sparseArray = new int[sum+1][3];

        //首先保存第一行数据(二维数组的行、列、多少个不同的值)
        sparseArray[0][0] = twoDimensional.length;
        sparseArray[0][1] = twoDimensional[0].length;
        sparseArray[0][2] = sum;

        //遍历二维数组,将不同的值存入稀疏数组
        int count = 0;
        for(int i = 0; i < twoDimensional.length;i++){
            for(int j = 0; j < twoDimensional[0].length; j++){
                if(twoDimensional[i][j] != 0){
                    //先做加1操作,因为第一行保存了二维数组的行列信息
                    count++;
                    //保存行
                    sparseArray[count][0] = i;
                    //保存列
                    sparseArray[count][1] = j;
                    //保存值
                    sparseArray[count][2] = twoDimensional[i][j];
                }
            }
        }
        return sparseArray;
    }

    private static void printArray(int[][] array){
        for(int[] arr : array){
            for(int a : arr){
                System.out.print(a+"  ");
            }
            System.out.println();
        }
    }

    public static void main(String[] args) {
        //构造二维数组
        //构造一个11*11的二维数组,且第一行第二列为1,第二行第三列为2
        int[][] twoDimensional = new int[11][11];
        twoDimensional[0][1] = 1;
        twoDimensional[1][2] = 2;

        //打印原始二维数组
        System.out.println("原始二维数组");
        printArray(twoDimensional);
        System.out.println();

        //将二维数组转为稀疏数组并且打印
        int[][] sparseArray = twoDimensionalToSparseArray(twoDimensional);
        System.out.println("稀疏数组");
        printArray(sparseArray);


    }

稀疏数组转二维数组思路

  1. 先读取稀疏数组的第一行,根据第一行的数据(行和列)创建二维数组。
  2. 在读取稀疏数组后面几行的内容,依次赋值给二维数组即可。

代码实现

 /**
     * 将稀疏数组转为二维数组
     * @param sparseArray
     * @return
     */
    private static int[][] sparseArrayToTwoDimensional(int[][] sparseArray){
        if(sparseArray.length == 0){
            return null;
        }
        //读取稀疏数组的第一行构造二维数组
        //行
        int row = sparseArray[0][0];
        int column = sparseArray[0][1];
        int[][] twoDimensional = new int[row][column];

        //读取稀疏数组剩余部分,循环给二维数组赋值
        for(int i = 1; i < sparseArray.length; i++){
            twoDimensional[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
        }

        return twoDimensional;
    }
    
    
     public static void main(String[] args) {
        //构造二维数组
        //构造一个11*11的二维数组,且第一行第二列为1,第二行第三列为2
        int[][] twoDimensional = new int[11][11];
        twoDimensional[0][1] = 1;
        twoDimensional[1][2] = 2;

        //打印原始二维数组
        System.out.println("原始二维数组");
        printArray(twoDimensional);

        //将二维数组转为稀疏数组并且打印
        int[][] sparseArray = twoDimensionalToSparseArray(twoDimensional);
        System.out.println("稀疏数组");
        printArray(sparseArray);

        int[][] newTwoDimensional = sparseArrayToTwoDimensional(sparseArray);
        System.out.println("还原后的二维数组");
        printArray(newTwoDimensional);

    }
二 队列

队列是一个有序列表,可以使用数组或者链表来实现

遵循先入先出原则。即先存入队列的数据,要先取出,后存入队列的数据要后取出。

1. 数组模拟队列的思路
  • 队列本身是有序列表,若使用数组的结构来存储队列的数据,因为队列的输出输入是分别从前后端来处理,因此需要两个变量front及rear分别表示队列前后端的下标。front会随着数据的输出二改变,rear会随着数据的输入而改变。

代码实现如下:

2. 数组模拟环形队列

对数组模拟队列的优化,充分利用数组,因此将数组看做是一个环形的(通过取模的方式来实现)

思路分析:

  1. front 变量的含义做一个调整:front就指向队列的第一个元素,也就是说arr[front]就是队列的第一个元素。
  2. rear变量的含义做一个调整:rear指向队列的最后一个元素的后一个位置。因为希望空出一个空间做为约定。
  3. 当队列满时,条件时(rear+1)%maxSize=front [满]
  4. 当队列为空的条件:rear == front 空
  5. 队列中的有效数据个数(rear+maxSize-front)%maxSize // rear=1 front=0

尾索引的下一个为头索引表示队列满

代码实现

public class MyQueue {
    //表示队列的数组
    private int[] queue;
    //头部下标
    private int head;
    //尾部下标
    private int tail;

    public MyQueue(int n) {
        queue = new int[n];
        head = -1;
        tail = -1;
    }

    /**
     * 判断队列为空
     *
     * @return:
     * @author: zhaojiaxing
     * @createTime: 2019/10/31 0031 22:02
     */
    public boolean isEmpty() {
        return head == tail ? true : false;
    }

    /**
     * 判断队列是否已满
     *
     * @return:
     * @author: zhaojiaxing
     * @createTime: 2019/10/31 0031 22:04
     */
    public boolean isFull() {
        if (head >= queue.length - 1) {
            return true;
        }
        return false;
    }

    /**
     * 向队列中放元素
     *
     * @param num
     * @return: int
     * @author: zhaojiaxing
     * @createTime: 2019/10/31 0031 22:12
     */
    public int add(int num) {
        if (isFull()) {
            throw new RuntimeException("队列已满,不能再添加元素");
        }
        head++;
        queue[head] = num;
        return queue[head];
    }

    /**
     * 向队列中取元素
     * @param
     * @return: int
     * @author: zhaojiaxing
     * @createTime: 2019/10/31 0031 22:15
     */
    public int get() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空,不能再获取元素");
        }
        tail++;
        return queue[tail];
    }

    /**
     * 打印队列
     * @return:
     * @author: zhaojiaxing
     * @createTime: 2019/10/31 0031 22:20
     */
    public void searchQueue(){
        if(isEmpty()){
            System.out.println("队列 为空");
        }
        for(int i = tail+1;i<=head;i++){
            System.out.print(queue[i]+" ");
        }
        System.out.println(" ");
    }

    public static void main(String[] args) {
        //初始化队列
        MyQueue queue = new MyQueue(10);
        //向队列中添加元素
        try {
            for(int i = 0;i < 12;i++){
                queue.add((int)((Math.random()+1)*20));
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        queue.searchQueue();

        //从队列中读取元素
        try {
            System.out.println("向队列中获取元素");
            for(int i = 0;i < 12;i++) {
                System.out.println(queue.get());
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        queue.searchQueue();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值