日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

稀疏数组和队列

發布時間:2023/12/20 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 稀疏数组和队列 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 稀疏數組sparsearray


1.1 運用場景

  • 編寫的五子棋程序中, 有存盤退出和續上盤的功能。

  • 分析問題:

因為該二維數組的很多值是默認值 0, 因此記錄了很多沒有意義的數據,這個時候我們就可以運用稀疏數組

?

1.2 解決方案

  • 當一個數組中大部分元素為0 , 或者為同一個值的數組時, 可以使用稀疏數組來保存該數組。
  • 稀疏數組的處理方法:
  • 稀疏數組一般是個N行3列的二維數組,第一行記錄了數組包含幾行幾列,有多少個不同的值。
  • 稀疏數組從第二行開始,記錄數組不同的值在第幾行、第幾列及其具體的值,從而縮小程序的規模。
  • 1.3 應用實例

    • 使用稀疏數組, 來保留類似前面的二維數組(棋盤、 地圖等等)
    • 把稀疏數組存盤, 并且可以從新恢復原來的二維數組數
    • 整體思路分析:

    1.4 代碼實現

    package com.gtjt.xxjss.parsearry;public class SparseArray {/*** 二維數組轉換成稀疏數組** @param dyadicArry* @return*/public static int[][] dyadicArrayConvertIntoSparseArray(int[][] dyadicArry) {//1.遍歷原始的二維數組,得到有效數據的個數sumint sum = 0;for (int i = 0;i < dyadicArry.length;i++) {for (int j = 0;j < dyadicArry[i].length;j++) {if (dyadicArry[i][j] != 0) {sum++;}}}//2.根據sum就可以創建稀疏數組sparseArray int[sum+1][3]int[][] sparseArray = new int[sum+1][3];sparseArray[0][0] = dyadicArry.length;sparseArray[0][1] = sparseArray[0][0];sparseArray[0][2] = sum;//3.將二維數組的有效數據存入稀疏數組int k = 1;for (int i = 0;i < dyadicArry.length;i++) {for (int j = 0;j < dyadicArry[i].length;j++) {if (dyadicArry[i][j] != 0) {sparseArray[k][0] = i;sparseArray[k][1] = j;sparseArray[k][2] = dyadicArry[i][j];k++;}}}return sparseArray;}/*** 稀疏數組轉換成二維數組** @param sparseArray* @return*/public static int[][] sparseArrayConvertIntoDyadicArray(int[][] sparseArray) {//1.先讀取稀疏數組的第一行,根據第一行的數據,創建原始的二維數組int[][] dyadicArray = new int[sparseArray[0][0]][sparseArray[0][1]];//2.在讀取稀疏數組后幾行的數據,并賦值給原始的二維數組即可for (int i = 1;i <= sparseArray[0][2];i++) {dyadicArray[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];}return dyadicArray;}public static void main(String[] args) {int[][] dyadicArry ={{0,0,0,0,0,0,0,0,0,0,0},{0,0,1,0,0,0,0,0,0,0,0},{0,0,0,2,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0}};System.out.println("原始的二維數組:");for (int[] d : dyadicArry) {for (int i = 0;i < d.length;i++) {System.out.printf("%d\t", d[i]);}System.out.println();}int[][] sparseArray = dyadicArrayConvertIntoSparseArray(dyadicArry);System.out.println("二維數組轉換后的稀疏數組:");for (int[] s : sparseArray) {for (int i = 0;i < s.length;i++) {System.out.printf("%d\t", s[i]);}System.out.println();}int [][] dyadicArry2 = sparseArrayConvertIntoDyadicArray(sparseArray);System.out.println("稀疏數組轉換后的二維數組:");for (int[] d : dyadicArry2) {for (int i = 0;i < d.length;i++) {System.out.printf("%d\t", d[i]);}System.out.println();}}}

    1.5 程序運行結果

    原始的二維數組: 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 二維數組轉換后的稀疏數組: 11 11 2 1 2 1 2 3 2 稀疏數組轉換后的二維數組: 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

    1.4 課后練習

    • 在前面的基礎上, 將稀疏數組保存到磁盤上, 比如 map.data
    • 恢復原來的數組時, 讀取 map.data 進行恢復

    ?

    2. 隊列

    2.1 隊列的一個使用場景

    銀行排隊的案例:

    2.2 隊列介紹

  • ?隊列是一個有序列表, 可以用數組或是鏈表來實現。
  • 遵循先入先出的原則。 即: 先存入隊列的數據, 要先取出。 后存入的要后取出
  • 示意圖: (使用數組模擬隊列示意圖)
  • 2.3 數組模擬隊列思路

    • 隊列本身是有序列表, 若使用數組的結構來存儲隊列的數據, 則隊列數組的聲明如下圖, 其中 maxSize 是該隊列的最大容量。
    • 因為隊列的輸出、 輸入是分別從前后端來處理, 因此需要兩個變量 front 及 rear 分別記錄隊列前后端的下標,
    • front 會隨著數據輸出而改變, 而 rear 則是隨著數據輸入而改變, 如圖所示:

    • 當我們將數據存入隊列時稱為” addQueue” , addQueue 的處理需要有兩個步驟: 思路分析
  • 將尾指針往后移: rear+1 , 當 front == rear 【空】
  • 若尾指針 rear 小于隊列的最大下標 maxSize-1, 則將數據存入 rear 所指的數組元素中, 否則無法存入數據。rear == maxSize - 1[隊列滿]
  • 2.4 代碼實現

    package com.gtjt.xxjss.queue;import java.util.Scanner;public class ArrayQueueDemo {public static void main(String[] args) {ArrayQueue queue = new ArrayQueue(3);char key = ' ';Scanner scanner = new Scanner(System.in);boolean loop = true;while (loop) {System.out.println("s(show):顯示隊列");System.out.println("e(exit):退出程序");System.out.println("a(add):添加數據到隊列");System.out.println("g(get):從隊列中取出數據");System.out.println("h(head):查看隊列頭部數據");key = scanner.next().charAt(0);switch (key) {case 's' :queue.showQueue();break;case 'a' :System.out.println("請輸入一個整數:");int value = scanner.nextInt();queue.addQueue(value);break;case 'g' :try {int res = queue.getQueue();System.out.printf("取出的數據是:%d\n", res);} catch (Exception e) {System.out.println(e.getMessage());}break;case 'h' :try {int res = queue.headQueue();System.out.printf("隊列頭部的數據是:%d\n", res);} catch (Exception e) {System.out.println(e.getMessage());}break;case 'e' :scanner.close();loop = false;break;default:break;}}System.out.println("程序退出~~");} }class ArrayQueue {private int maxSize;//隊列最大長度private int front;//指向隊列頭部前一個位置private int rear;//指向隊列尾部,包含尾部private int[] array;//構造一個長度為size的隊列public ArrayQueue(int size) {maxSize = size;front = -1;//隊列頭部,指向的是隊列頭的前一個位置rear = -1;//隊列尾部,指向隊列尾的數據(隊列的最后一個數據)array = new int[size];}//判斷隊列是否空public boolean isEmpty() {return front == rear;}//判斷隊列是否滿public boolean isFull() {return rear == maxSize - 1;}//往隊列存數public void addQueue(int n) {if (isFull()) {System.out.println("隊列滿,不能存數!");return;}rear++;array[rear] = n;}//從隊列中取數public int getQueue() {if (isEmpty()) {throw new RuntimeException("隊列空,不能取數!");}front++;return array[front];}//顯示隊列public void showQueue() {if (isEmpty()) {System.out.println("隊列為空,沒有數據!");return;}for (int i = (front + 1);i < rear + 1;i++) {System.out.printf("array[%d]:%d\n",i, array[i]);}}//取出隊列頭數據public int headQueue() {if (isEmpty()) {throw new RuntimeException("隊列空,不能取數!");}return array[front + 1];} }

    2.5 程序運行結果

    s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 a 請輸入一個整數: 1 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 a 請輸入一個整數: 2 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 a 請輸入一個整數: 3 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 a 請輸入一個整數: 4 隊列滿,不能存數! s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 h 隊列頭部的數據是:1 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 g 取出的數據是:1 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 s array[1]:2 array[2]:3 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 g 取出的數據是:2 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 g 取出的數據是:3 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 g 隊列空,不能取數! s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 s 隊列為空,沒有數據! s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 a 請輸入一個整數: 4 隊列滿,不能存數! s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據

    2.6?問題分析并優化

    • 目前數組使用一次就不能用, 沒有達到復用的效果
    • 將這個數組使用算法, 改進成一個環形的隊列 取模: %

    ?

    3. 數組模擬環形隊列

    ? 3.1 對前面的數組模擬隊列進行優化, 充分利用數組,可將數組看是一個環形的。 (通過取模的方式來實現)

    • 分析說明:
  • 尾索引的下一個為頭索引時表示隊列滿, 即將隊列容量空出一個作為約定,這個在做判斷隊列滿的時候需要注意 (rear + 1) % maxSize == front 滿]
  • rear == front [空]
  • 分析示意圖:
  • 3.2 代碼實現

    package com.gtjt.xxjss.queue;import java.util.Scanner;public class CircleArrayQueueDemo {public static void main(String[] args) {CircleArrayQueue queue = new CircleArrayQueue(4);char key = ' ';Scanner scanner = new Scanner(System.in);boolean loop = true;while (loop) {System.out.println("s(show):顯示隊列");System.out.println("e(exit):退出程序");System.out.println("a(add):添加數據到隊列");System.out.println("g(get):從隊列中取出數據");System.out.println("h(head):查看隊列頭部數據");key = scanner.next().charAt(0);switch (key) {case 's' :queue.showQueue();break;case 'a' :System.out.println("請輸入一個整數:");int value = scanner.nextInt();queue.addQueue(value);break;case 'g' :try {int res = queue.getQueue();System.out.printf("取出的數據是:%d\n", res);} catch (Exception e) {System.out.println(e.getMessage());}break;case 'h' :try {int res = queue.headQueue();System.out.printf("隊列頭部的數據是:%d\n", res);} catch (Exception e) {System.out.println(e.getMessage());}break;case 'e' :scanner.close();loop = false;break;default:break;}}System.out.println("程序退出~~");} }class CircleArrayQueue {private int maxSize;//隊列最大長度private int front;//指向隊列頭部,隊列第一個元素的位置private int rear;//指向隊列尾部,隊列最后一個元素的下一個位置(因為預留出一個空間,區分隊列滿和隊列空的情況)private int[] array;//構造器public CircleArrayQueue(int size) {maxSize = size;front = 0;rear = 0;array = new int[size];}//判斷隊列是否空public boolean isEmpty() {return front == rear;}//判斷隊列是否滿public boolean isFull() {return (rear + 1) % maxSize == front;}//往隊列存數public void addQueue(int n) {if (isFull()) {System.out.println("隊列滿,不能存數!");return;}array[rear] = n;//直接將數據寫入rear = (rear + 1) % maxSize;//將rear后移, 這里要考慮取模}//從隊列中取數public int getQueue() {if (isEmpty()) {throw new RuntimeException("隊列空,不能取數!");}// 因為front是指向隊列的第一個元素// 1. 先把 front 對應的值保留到一個臨時變量// 2. 將 front 后移, 要考慮取模// 3. 將臨時保存的變量返回int val = array[front];front = (front + 1) % maxSize;return val;}//顯示隊列的所有數據public void showQueue() {if (isEmpty()) {System.out.println("隊列為空,沒有數據!");return;}// 思路:從front開始遍歷,遍歷多少個元素// 關鍵點:環形隊列,front的值會在0到maxSize-1之間不斷循環for (int i = front;i < front + size();i++) {System.out.printf("array[%d]:%d\n",i % maxSize, array[i % maxSize]);}}//計算隊列的有效值個數public int size() {return ((rear - front + maxSize) % maxSize);}//取出隊列頭數據public int headQueue() {if (isEmpty()) {throw new RuntimeException("隊列空,不能取數!");}return array[front];} }

    3.3 程序運行結果

    s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 a 請輸入一個整數: 1 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 a 請輸入一個整數: 2 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 a 請輸入一個整數: 3 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 a 請輸入一個整數: 4 隊列滿,不能存數! s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 s array[0]:1 array[1]:2 array[2]:3 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 g 取出的數據是:1 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 h 隊列頭部的數據是:2 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 g 取出的數據是:2 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 s array[2]:3 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 g 取出的數據是:3 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 g 隊列空,不能取數! s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 a 請輸入一個整數: 4 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 a 請輸入一個整數: 5 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 s array[3]:4 array[0]:5 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 a 請輸入一個整數: 6 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 a 請輸入一個整數: 7 隊列滿,不能存數! s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 s array[3]:4 array[0]:5 array[1]:6 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 g 取出的數據是:4 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 h 隊列頭部的數據是:5 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 a 請輸入一個整數: 7 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 s array[0]:5 array[1]:6 array[2]:7 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 a 請輸入一個整數: 8 隊列滿,不能存數! s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據 s array[0]:5 array[1]:6 array[2]:7 s(show):顯示隊列 e(exit):退出程序 a(add):添加數據到隊列 g(get):從隊列中取出數據 h(head):查看隊列頭部數據

    ?

    ?

    ?


    ?

    總結

    以上是生活随笔為你收集整理的稀疏数组和队列的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。