Javaデータ構造とアルゴリズムシーケンステーブル

        シーケンステーブルは、データ要素が連続した物理アドレスを持つストレージユニットのセグメントに順次格納される線形構造であり、通常は配列ストレージを使用します。アレイでの完全なデータの追加、削除、検索、および変更。シーケンステーブルは、一般的に次のように分割できます。静的シーケンステーブル:固定長の配列ストレージを使用します。動的シーケンステーブル:動的に開発された配列ストレージを使用します。静的シーケンステーブルは、保存する必要のあるデータの量がわかっている場合に役立ちます。静的シーケンステーブルの固定長配列により、Nが大きくなり、スペースが無駄になり、少ないだけでは不十分です。対照的に、動的シーケンステーブルはより柔軟で、スペースのサイズが動的に割り当てられます。必要に応じて。

次に、動的シーケンステーブルを実装しましょう。

まず、実装するインターフェース

 public class SeqList {
 
    // 打印顺序表 
    public void display() { }
 
    // 在 pos 位置新增元素 
    public void add(int pos, int data) { }
 
    // 判定是否包含某个元素 
    public boolean contains(int toFind) { return true; }
 
    // 查找某个元素对应的位置 
    public int search(int toFind) { return -1; }
 
    // 获取 pos 位置的元素 
    public int getPos(int pos) { return -1; }
 
    // 给 pos 位置的元素设为 value 
    public void setPos(int pos, int value) { }
 
    //删除第一次出现的关键字key 
    public void remove(int toRemove) { } 

    // 获取顺序表长度 
    public int size() { return 0; } 

    // 清空顺序表 
    public void clear() { }
}

第二に、インターフェースの実現

        1、テーブルのフレームを作成します

        上の図からわかるように、配列(int [] elem)を作成し、自分で要素を追加する必要があります。同時に、このテーブルの配列のサイズも知っておく必要があります。配列のサイズは自分で決定します。ここでは、初期容量(int IntCapacity)を10と仮定します。このような大きなテーブルを開きましたが、すべての配列に要素が含まれているわけではありません。このとき、有効サイズ(int usedSize)である実際のサイズを知る必要があります。

    public int[] elem;
    //有效的数据个数
    public int usedSize;
    //初始容量,且不能被改变
    public static final int intCapacity = 10;


    //创建对象并调用合适的构造方法
    public MyArrayList() {
        //创建一个初始容量为10个大小的数组对象
        this.elem = new int[intCapacity];
        this.usedSize = 0;
    }

       2.注文表を印刷する

        まず、シーケンステーブルを印刷します。印刷して初めて、後続のインターフェイスの実装が正しいかどうかを知ることができます。最初は、テーブルの内容が空であるため、印刷されたテーブルは自然に空になります。ここでは、テーブルにコンテンツがあると想定しています。このテーブルをトラバースする必要があります。それだけです。このテーブルの有効な要素を出力するには、IntCapacityであるかusedSizeであるかにかかわらず、トラバーサルの終了条件を指定する必要があることに注意してください。

// 打印顺序表
    public void display() {

        int i  = 0;
        for(i = 0; i < this.usedSize; i++) {
            System.out.print(this.elem[i] + " ");
        }
        System.out.println();
        //System.out.print(Arrays.toString(this.elem));
    }

       3.位置に要素を追加します 

        ここでは、次のことを考慮する必要があります。1、どのように達成するか。2.入力位置はこの配列の有効範囲内にありますか?3.このアレイはいっぱいになりますか?いっぱいになったらどうすればいいですか?

        まず、この問題を実装する方法を検討します。最初に位置位置を見つけたら、要素を内側に移動して、要素を挿入する位置を残す必要があります。そうしないと、直接挿入すると位置位置の内容が上書きされます。したがって、要素をposの後ろに移動します。移動するときは、最後の位置から始めてください。そうしないと、posの位置から移動すると、上書きされる問題が発生します。完了したら、usedSize++に実行させます。

        次に、質問2と3について考えます。質問2の場合、posは有効範囲内であり、操作できます。この範囲は、添え字0からusedSizes-1添え字までです。この範囲から外れると、違法であり、警告する必要があります。例外を使用することも、印刷することもできます。質問3、私たちは完全な状況を判断する必要があります。要素を追加すると、usedSize(有効長)が累積されます。十分な数の要素が追加されると、usedSizeは配列の容量の長さに等しくなります。ここに、拡張が必要かどうかを判断するための条件があります。同時に、初期容量は変更できないため、容量を拡張する場合は、アレイをコピーして容量を拡張する必要があります。配列のcopyOfメソッドを使用して、配列をコピーし、同時に容量を拡張します。

    //检查pos位置合法性
    private void checkPos(int pos) {

        if(pos < 0 || pos > this.usedSize) {
            throw new RuntimeException("pos位置不合法!");
        }
    }

    //检查数组是否满的情况
    private boolean isFull() {

        if(this.elem.length == this.usedSize) {
            return true;
        }
        return false;
    }

    // 在 pos 位置新增元素
    public void add(int pos, int data) {

        //pos位置合法性
        checkPos(pos);
        //检查数组是否满了
        if(isFull()) {
            this.elem = Arrays.copyOf(this.elem, 2 * this.elem.length);
        }
        //新增元素
        for(int i = this.usedSize - 1; i >= pos; i--) {
            this.elem[i + 1] = this.elem[i];
        }
        this.elem[pos] = data;
        this.usedSize++;
    }

        4.要素が含まれているかどうかを確認します

        これは、トラバースしてから判断する必要があるだけです。        

