(一)稀疏數(shù)組晨缴、數(shù)組隊列

一 線性結(jié)構(gòu)

數(shù)據(jù)元素之間存在一對一的線性關系

順序存儲結(jié)構(gòu)

順序表中的存儲元素是連續(xù)的

鏈式存儲結(jié)構(gòu)

鏈表中的存儲元素不一定是連續(xù)的,元素節(jié)點中存放數(shù)據(jù)元素以及相鄰元素的地址信息

二 非線性結(jié)構(gòu)

非線性結(jié)構(gòu)包括:二維數(shù)組,多維數(shù)組,廣義表勋颖,樹結(jié)構(gòu)耘擂,圖結(jié)構(gòu)

三 稀疏數(shù)組

當一個數(shù)組中大部分元素為摇庙,或者為同一個值的數(shù)組時旱物,可以使用稀疏數(shù)組來保存該數(shù)組。
稀疏數(shù)組的處理方法是:

  1. 記錄數(shù)組一共有幾行幾列卫袒,有多少個不同的值
    把具有不同值的元素的行列及值記錄在一個小規(guī)模的數(shù)組中宵呛,從而縮小程序的規(guī)模
    image.png

    image.png

實戰(zhàn)

  1. 使用稀疏數(shù)組,來保留類似前面的二維數(shù)組(棋盤夕凝、地圖等等)
  2. 把稀疏數(shù)組存盤宝穗,并且可以從新恢復原來的二維數(shù)組數(shù)
  3. 整體思路分析


    image.png

思路

二維數(shù)組轉(zhuǎn)稀疏數(shù)組

  1. 遍歷原始數(shù)組,得到有效數(shù)據(jù)的個數(shù)sum
  2. 創(chuàng)建一個稀疏數(shù)組int[sum+1][3](如果值只有0码秉,1逮矛;則可以省略第三列。第一行可以放默認值,規(guī)則自定義)转砖。這里放第一行二維數(shù)組的行列數(shù)以及sum
  3. 將二維數(shù)組的有效數(shù)據(jù)依次記錄

稀疏數(shù)組還原二維數(shù)組

  1. 根據(jù)第一行創(chuàng)建一個默認值的二維數(shù)組
  2. 從第二行開始遍歷须鼎,還原有效數(shù)值

代碼

    /**
     * 獲得一個原始二維數(shù)組
     * @return
     */
    public int[][] getOriginArray(){
        int[][] origin = new int[10][12];
        origin[2][8] = 1;
        origin[9][11] = 90;
        origin[8][5] = 123;
        origin[6][6] = 99;
        origin[7][4] = 6;
        origin[3][1] = 618;
        origin[5][9] = 111;
        return origin;

    }

    /**
     * 轉(zhuǎn)換成稀疏數(shù)組
     * @param origin
     * @return
     */
    public int[][] tranSparseArray(int[][] origin){
        int sum = 0;
        int rows = origin.length;
        int columns = origin[0].length;
        for(int i=0;i<rows;i++){
            int[] row= origin[i];
            for(int j=0;j<columns;j++){
                if(row[j]!=0){
                    sum++;
                }
            }
        }
        int[][] sparseArray = new int[sum+1][3];
        sparseArray[0][0] = sum;
        sparseArray[0][1] = rows;
        sparseArray[0][2] = columns;
        int index = 1;
        for(int i=0;i<rows;i++){
            int[] row= origin[i];
            for(int j=0;j<columns;j++){
                if(row[j]!=0){
                    sparseArray[index][0] = i;
                    sparseArray[index][1] = j;
                    sparseArray[index][2] = row[j];
                    index ++;
                }
            }
        }
        return sparseArray;

    }

    /**
     * 稀疏數(shù)組還原
     * @param sparseArray
     * @return
     */
    public int[][] recovery(int[][] sparseArray){
        int rows = sparseArray[0][1];
        int columns = sparseArray[0][2];
        int[][] orgins = new int[rows][columns];
        for(int index=1;index<sparseArray.length;index++){
            int row = sparseArray[index][0];
            int column = sparseArray[index][1];
            int value = sparseArray[index][2];
            orgins[row][column] = value;

        }
        return orgins;
    }

工具方法

    /**
     * 打印二維數(shù)組
     * @param array
     */
    public static void printTwoDimArray(int[][] array){
        for(int i = 0;i<array.length;i++){
            System.out.print("[");
            for(int j=0;j<array[i].length;j++){
                System.out.print("\t"+array[i][j]);
            }
            System.out.println("\t"+"]");

        }
    }

