稀疏數組與環形數組

来源:https://www.cnblogs.com/train99999/archive/2019/06/26/11094469.html
-Advertisement-
Play Games

數據結構與演算法的關係 數據結構(data structure)是一門研究組織數據方式的學科,有了編程語言也就有了數據結構。學好數據結構可以編寫出跟家漂亮,更加有效率的代碼 要學好數據結構就要多多考慮如何將生活中遇到的問題,用程式去實現解決 程式=數據結構+演算法 數據結構是演算法的基礎,換言之,想要學好 ...


數據結構與演算法的關係

數據結構(data structure)是一門研究組織數據方式的學科,有了編程語言也就有了數據結構。學好數據結構可以編寫出跟家漂亮,更加有效率的代碼

要學好數據結構就要多多考慮如何將生活中遇到的問題,用程式去實現解決

程式=數據結構+演算法

數據結構是演算法的基礎,換言之,想要學好演算法,需要把數據結構學到位

數據結構包括:線性結構和非線性結構

線性結構:
  1. 線性結構作為最常用的數據結構,其特點是數據元素之間存在一對一的線性關係(a[0]=30)
  2. 線性結構有兩種不同的存儲結構,即順序存儲結構和鏈式存儲結構。順序存儲的線性表稱為順序表,順序表中的存儲元素是連續的
  3. 鏈式存儲的線性表稱為鏈表,鏈表中的存儲元素不一定連續,元素節點中存放數據元素以及相鄰元素的地址信息
  4. 線性結構常見的有:數組,隊列,鏈表和棧
非線性結構

非線性結構包括:二維數組,多維數組,廣義表,樹結構,圖結構

稀疏數組

當一個數組中大部分元素為0,或者為同一個值的數組時,可以使用稀疏數組來保存該數組

稀疏數組的處理方法是:

  1. 記錄數組一共有幾行幾列,有多少個不同的值
  2. 把具有不同的值得元素的行列及值記錄在一個小規模的數組中,從而縮小程式的規模

二維數組轉稀疏數組

  1. 遍歷 原始的二維數組,得到有效數據的個數sum
  2. 根據sum就可以創建稀疏數組sparseArr 行數為sum+1,列數固定為3
  3. 將二維數組的有效數據存入到稀疏數組

稀疏數組轉原始的二維數據

1.先讀取稀疏數組的第一行,根據第一行的數據,創建原始的二維數組,

2.在讀取稀疏數組後幾行的數據,並賦給原始的二維數據

package demo1;

public class SparseArray {
    public static void main(String[] args) {
        //二維數組,數組裡面裝了數組
        //定義一個行列為11的二維數組,第一個[]代表行,第二個代表列
        int chessArr1[][] = new int[11][11];
        //0:表示沒有棋子,1表示黑子,2表示藍子
        chessArr1[1][2] = 1;
        chessArr1[2][3] = 2;
        chessArr1[3][4] = 2;
//      System.out.println(chessArr1[1][2]);
        //遍曆數組,原始二維數組
        for(int i=0;i<chessArr1.length;i++) {
            for(int j=0; j<chessArr1[i].length;j++) {
                System.out.print(chessArr1[i][j]+"  ");
            }
            System.out.println();
        }
        //將二維數組轉為稀疏數組的思路
        //1.先遍歷二維數組 得到非0數據的個數
        int sum = 0 ;
        for(int i=0;i<chessArr1.length;i++) {
            for(int j=0; j<chessArr1[i].length;j++) {
                if(chessArr1[i][j]!=0) {
                    sum=sum+1;
                }
            }
        }
        //2.創建對應的稀疏數組
        //給稀疏數組賦值,
        int sparseArr[][] = new int[sum+1][3];
        sparseArr[0][0] = 11;
        sparseArr[0][1] = 11;
        sparseArr[0][2] = sum;
        // 遍歷二維數組,將非0的值存放到sparseArr中
        int count=0;
        for(int i=0;i<chessArr1.length;i++) {
            for(int j=0; j<chessArr1[i].length;j++) {
                if(chessArr1[i][j]!=0) {
                    count++;
                    //給sparseArr數組賦值
                    //第一個稀疏數組的值放在第一行
                    //所以需要遞增
                    sparseArr[count][0]=i;//稀疏數組的第一列存儲的是行數
                    sparseArr[count][1]=j;//稀疏數組的第二列存儲的是列數
                    sparseArr[count][2]=chessArr1[i][j];//稀疏數組的第三列存儲的是值
                }
            }
        }
        System.out.println("稀疏數組--------");
        for(int i=0;i<sparseArr.length;i++) {
            for(int j=0; j<sparseArr[i].length;j++) {
                System.out.print(sparseArr[i][j]+"  ");
            }
            System.out.println();
        }
        //把稀疏數組轉換成二維數組
        //定義新的二維數組,行數應該為稀疏數組的第一列,列數為第二列
        int chessArr2[][] = new int[sparseArr[0][0]][sparseArr[0][1]];
        //定義好的二維數組,把稀疏數組轉換為二維數組
        //稀疏數組sparseArr[i][0]對應是chessArr2的行
        //稀疏數組sparseArr[i][1]對應的是chessArr2的列
        //sparseArr[i][2];對應的是稀疏數組的值
        for(int i=1;i<sparseArr.length;i++) {
            chessArr2[sparseArr[i][0]][sparseArr[i][1]]=sparseArr[i][2];
        }
        //遍歷二維數組
        System.out.println("稀疏數組轉二維數組");
        for(int i=0;i<chessArr2.length;i++) {
            for(int j=0; j<chessArr2[i].length;j++) {
                System.out.print(chessArr2[i][j]+"  ");
            }
            System.out.println();
        }
    } 
}

img

隊列

隊列是一個有序列表,可以用數組或是鏈表來實現