// 判定是否包含某个元素
    public boolean contains(int toFind) {

        for(int i = 0; i < this.usedSize; i++) {
            if(this.elem[i] == toFind) {
                return true;
            }
        }
        return false;
    }

        5.要素に対応する位置を見つけます

        これは、トラバースしてから判断する必要があるだけです。妥当性チェック関数は以前に作成されており、直接呼び出すことができます。  

    // 查找某个元素对应的位置
    public int search(int toFind) {

        //合法性检查
        checkPos(toFind);
        for(int i = 0; i < this.usedSize; i++) {
            if(this.elem[i] == toFind) {
                return i;
            }
        }
        return -1;
    }

      6.位置にある要素を取得します

        考慮すべき質問:1。見つける方法は?2.合法性?3.テーブルは空ですか?

        以前、posの有効性を判断する関数を作成しましたが、ここではそれを呼び出すだけで済みます。それでは、問題3を解決しましょう。テーブルが空かどうかを判断する必要があるのはなぜですか?テーブルは空であり、有効な長さが0であることを示しています。つまり、テーブルに返す要素がなく、それらを取得する必要がないことを示しています。

    //判断是否为空
    private boolean isEmpty() {
        return this.usedSize == 0;
    }

    // 获取 pos 位置的元素
    public int getPos(int pos) {

        //表是否为空
        if (isEmpty()) {
            //也可以进行打印
            throw new RuntimeException("表为空!");
        }
        //检查合法性
        if(pos < 0 || pos >= this.usedSize) {
            throw new RuntimeException("pos位置不合法!");
        }
        //获取元素
        return this.elem[pos];
    }

        7.位置の要素を値に設定します

        最初に有効性を確認してから、値を上書きします。テーブルが空かどうかを判断する必要があります。

    // 给 pos 位置的元素设为 value
    public void setPos(int pos, int value) {

        checkPos(pos);
        if(isFull()) {
            throw new RuntimeException("表为空!");
        }
        this.elem[pos] = value;
    }

       8.キーワードキーの最初の出現を削除します 

        削除後、有効長を-にします。

    //删除第一次出现的关键字key
    public void remove(int toRemove) {

        int pos = search(toRemove);
        if(pos == -1) {
            System.out.println("未找到该值!");
            return;
        }
        for(int i = pos; i < this.usedSize - 1; i++) {
            this.elem[i] = this.elem[i + 1];
        }
        this.usedSize--;
    }

        9.シーケンステーブルの長さを取得します

        シーケンステーブルの長さは、その有効な長さです。

    // 获取顺序表长度
    public int size() {

        if (!isEmpty()) {
            return this.usedSize;
        }
        return 0;
    }

        10.シーケンステーブルをクリアします

        有効長を0とします。

    // 清空顺序表
    public void clear() {

        this.usedSize = 0;
    }

3.すべてのコードと結果

import java.util.Arrays;

/**
 * @author: Naion
 * @create: 2021-12-26 14:56
 **/

public class MySeqlist {

    //定义一个顺序表
    private int[] elem;
    private int usedSize;
    private int intCapacity = 10;

    //调用合适的构造方法
    public MySeqlist() {
        //定义大小
        this.elem = new int[intCapacity];
        this.usedSize = 0;
    }

