稀疏數組和隊列

一、稀疏數組

當一個數組中大部分元素爲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();
    }
}
發佈了94 篇原創文章 · 獲贊 94 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章