測試

    @Test
    public void test() {
        int[][] origin = getOriginArray();
        ArrayUtils.printTwoDimArray(origin);

        System.out.println("-----------");

        int[][] sparseArray = tranSparseArray(origin);
        ArrayUtils.printTwoDimArray(sparseArray);

        System.out.println("-----------");

        int[][] recoverys = recovery(sparseArray);
        ArrayUtils.printTwoDimArray(recoverys);


    }

四 隊列

隊列是一個有序列表,可以用數(shù)組或是鏈表來實現(xiàn)
遵循先入先出的原則

數(shù)組實現(xiàn)

  1. 隊列本身是有序列表府蔗,若使用數(shù)組的結(jié)構(gòu)來存儲隊列的數(shù)據(jù)晋控,則隊列數(shù)組的聲明如下圖, 其中 maxSize 是該隊列的最大容量
  2. 因為隊列的輸出、輸入是分別從前后端來處理姓赤,因此需要兩個變量 frontrear分別記錄隊列前后端的下標赡译,front會隨著數(shù)據(jù)輸出而改變,而 rear則是隨著數(shù)據(jù)輸入而改變不铆,如圖所示:

我的定義和圖不同蝌焚,front(rear)指向下一個要取(加)得元素得前一個下標

image.png

思路

  1. 取數(shù)據(jù)后狂男,front+1综看;加數(shù)據(jù)后品腹,rear+1(rear總是大于等于front
  2. 封裝一個數(shù)據(jù)機構(gòu)
  3. front=maxSize-1時岖食,隊列滿了

代碼

package com.zyc;

import org.junit.Test;

/**
 * @author zhuyc
 * @create 2019-07-13 16:25
 */
public class ArrayQueue {

    private int front;//下一個坐標就是要取得元素坐標
    private int rear;//下一個坐標就是增加元素得坐標
    private int maxSize;
    private int[] array;

    public ArrayQueue(int maxSize){
        front = -1;
        rear = -1;
        this.maxSize = maxSize;
        array = new int[maxSize];

    }

    public boolean isFull(){
        return rear == maxSize-1;
    }

    public boolean isEmpty(){
        return front==rear;//一樣表示放的都取出來了
    }

    public void push(int value){
        if(isFull()){
            throw new RuntimeException("隊列已滿");
        }
        array[++rear] = value;
    }

    public int pop(){
        if(isEmpty()){
            throw new RuntimeException("空隊列");
        }

        return array[++front];
    }


    public void showValidQueue(){
        if(isEmpty()){
            System.out.println("空隊列");
        }else{
            for(int i = front;i<rear;i++){
                System.out.printf("數(shù)組[%d]=%d",i+1,array[i+1]);
            }
            System.out.println();
        }

    }

    public void showQueue(){
        if(isEmpty()){
            System.out.println("空隊列");
        }else{
            for(int i = 0;i<maxSize;i++){
                System.out.printf("數(shù)組[%d]=%d",i,array[i]);
            }
            System.out.println();
        }

    }

    public int head(){
        if(isEmpty()){
            throw new RuntimeException("空隊列");
        }
        int index = front +1;
        return array[index];
    }
}

測試

    @org.junit.Test
    public void test(){
        ArrayQueue queue = new ArrayQueue(10);
        queue.push(23);
        queue.push(28);
        queue.push(1);
        queue.push(3);
        System.out.println("-------");
        queue.showQueue();
        queue.showValidQueue();
        System.out.println("-------");
        System.out.println(queue.pop());
        System.out.println(queue.head());
        System.out.println(queue.pop());
        System.out.println("-------");
        queue.showQueue();
        queue.showValidQueue();




    }

數(shù)組模擬環(huán)形隊列

上面的隊列的空間是不可復用,下面我們要進行優(yōu)化

思路分析

  1. front和rear對maxSize取模后的值范圍[0,maxSize-1]正好是數(shù)組的有效下標范圍
  2. rear-front<maxSize,否則就超出了容量(這樣就處理了覆蓋的問題)
  3. 取下標時我們需要對front(rear)取模
  4. 當front和rear同時超過maxSize時舞吭,作一次重置操作(兩者都等于取模后的值泡垃,這樣可以避免無限增長)
  5. 當maxSize=2的n次方時,可以用&maxSize-1操作代替取模

代碼

package com.zyc;

import org.junit.Test;

/**
 * @author zhuyc
 * @create 2019-07-13 16:25
 */
public class ArrayQueue {

    private int front;//下一個坐標就是要取得元素坐標
    private int rear;//下一個坐標就是增加元素得坐標
    private int maxSize;
    private int[] array;

    public ArrayQueue(int maxSize){
        front = -1;
        rear = -1;
        this.maxSize = maxSize;
        array = new int[maxSize];

    }

    public boolean isFull(){
        return rear-front==maxSize;
    }

    public boolean isEmpty(){
        return front==rear;//一樣表示放的都取出來了
    }

    public void push(int value){
        if(isFull()){
            throw new RuntimeException("隊列已滿");
        }


        int index = ++rear%maxSize;
        array[index] = value;
    }

    public int pop(){
        if(isEmpty()){
            throw new RuntimeException("空隊列");
        }
        if(front==maxSize){//重置
            front = front%maxSize;
            rear = rear%maxSize;
        }
        int index = ++front%maxSize;
        return array[index];
    }


    public void showValidQueue(){
        if(isEmpty()){
            System.out.println("空隊列");
        }else{
            for(int i = front;i<rear;i++){
                int index = (i+1)%maxSize;
                System.out.printf("數(shù)組[%d]=%d",index,array[index]);
            }
            System.out.println();
        }

    }

    public void showQueue(){
        if(isEmpty()){
            System.out.println("空隊列");
        }else{
            for(int i = 0;i<maxSize;i++){
                System.out.printf("數(shù)組[%d]=%d",i,array[i]);
            }
            System.out.println();
        }

    }

    public int head(){
        if(isEmpty()){
            throw new RuntimeException("空隊列");
        }
        int index = (front +1)%maxSize;
        return array[index];
    }





}

測試

    @Test
    public void testArrayQueue2(){
        ArrayQueue queue = new ArrayQueue(4);
        queue.push(1);
        queue.push(2);
        queue.push(3);
        queue.push(4);
        System.out.println("-------");
        queue.showQueue();
        queue.showValidQueue();
        System.out.println("-------");
        System.out.println(queue.pop());
        System.out.println(queue.head());
        System.out.println(queue.pop());
        System.out.println("-------");
        queue.showQueue();
        queue.showValidQueue();
        System.out.println("-------");
        queue.push(5);
        queue.push(6);
        queue.showQueue();
        queue.showValidQueue();
        System.out.println("-------");
        System.out.println(queue.pop());
        System.out.println(queue.pop());
        System.out.println(queue.pop());
        System.out.println(queue.pop());
        queue.push(7);
        queue.push(8);
        queue.push(9);
        queue.push(10);
        System.out.println("-------");
        queue.showQueue();
        queue.showValidQueue();
        System.out.println("-------");
        System.out.println(queue.pop());
        System.out.println(queue.pop());
        System.out.println(queue.pop());
        System.out.println(queue.pop());
        System.out.println("-------");
        queue.showQueue();
        queue.showValidQueue();
        System.out.println("-------");
        queue.push(11);
        System.out.println(queue.pop());
        System.out.println("end");


    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末羡鸥,一起剝皮案震驚了整個濱河市蔑穴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌惧浴,老刑警劉巖存和,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡捐腿,警方通過查閱死者的電腦和手機纵朋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來茄袖,“玉大人操软,你說我怎么就攤上這事∠芟椋” “怎么了聂薪?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蝗羊。 經(jīng)常有香客問我藏澳,道長,這世上最難降的妖魔是什么肘交? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任笆载,我火速辦了婚禮,結(jié)果婚禮上涯呻,老公的妹妹穿的比我還像新娘凉驻。我一直安慰自己,他們只是感情好复罐,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布涝登。 她就那樣靜靜地躺著,像睡著了一般效诅。 火紅的嫁衣襯著肌膚如雪胀滚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天乱投,我揣著相機與錄音咽笼,去河邊找鬼。 笑死戚炫,一個胖子當著我的面吹牛剑刑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播双肤,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼施掏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了茅糜?” 一聲冷哼從身側(cè)響起七芭,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蔑赘,沒想到半個月后狸驳,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體预明,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年耙箍,在試婚紗的時候發(fā)現(xiàn)自己被綠了贮庞。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡究西,死狀恐怖窗慎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情卤材,我是刑警寧澤遮斥,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站扇丛,受9級特大地震影響术吗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜帆精,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一较屿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧卓练,春花似錦隘蝎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至顽悼,卻和暖如春曼振,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蔚龙。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工冰评, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人木羹。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓甲雅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親汇跨。 傳聞我的和親對象是個殘疾皇子务荆,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容