遵循先入先出的原則,先存入隊列的數據,要先取出,後存入的數據,後取出。

數組模擬環形隊列實現

隊列滿條件是 (rear + 1) % maxSize == front 【滿】

隊列中有效的數據的個數 (rear + maxSize - front) % maxSize

package demo1;

import java.util.Scanner;

public class CircleArrayQueueDemo {

    public static void main(String[] args) {
        CircleArray queue = new CircleArray(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):查看隊列頭的數據");
            System.out.println("請輸入您的操作");
            key = scanner.next().charAt(0);
            switch(key) {
            case 's':
                queue.showQueue();
                break;
            case 'e':
                scanner.close();
                loop=false;
                break;
            case 'a':
                System.out.println("請輸入你要添加的數據");
                int i = scanner.nextInt();
                 queue.addQueue(i);
                break;
            case 'g':
                try {
                    int res = queue.getQueue();
                    System.out.println("取出的數據是"+res);
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }
                break;
            case 'h':
                try {
                    int res = queue.getQueue();
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }
                break;
            default:
                break;
            
            }
        }
        
        System.out.println("程式退出");

    }

}

class CircleArray{
    private int maxSize;//數組最大的容量
    private int front;//front指向隊列的第一個元素初始值為0
    private int rear;//rear 指向隊列的最後一個元素的後一個位置,rear初始值為0
    private int[] arr;//該數據用於存放數據,模擬隊列
    //創建隊列的構造器
    public CircleArray(int arrMaxSize) {
        maxSize = arrMaxSize;
        arr = new int[maxSize];
    }
    //判斷隊列是否滿
    public boolean isFull() {
        return (rear+1) % maxSize == front;
    } 
    //判斷隊列是否為空
    public boolean isEmpty() {
        return front == rear;
    }
    //添加數據到隊列
    public void addQueue(int n) {
        //判斷隊列是否滿
        if(isFull()) {
            System.out.println("隊列滿,不能加入數據");
        }
        arr[rear]=n;//rear指針在最後元素的後一位
        rear=(rear+1)%maxSize;
    }
    //獲取隊列的數據,出隊列
    public int getQueue() {
        //取出隊列,先判斷是否為空,為空,不能取
        if(isEmpty()) {
            throw new RuntimeException("隊列空,不能取");
        }
        int value = arr[front];
        front=(front+1)%maxSize;//front後移
        return value;
    }
    //顯示隊列的所有數據
    public void showQueue() {
        if(isEmpty()) {
            System.out.println("隊列空的,沒有數據");
            return;
        }
        for(int i = front; i< front +size();i++) {
            System.out.printf("arr[%d]=%d\n",i%maxSize,arr[i%maxSize]);
        }
    }
    public int size() {
        return(rear + maxSize - front) % maxSize;
    }
    //顯示隊列的頭數據
    public int headQueue() {
        if(isEmpty()) {
            System.out.println("隊列空的,沒有數據");
            throw new RuntimeException("隊列空的,沒有數據");
        }
        return arr[front];
    }
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 簡介Redis 是目前使用十分廣泛的記憶體資料庫。Redis 比 Memcached 支持更豐富的數據類型,如 Lists, Hashes, Sets 及 Ordered Sets 等,支持數據持久化、備份;除此之外,Redis 還支持事務,HA,主從庫,同時兼具了非關係型資料庫與關係型數據的特性,有 ...
  • python小游戲-16行代碼實現3D撞球小游戲!-源碼下載 python小游戲-16行代碼實現3D撞球小游戲!-源碼下載 python小游戲-16行代碼實現3D撞球小游戲!-源碼下載 所屬網站分類: 資源下載 > python小游戲 作者:搞笑 鏈接: http://www.pythonheido ...
  • 前幾天,星球有人提到貪吃蛇,一下子就勾起了我的興趣,畢竟在那個Nokia稱霸的年代,這款游戲可是經典中的經典啊!而用Python(蛇)玩Snake(貪吃蛇),那再合適不過了
  • 一、鏈表 鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。鏈表由一系列結點(鏈表中每一個元素稱為結點)組成,結點可以在運行時動態生成。每個結點包括兩個部分:一個是存儲數據元素的數據域,另一個是存儲下一個結點地址的指針域。 相比於線性表順序結構,操 ...
  • [TOC] 記憶體分配和釋放 STL中有兩個分配器,一級分配器和二級分配器,預設使用二級分配器,使用二級分配器分配大記憶體時會調用一級分配器去執行,一級分配器使用malloc和free分配和釋放記憶體。如果分配小記憶體那麼二級分配器會從記憶體池中進行查找,防止malloc/free的開銷。 為了瞭解原理,不深 ...
  • 代理模式:為其他對象提供一種代理來控制對這個對象的訪問。我們來看這樣一個簡單的例子,現在超市商家不直接把商品交給客戶,而是通過一些平臺的外賣小哥把商品送到客戶手中,此時外賣小哥就起到了代理的作用。代碼如下: ...
  • 今天我們來看一個編程語言入門必演示的HelloWorld程式,藉此來展示我們的重點知識。話不多說,先看代碼。 本段代碼在eclipse中編輯運行,怎麼在eclipse中新建項目呢:點擊左上角File選擇New一個Project.雖然本例僅僅實現了一個簡單的輸出HelloWorld一行字元串的簡單功能 ...
  • 花下貓語:之前說過,我對於編程語言跟其它學科的融合非常感興趣,但我還說漏了一點,就是我對於 Python 跟其它編程語言的對比學習,也很感興趣。所以,我一直希望能聚集一些有其它語言基礎的同學,一起討論共通的語言特性間的話題。不同語言的碰撞,常常能帶給人更高維的視角,也能觸及到語言的根基,這個過程是極 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...