アルゴリズムとデータ構造(Java Edition)01-スパース配列とキューの詳細な説明とコード実装

1スパース配列

  • いわゆるスパース配列は、配列内のほとんどのコンテンツ値が未使用(またはすべてゼロ)であり、配列内のスペースのごく一部のみが使用されている場合です。これにより、メモリスペースが無駄になります。メモリスペースを節約し、配列内の元のコンテンツ値に影響を与えないようにするために、スパース配列を使用してデータを圧縮できます。

1.1スパース配列のアプリケーションシナリオ

ここに画像の説明を挿入

1.2スパース配列の基本的な紹介

  • 配列内のほとんどの要素が0または同じ値の場合、スパース配列を使用して配列を格納できます
  • スパース配列の処理方法
    • レコード配列には合計でいくつかの行と列があり、そこにはいくつの異なる値があります
    • 異なる値を持つ要素の行と列を小さな配列に記録することにより、プログラムのサイズを縮小します

ここに画像の説明を挿入

1.3スパース配列のアプリケーション

ここに画像の説明を挿入

  • 2D配列をスパース配列に変換します
    • 元の2次元配列をトラバースして、有効なデータデータの総数を確認します
    • 有効なデータの数に基づいてスパース配列を作成します[有効な配列+1]
    • 有効なデータを2D配列のスパース配列に格納します
    • IOを介してスパース配列をディスクに書き込みます
  • スパース配列を元の2次元配列に変換します
    • ディスクからスパース配列を読み取り、上記のように最初の行のデータに従って元の2次元配列を作成します。int[15] [15]
    • スパース配列の残りの数行のデータを読み取り、それを2次元配列に割り当てます

1.4スパース配列コードの実装

1.4.1 2次元配列を作成し、初期値を割り当てます

/**
     * 二维数组初始化
     *
     * <p>
     *     这里模拟定义一个15*15的五子棋棋盘,并已知棋盘中已存在两个棋子
     *     来创建一个[15][15]的二维数组
     * </p>
     * @param
     * @return int[][]
     * @author ZhangSan_Plus
     * @description //TODO
     * @date 15:22 2022/4/15
     **/
    public static int[][] twoDimensionalGoBang() {
        int goBang[][] = new int[15][15];
        goBang[3][3] = 1;
        goBang[4][4] = 2;
        return goBang;
    }
复制代码

1.4.2元の2次元配列をスパース配列に変換する

/**
     * 二维数组转成稀疏数组
     *
     * <p>
     *     1.首先遍历原有的二维数组,得知原二维数组有效数据的总个数
     *     2.根据得知的有效数据来创建稀疏数组 [有效数据+1]
     *     3.将二维数据中有效数据的位置和值放到稀疏数组中
     * </p>
     * @param
     * @return int[][]
     * @author ZhangSan_Plus
     * @description //TODO
     * @date 15:37 2022/4/15
     **/
    public static int[][] twoDimensionalToSparse() {
        //创建一个原始的二位数组
        int[][] goBang = twoDimensionalGoBang();
        //1.遍历原有的二维数组,得知有效数据数据的总个数
        int valid = 0;
        for (int i = 0; i < goBang.length; i++) {
            for (int j = 0; j < goBang.length; j++) {
                if (goBang[i][j] != 0) {
                    valid++;
                }
            }
        }
        //2.根据有效数据来创建稀疏数组
        int[][] sparse = new int[valid + 1][valid + 1];
        sparse[0][0] = goBang.length;
        sparse[0][1] = goBang.length;
        sparse[0][2] = valid;
        int count = 0;
        for (int i = 0; i < goBang.length; i++) {
            for (int j = 0; j < goBang.length; j++) {
                if (goBang[i][j] != 0) {
                    count++;
                    sparse[count][0] = i;
                    sparse[count][1] = j;
                    sparse[count][2] = goBang[i][j];
                }
            }
        }
        return sparse;
    }
复制代码

1.4.3スパース配列を元の2次元配列に変換する

	public static void main(String[] args) {
        /**
         * <p>
         *     1.根据稀疏数组的特性已知其第一行存放为 二维数组的 行、列、值
         *     2.除第一行以外的数据其余存放的则是有效数据的 行、列、值
         * </p>
         */
        int[][] sparse = twoDimensionalToSparse();
        int[][] two = new int[sparse[0][0]][sparse[0][1]];
        for (int i = 1; i < sparse.length; i++) {
            //稀疏数组的第i行第0,1列为二维数组所在的位置 稀疏数组的第2列则为二维数组的值
            two[sparse[i][0]][sparse[i][1]] = sparse[i][2];
        }
        traverse(two);
    }
复制代码

1.4.42次元配列のトラバース

/**
     * 二维数组遍历
     *
     * @param array 二维数组
     * @return void
     * @author ZhangSan_Plus
     * @description //TODO
     * @date 15:22 2022/4/15
     **/
    public static void traverse(int[][] array) {
        for (int[] row : array) {
            for (int data : row) {
                System.out.printf("%d\t", data);
            }
            System.out.println();
        }
    }
复制代码

2つのキュー

  • キューは特殊な種類の線形テーブルです。特別な機能は、テーブルの前面での削除操作とテーブルの背面での挿入操作のみを許可することです。スタックと同様に、キューは線形制約テーブルの対象となる操作です。挿入操作を実行する端はキューの末尾と呼ばれ、削除操作を実行する端はキューの先頭と呼ばれます。