    // 打印顺序表
    public void display() {

        int i = 0;
        for(i = 0; i < this.usedSize; i++) {
            System.out.print(this.elem[i] + " ");
        }
        System.out.println();
    }

    //检查pos位置合法性
    private void checkPos(int pos) {

        if(pos < 0 || pos > this.usedSize) {
            throw new RuntimeException("pos位置不合法!");
        }
    }

    //检查数组是否满的情况
    private boolean isFull() {

        if(this.elem.length == this.usedSize) {
            return true;
        }
        return false;
    }

    // 在 pos 位置新增元素
    public void add(int pos, int data) {

        //pos位置合法性
        checkPos(pos);
        //检查数组是否满了
        if(isFull()) {
            this.elem = Arrays.copyOf(this.elem, 2 * this.elem.length);
        }
        //新增元素
        for(int i = this.usedSize - 1; i >= pos; i--) {
            this.elem[i + 1] = this.elem[i];
        }
        this.elem[pos] = data;
        this.usedSize++;
    }

    // 判定是否包含某个元素
    public boolean contains(int toFind) {

        for(int i = 0; i < this.usedSize; i++) {
            if(this.elem[i] == toFind) {
                return true;
            }
        }
        return false;
    }

    // 查找某个元素对应的位置
    public int search(int toFind) {

        //合法性检查
        checkPos(toFind);
        for(int i = 0; i < this.usedSize; i++) {
            if(this.elem[i] == toFind) {
                return i;
            }
        }
        return -1;
    }

    //判断是否为空
    private boolean isEmpty() {
        return this.usedSize == 0;
    }

    // 获取 pos 位置的元素
    public int getPos(int pos) {

        //表是否为空
        if (isEmpty()) {
            throw new RuntimeException("表为空!");
        }
        //检查合法性
        if(pos < 0 || pos >= this.usedSize) {
            throw new RuntimeException("pos位置不合法!");
        }
        //获取元素
        return this.elem[pos];
    }

    // 给 pos 位置的元素设为 value
    public void setPos(int pos, int value) {

        checkPos(pos);
        if(isFull()) {
            throw new RuntimeException("表为空!");
        }
        this.elem[pos] = value;
    }

    //删除第一次出现的关键字key
    public void remove(int toRemove) {

        int pos = search(toRemove);
        if(pos == -1) {
            System.out.println("未找到该值!");
            return;
        }
        for(int i = pos; i < this.usedSize - 1; i++) {
            this.elem[i] = this.elem[i + 1];
        }
        this.usedSize--;
    }

    // 获取顺序表长度
    public int size() {

        if (!isEmpty()) {
            return this.usedSize;
        }
        return 0;
    }
    // 清空顺序表
    public void clear() {

        this.usedSize = 0;
    }
}
/**
 * @author: Naion
 * @create: 2021-12-26 14:55
 **/

public class test_12_26_01 {

    public static void main(String[] args) {

        MySeqlist myseqlist = new MySeqlist();
        for(int i = 0; i < 10; i++) {
            myseqlist.add(i, i);
        }
        myseqlist.display();
        System.out.println("======");
        myseqlist.add(1, 3);
        myseqlist.display();
        System.out.println("======");
        System.out.println(myseqlist.contains(3));
        System.out.println("======");
        System.out.println(myseqlist.search(3));
        System.out.println("======");
        System.out.println(myseqlist.getPos(1));
        System.out.println("======");
        myseqlist.setPos(1, 0);
        myseqlist.display();
        System.out.println("======");
        myseqlist.remove(0);
        myseqlist.display();
        System.out.println("======");
        System.out.println(myseqlist.size());
        System.out.println("======");
        myseqlist.clear();
        myseqlist.display();
    }
}

第四に、シーケンステーブルの問題

1.シーケンステーブルの中央/先頭での挿入と削除。時間計算量はO(N)です。

2.容量を増やすには、新しいスペースを申請し、データをコピーして、古いスペースを解放する必要があります。多少の消費があります。

3.容量の拡張は、通常2倍になり、ある程度のスペースデブリが発生します。たとえば、現在の容量は100で、容量がいっぱいになると容量は200に増加します。引き続き5つのデータを挿入し、後でデータを挿入しないため、95のデータスペースが無駄になります。

これらの問題を解決するには、単一リンクリストが必要です。 

おすすめ

転載: blog.csdn.net/Naion/article/details/122186009
おすすめ