Estructura de datos de Java y tabla de secuencias de algoritmos

        La tabla de secuencia es una estructura lineal en la que los elementos de datos se almacenan secuencialmente en un segmento de unidades de almacenamiento con direcciones físicas consecutivas, generalmente utilizando almacenamiento en matriz. Complete la adición, eliminación, búsqueda y modificación de datos en la matriz. La tabla de secuencias generalmente se puede dividir en: Tabla de secuencias estáticas: utiliza almacenamiento de matriz de longitud fija. Tabla de secuencia dinámica: use almacenamiento de matriz desarrollado dinámicamente. Una tabla de secuencia estática es útil cuando sabe cuántos datos necesita almacenar. La matriz de longitud fija de la tabla de secuencia estática hace que N sea grande, y el espacio es demasiado derrochador, y menos no es suficiente. En contraste, la tabla de secuencia dinámica es más flexible y el tamaño del espacio se asigna dinámicamente. según las necesidades.

A continuación, implementemos una tabla de secuencia dinámica.

Primero, la interfaz a implementar.

 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() { }
}

En segundo lugar, la realización de la interfaz.

        1, construye el marco de la mesa

        Como puede ver en la imagen de arriba, necesitamos crear una matriz (int[] elem) y agregarle elementos nosotros mismos. Al mismo tiempo, también necesita saber el tamaño de la matriz en esta tabla. El tamaño de la matriz lo determina usted mismo. Aquí, asumimos que la capacidad inicial (int IntCapacity) es 10. Aunque hemos abierto una tabla tan grande, no todas las matrices tienen elementos. En este momento, necesitamos saber su tamaño real, que es el tamaño efectivo (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. Tabla de órdenes de impresión

        Primero, imprima la tabla de secuencia. Solo después de la impresión, podemos saber si la implementación de la interfaz posterior es correcta. Al principio, el contenido de la tabla está vacío, por lo que la tabla impresa está naturalmente vacía. Aquí, asumimos que la tabla tiene contenido. Sólo tenemos que atravesar esta mesa y eso es todo. Cabe señalar que para imprimir los elementos válidos en esta tabla, es necesario especificar la condición de terminación del recorrido, ya sea IntCapacity o 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. Agregue un elemento en la posición pos 

        Aquí, tenemos que considerar: 1, ¿cómo lograrlo? 2. ¿Está la posición pos de entrada dentro del rango válido de esta matriz? 3. ¿Estará llena esta matriz? ¿Qué debo hacer cuando esté lleno?

        Primero consideramos cómo implementar este problema. Después de encontrar primero la posición pos, debe mover el elemento hacia adentro, dejando una posición para que se inserte el elemento; de lo contrario, la inserción directa sobrescribirá el contenido de la posición pos. Entonces, para mover el elemento detrás de pos. Cuando se mueva, comience desde el último, de lo contrario, moverse desde la posición pos aún causará el problema de sobrescribir. Una vez hecho esto, deja que usedSize++ lo haga.

        A continuación, considere las preguntas 2 y 3. Para la pregunta 2, pos está dentro del rango válido y se puede operar. Este rango va desde el subíndice 0 hasta usedSizes - 1 subíndice. Una vez fuera de este rango, es ilegal y debe ser advertido. Puede usar excepciones o puede imprimir. Pregunta 3, tenemos que juzgar la situación completa. Al agregar elementos, usedSize (longitud efectiva) se acumula. Cuando se agregan suficientes elementos, usedSize será igual a la capacidad de longitud de la matriz. Aquí está la condición para juzgar si se necesita expansión. Al mismo tiempo, debe tenerse en cuenta que la capacidad inicial no se puede cambiar, por lo que al expandir la capacidad, es necesario copiar la matriz para expandir la capacidad. Use el método copyOf en Arrays para copiar la matriz y expandir la capacidad al mismo tiempo.

    //检查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. Determinar si un elemento está incluido

        Esto solo necesita ser atravesado y luego juzgado.        

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

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

        5. Encuentra la posición correspondiente a un elemento

        Esto solo necesita ser atravesado y luego juzgado. La función de verificación de validez se ha escrito antes y se puede llamar directamente.  

    // 查找某个元素对应的位置
    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. Obtenga el elemento en la posición pos.

        Preguntas a considerar: 1. ¿Cómo encontrar? 2. ¿Legalidad? 3. ¿Está vacía la mesa?

        Anteriormente, escribimos la función para juzgar la validez de pos, y aquí solo necesitamos llamarla. Ahora resolvamos el problema 3. ¿Por qué es necesario determinar si la tabla está vacía? La tabla está vacía, lo que indica que su longitud efectiva es 0, es decir, no hay elementos en ella para devolver, y no hay necesidad de obtenerlos.

    //判断是否为空
    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. Establezca el elemento en la posición pos al valor

        Primero verifique la validez y luego sobrescriba el valor. Debe juzgarse si la mesa está vacía.

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

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

       8. Elimine la primera aparición de la clave de palabra clave 

        Después de la eliminación, deje que la longitud efectiva --.

    //删除第一次出现的关键字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. Obtenga la longitud de la tabla de secuencia

        La longitud de la tabla de secuencia es su longitud efectiva.

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

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

        10. Borrar la tabla de secuencias

        Deje que la longitud efectiva sea 0.

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

        this.usedSize = 0;
    }

3. Todos los códigos y resultados

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();
    }
}

Cuarto, el problema de la tabla de secuencia

1. Inserción y eliminación en el medio/cabeza de la tabla de secuencia, la complejidad del tiempo es O(N)

2. Para aumentar la capacidad, debe solicitar un nuevo espacio, copiar datos y liberar espacio antiguo. Habrá algo de consumo.

3. La expansión de la capacidad es generalmente un aumento de 2 veces, y seguramente habrá una cierta cantidad de espacio desperdiciado. Por ejemplo, la capacidad actual es 100 y la capacidad aumenta a 200 cuando está llena. Continuamos insertando 5 datos y no se insertan datos más tarde, por lo que se desperdician 95 espacios de datos.

Estos problemas requieren una lista enlazada simple para resolverlos. 

Supongo que te gusta

Origin blog.csdn.net/Naion/article/details/122186009
Recomendado
Clasificación