画像の説明を追加してください

2.1キューのアプリケーションシナリオ

  • 例:銀行の預金と引き出し、病院への電話などはキューと見なされます

2.2キューの基本的な紹介

  • キューは順序付きリストであり、配列またはリンクリストを使用して実装できます。
  • 先入れ先出しの原則に従います。つまり、最初にキューに格納されたデータを最初に取り出す必要があり、後で格納されたデータが取り出されます。

2.3一方向キューシミュレーションの実装

2.3.1配列を使用してキューをシミュレートする

public class ArrayImitateQueue {
    /**
     * 数组最大容量
     */
    private int maxSize;
    /**
     * 队列头
     */
    private int front;
    /**
     * 队列尾
     */
    private int rear;
    /**
     * 存放数据
     */
    private int[] arr;

    public ArrayImitateQueue(int maxSize) {
        this.maxSize = maxSize;
        arr = new int[maxSize];
        //指向队列头的前一个位置
        front = -1;
        //指向队列尾
        rear = -1;
    }

    /**
     * 判断队列是否已满
     *
     * @param
     * @return boolean
     * @author ZhangSan_Plus
     * @description //TODO
     * @date 16:43 2022/4/15
     **/
    public boolean isFull() {
        return rear == maxSize - 1;
    }

    /**
     * 判断队列是否为空
     *
     * @param
     * @return boolean
     * @author ZhangSan_Plus
     * @description //TODO
     * @date 16:44 2022/4/15
     **/
    public boolean isEmpty() {
        return rear == front;
    }

    /**
     * 向队列中添加数据
     *
     * @param num
     * @return void
     * @author ZhangSan_Plus
     * @description //TODO
     * @date 16:46 2022/4/15
     **/
    public void addQueue(int num) {
        if (isFull()) {
            System.err.println("队列已满不能添加数据");
            return;
        }
        rear++;
        arr[rear] = num;
    }

    /**
     * 取出队列中的值
     *
     * @param
     * @return int
     * @author ZhangSan_Plus
     * @description //TODO
     * @date 16:50 2022/4/15
     **/
    public int getQueue() {
        if (isEmpty()) {
            throw new RuntimeException("ERROR:index out of bounds");
        }
        front++;
        return arr[front];
    }

    /**
     * 显示队列中全部内容
     *
     * @param
     * @return void
     * @author ZhangSan_Plus
     * @description //TODO
     * @date 16:50 2022/4/15
     **/
    public void showQueue() {
        if (isEmpty()) {
            System.err.println("Queue is Null~");
            return;
        }
        for (int i : arr) {
            System.out.println(i);
        }
    }

    /**
     * 获取队列的头数据
     *
     * @param
     * @return int
     * @author ZhangSan_Plus
     * @description //TODO
     * @date 16:52 2022/4/15
     **/
    public int getFirstQueue() {
        if (isEmpty()) {
            throw new RuntimeException("ERROR:index out of bounds");
        }
        return arr[front + 1];
    }
}

复制代码

2.3.2リンクリストを使用してキューをシミュレートする

public class ChainImitateQueue<T> {
    private Node first;
    private Node last;
    private int n;

    /**
     * 在链表中添加数据
     *
     * @param item
     * @return void
     * @author ZhangSan_Plus
     * @description //TODO
     * @date 17:09 2022/4/15
     **/
    public void addQueue(T item) {
        //在链表尾部插入结点
        Node oldLast = last;
        last = new Node();
        last.item = item;
        last.next = null;
        if (isEmpty()) {
            //队列插入第一个元素
            first = last;
        } else {
            oldLast.next = last;
        }
        n++;
    }

    /**
     * 删除链表中的头数据
     *
     * @param
     * @return T
     * @author ZhangSan_Plus
     * @description //TODO
     * @date 17:10 2022/4/15
     **/
    public T removeQueue() {
        //在链表表头删除结点,(对单链表而言,不好删除表尾结点)
        if (isEmpty()) {
            //删除队列中最后一个元素
            throw new RuntimeException("ERROR: There is no more data in the queue to delete");
        }
        T item = first.item;
        first = first.next;
        n--;
        return item;
    }

    /**
     * 判断列表是否为空
     *
     * @param
     * @return boolean
     * @author ZhangSan_Plus
     * @description //TODO
     * @date 17:10 2022/4/15
     **/
    public boolean isEmpty() {
        return n == 0 ? true : false;
    }

    /**
     * 获取列表的长度
     *
     * @param
     * @return int
     * @author ZhangSan_Plus
     * @description //TODO
     * @date 17:11 2022/4/15
     **/
    public int size() {
        return n;
    }


    class Node {
        Node next;
        T item;
    }

    public static void main(String[] args) {
        ChainImitateQueue<Integer> queue = new ChainImitateQueue<>();
        queue.addQueue(10);
        queue.addQueue(100);
        System.out.println(queue.size());
        System.out.println(queue.removeQueue());
        System.out.println(queue.removeQueue());
        System.out.println(queue.size());
        System.out.println(queue.removeQueue());
    }
}
复制代码

2.4循環キューシミュレーションの実装

おすすめ

転載: juejin.im/post/7087787258555662344