Estructura de datos

         1. Introducción

                  La estructura de datos estudia principalmente los objetos de operación informática que aparecen en la programación no numérica y la relación y funcionamiento entre ellos, etc.

        el término  

        Datos ( Data ): Información     se refiere al término general para todos los símbolos que pueden ingresarse en una computadora y procesarse mediante un programa informático en informática;

                              Por ejemplo, en la representación simbólica de cosas objetivas, en la estructura, el contenido representado en la estructura son datos

        Elemento de datos ( Elemento de datos ) : la unidad básica de datos  

        Elemento de datos ( Data Item ) : Es la unidad más pequeña con significado independiente.El elemento de datos constituye un elemento de datos

         Un elemento de datos puede contener uno o varios elementos de datos. Por ejemplo, una columna en una tabla de base de datos es un elemento de datos y cada fila es un elemento de datos.

        La unidad básica de datos generalmente se considera y procesa como un todo en el programa de cálculo. A veces, un elemento de datos puede estar compuesto por varios elementos de datos; por ejemplo, la información numérica de un libro es un elemento de datos, y la información bibliográfica Cada elemento (título del libro, nombre del autor, etc.) es un elemento de datos, y el elemento de datos es la unidad de datos más pequeña. Hay 10 elementos en la matriz int a[10], y la estructura en su conjunto es un elemento de datos

        Objeto de datos ( Objeto de datos ) : una colección de elementos

Es una colección de elementos de datos con la misma naturaleza y es un subconjunto de datos, 
tales como: objeto de datos enteros N = {0, ±1, ±2, ±3, ...}, objeto de datos de caracteres alfabéticos C = { 'A', 'B', 'C', ..., 'Z'}

       Estructura de datos ( Estructura de datos ) :

                 Es una colección de elementos de datos con una o más relaciones específicas entre ellos (generalmente hay cuatro tipos de estructuras básicas).

                         Conjunto : Los elementos de datos en la estructura no tienen otra relación excepto la relación de "pertenecer al mismo conjunto";

                         Estructura lineal : existe una relación de uno a uno entre los elementos de datos en la estructura. Excepto  el primer elemento, los demás elementos tienen solo un predecesor y, excepto el último elemento, los demás elementos tienen solo un sucesor.

                        Estructura de árbol : existe una relación de uno a muchos entre los elementos de datos en la estructura    , es decir, un elemento tiene solo un predecesor pero puede tener múltiples sucesores

                        Estructura gráfica o de red : los elementos de datos en la estructura tienen una relación de muchos a muchos,    y la relación lógica entre los elementos puede ser arbitraria

                 De lo anterior se puede ver      que una estructura de datos es una colección de elementos de datos con una estructura 

     Tres elementos de la estructura de datos

(1) Estructura lógica : descripción de la relación entre datos, virtual

En forma de estructura lógica se utilizan dos tuplas, B= ( K, R ) , K es un conjunto de nodos, R es un conjunto de relaciones sobre K , por ejemplo < k, k ' > significa que k es el antecesor de k' , y k ' es k El sucesor de , la estructura lógica de los nodos adyacentes        es independiente de la estructura de almacenamiento y la estructura de almacenamiento depende de la estructura lógica

      (1.1) Estructura lineal: solo hay un nodo inicial y un nodo terminal, y todos los nodos tienen como máximo un predecesor directo y un sucesor directo ( 1 a 1 ) . Ejemplos típicos son: lista lineal, pila, cola, matriz, cadena

      (1.2) Estructura no lineal: cada nodo puede tener más de un predecesor directo y un sucesor directo ( no 1 a 1 ) , árboles típicos, gráficos, conjuntos

 (2) Estructura de almacenamiento : la estructura de datos mapeada en la computadora se denomina estructura de almacenamiento y la estructura real    

                             La estructura de almacenamiento es la imagen de la relación lógica y la imagen del elemento mismo, y la estructura de almacenamiento es esencialmente la asignación de memoria.

     Nota: La unidad más pequeña de almacenamiento de información en una computadora se llama bit (bit), 8 bits representan un byte (byte), dos bytes se llaman palabra (palabra) y se pueden llamar bytes, palabras o más bits binarios. una cadena de bits, que se denomina elemento o nodo. Cuando un elemento de datos consta de varios elementos de datos, la cadena de subbits correspondiente a cada elemento de datos en la cadena de bits se denomina campo de datos.

        (2.1) Estructura de almacenamiento secuencial (estructura de almacenamiento secuencial ) : almacene los nodos conectados lógicamente en unidades de almacenamiento físicamente adyacentes, y la relación lógica entre los nodos se refleja en la relación de adyacencia de las unidades de almacenamiento. En general, se utiliza una matriz o una estructura de matriz para describir.  

       (2.2) Estructura de almacenamiento enlazado (LinkedStorage Structure ): no requiere nodos lógicamente adyacentes, son físicamente adyacentes y la relación lógica entre nodos se representa mediante un campo de referencia adicional (puntero). El campo de referencia de un nodo a menudo guía la ubicación de almacenamiento del siguiente nodo. En general, una lista enlazada se utiliza para describir

       (2.3) Método de almacenamiento de índice (índice ) : El método de almacenamiento de índice es un método de almacenamiento que utiliza una tabla de índice adicional para almacenar información de nodo. Una tabla de índice consta de varias entradas de índice. La forma general del elemento de índice en el modo de almacenamiento de índice es ( palabra clave, dirección ) . Entre ellos, la clave es un elemento de datos que puede identificar de forma única un nodo.

      (2.4) Método de almacenamiento hash (hash) : calcule directamente la dirección de almacenamiento del nodo a través de la función hash de acuerdo con la palabra clave del nodo

  (3) Cálculo de datos : algunas operaciones, agregar, eliminar, modificar, verificar

       Tipo de datos ( Tipo de datos ) : tipo

Un término general para un conjunto de valores y un conjunto de operaciones definidas en este conjunto de valores (por ejemplo, una variable entera en lenguaje C cuyo conjunto de valores es un número entero en un cierto intervalo), y las operaciones definidas en él son suma , resta, multiplicación Operaciones aritméticas como operaciones digitales y analógicas), de acuerdo con las diferentes características de "valor", los tipos de datos en lenguajes de programación de alto nivel se pueden dividir en dos categorías

            Tipos atómicos no estructurales : los tipos atómicos no se pueden descomponer, por ejemplo: los tipos básicos de C (tipos enteros, reales, de caracteres y de enumeración), tipos de puntero y tipos vacíos.

           Tipo estructural : El valor de un tipo estructural se compone de varios componentes de acuerdo a una determinada estructura, por lo que se puede descomponer, y sus componentes pueden ser no estructurales o estructurales, por ejemplo: el valor de un arreglo se compone de varios componentes , cada componente A puede ser un número entero, puede ser una matriz, etc. En cierto sentido, una estructura de datos puede considerarse como "un grupo de valores con la misma estructura", y una estructura de datos puede considerarse como un conjunto de datos. estructura y definida sobre ella se compone un conjunto de operaciones.

            Tipo de datos abstractos (Abstract Data Type, ADT) : se refiere a un modelo matemático y un conjunto de operaciones definidas en el modelo. La definición de un tipo de datos abstractos depende solo de su conjunto de características lógicas, en lugar de su representación interna e implementación en la computadora Irrelevante, es decir, no importa cómo cambie su estructura interna, mientras sus características matemáticas permanezcan sin cambios, no afectará su uso externo.

       Tipo de datos abstractos ( Tipo de datos abstractos , ADT ) : modelo, tipo

Un módulo de software que contiene un tipo de datos abstractos generalmente debe contener tres partes : " definición , representación e implementación
" . La definición de un tipo de datos abstractos consiste en un rango de valores y un conjunto de operaciones definidas en el rango de valores. De acuerdo con las diferentes características de su valor, se puede dividir en 3 tipos

           Tipo de datos atómicos (atomic data type) El valor de una variable que pertenece a un tipo atómico no es descomponible. Hay menos tipos de datos abstractos de este tipo, porque en general, los tipos de datos inherentes existentes son suficientes para cumplir con los requisitos, pero a veces es necesario para definir nuevos átomos Tipo de datos, como un número entero cuyo dígito completo es 100;

            tipo de estructura

                     El tipo de datos agregados fijos (tipo de datos agregados fijos) es una variable de este tipo, y su valor se compone de una cierta cantidad de componentes en una determinada estructura. Por ejemplo, un número complejo se compone de dos números reales en una cierta relación de orden.

En comparación con el tipo de agregado fijo, el tipo de fecha de agregado variable (tipo de fecha de agregado variable) tiene un número incierto de componentes que constituyen el "valor" del tipo de agregado variable. Por ejemplo, un tipo de datos abstracto de "entero ordenado secuencia "se puede definir                      , El tipo de agregación fija y el tipo de agregación variable se pueden denominar colectivamente como

            El tipo de datos polimórficos (tipo de datos polimórficos) se refiere al tipo de datos cuya composición de valores es incierta. En el tipo de datos abstractos, independientemente de las características que tengan los elementos, la relación entre los elementos es la misma y las operaciones básicas también son las mismas. Desde el tipo de dato abstracto Desde el punto de vista tiene las mismas características de abstracción matemática, por lo que se denomina tipo de dato polimórfico .

     2. Algoritmo

       1. Concepto

          Algoritmo + estructura de datos = programa , lo que indica que la estructura de datos y el algoritmo son dos elementos principales de un programa, y ​​los dos se complementan entre sí y son indispensables. Los algoritmos son el alma de los programas.

          Algoritmo : Un algoritmo es un método o un proceso para resolver un problema

          Programa : Un programa es una implementación concreta de un algoritmo en un lenguaje de programación.

          Tanto los algoritmos como los programas se usan para expresar pasos lógicos para resolver problemas, pero los algoritmos son independientes de computadoras específicas y no tienen nada que ver con lenguajes de programación específicos, mientras que los programas son todo lo contrario; los programas son algoritmos, pero los algoritmos no son necesariamente programas .

        2. Características del algoritmo

           Finitud : el algoritmo debe terminar después de ejecutar un número finito de pasos, y cada paso debe completarse en un tiempo finito.

           Determinismo : el significado de cada paso en el algoritmo debe ser determinista y no puede ser ambiguo.

           Entradas : un algoritmo puede tener cero o más entradas. 

           Salidas : un algoritmo tiene una o más salidas.

           Viabilidad : un algoritmo debe ser factible, es decir, cada operación en el algoritmo puede realizarse mediante un conjunto conocido de operaciones básicas.

        La representación de una estructura de datos (estructura de almacenamiento) se describe mediante una definición de tipo (typedef). La convención de tipos de elementos de datos es ElemType

       3. Complejidad del tiempo

Tiempo de ejecución del algoritmo: el tiempo de ejecución de un algoritmo es aproximadamente igual a la suma del tiempo de ejecución de todas sus declaraciones El tiempo de ejecución de una declaración se refiere al producto de los tiempos de ejecución de la declaración y el tiempo requerido para una ejecución.

Frecuencia de declaración: se refiere al número de veces que la declaración se ejecuta repetidamente en un algoritmo. La suma de todas las frecuencias de declaración en el algoritmo se registra como T(n) , y la frecuencia de operación básica es f(n) , T(n) =O(f(n)) significa que a medida que aumenta la escala del problema n , la tasa de crecimiento del tiempo de ejecución del algoritmo es la misma que la tasa de crecimiento de f(n) , que se denomina complejidad asintótica del tiempo del algoritmo. , o complejidad del tiempo para abreviar , por lo que la complejidad del tiempo es equivalente a la frecuencia de conteo

La complejidad del tiempo es cuántas veces se llama a la instrucción de ejecución.

La complejidad del tiempo depende del tamaño del problema y del estado inicial de los datos.

Seleccione el elemento con la tasa de crecimiento más rápida en T(n)=O(f(n)) , y el coeficiente debe escribirse como 1. Si f(n) no tiene relación con n, es decir , la frecuencia es una constante , es decir, un número que se pueda expresar claramente , escribe O (1)

Peor complejidad de tiempo y complejidad de tiempo promedio La complejidad de tiempo en el peor de los casos se llama la peor complejidad de tiempo. En general, no se indica específicamente, la complejidad del tiempo discutida es la complejidad del tiempo en el peor de los casos. La razón de esto es: la complejidad del tiempo en el peor de los casos es un límite superior en el tiempo de ejecución del algoritmo en cualquier instancia de entrada, lo que garantiza que el tiempo de ejecución del algoritmo no será más largo que cualquier instancia de entrada. 

regla

T(n)=T1(n)+T2(n)=O(f(n)+g(n))=O( máx (f(n),g(n))

T(n)=T1(n)*T2(n)=O(f(n)*g(n))=O (f(n)*g(n))

El cálculo general de la frecuencia de declaraciones en el ciclo más profundo es la complejidad del tiempo

Complejidad de tiempo común

Recuperación de tiempo común: O(1) <O(log 2 n) < O(n) < O(n log 2 n) < O(n 2 ) < O(n 3 ) < O(2 n ) < O (n !) < O( norte norte )

como calcular la complejidad del tiempo

(1) Si se llama solo una vez, como:
x=5; 
if(x<-4)
{x=x+4;}
else
{x=x+3;}
, solo se realizará una declaración de llamada, entonces O(n)=1;  
(2) Si se llama dos veces, como:
x=5;
if(x<-4)
{x=x+4;}
else
{x=x+3;}
x =x+ 56;
El contenido entre corchetes solo llamará a una declaración, pero al final, todavía hay una fórmula de cálculo para llamar a la declaración; el total se llama 2 veces. Entonces O(n)=2;
(3) Use un ciclo FOR para llamar
for(x=0;x<n;x++)
{x=x+1;}
x realizará un ciclo de 0 a n-1 y ejecutará el declaración Es agregar el valor x actual al nuevo x y llamarlo n veces en total; luego O(n)=n; (4
) usar 2 bucles FOR anidados para llamar
for(x=0;x<n;x++ )
{ para( y=1;y<=n;y++) {x=x+y;} }



Cuando encuentre bucles anidados, primero puede fijar las variables en la declaración FOR externa al valor inicial x = 0, principalmente dependiendo de la complejidad de tiempo de la declaración FOR interna. Obviamente, el número de ejecuciones de la declaración interna es de 1 a n para llamar un total de n veces, O(n)=n; esta es solo la llamada cuando x=0. x puede ir de 0 a n-1, n veces en total. Cada llamada ejecutará n llamadas a y, por lo tanto, ejecute la sentencia x=x+y, se realizarán un total de n*n llamadas. O(n)=n^2.

El número de tiempos de ejecución de la declaración de ejecución es la complejidad del tiempo. Nota:
(1) Encuentre la instrucción de ejecución correcta.
(2) El valor inicial y el valor de terminación en el bucle for .
for(i=0;i<n;i++) El valor de i cambia de 0 a n-1, un total de n veces.
for(i=0;i<=n;i++) El valor de i cambia de 0 a n, un total de n+1 veces.
(3) Preste atención al orden de llamada del ciclo for, desde adentro hacia afuera.

Nota: Visitar el i-ésimo nodo es aleatorio, la complejidad del tiempo es o(1), aquellos que no necesitan ser movidos son o(1) y aquellos que necesitan ser movidos son o(n);

         4. Complejidad espacial 

Con respecto a los requisitos de espacio de almacenamiento del algoritmo, similar a la complejidad de tiempo del algoritmo, usamos la complejidad de espacio como la medida S del espacio de almacenamiento requerido por el algoritmo, que se registra como: S(n)=O( f ( n)) , donde n es la escala del problema, O significa orden de magnitud.

La cantidad de almacenamiento específico que ocupan los datos de entrada solo depende del problema en sí, y no tiene nada que ver con el algoritmo, por lo tanto, solo es necesario analizar el espacio auxiliar requerido para la implementación del algoritmo . Si el espacio auxiliar requerido es constante en relación con los datos de entrada, se dice que el algoritmo funciona en su lugar y el espacio auxiliar es O(1)

          3. Mesa lineal

     1. Definición

Una lista lineal ( Linear_List ) se denomina lista para abreviar : n ( n≥0 ) secuencias   finitas de elementos de datos del mismo tipo , donde n es la longitud de la lista, y cuando n=0, la lista lineal es una lista vacía. Si se usa L para nombrar la tabla lineal, generalmente se expresa de la siguiente manera:     L=(a1, a2, ..., ai, ai+1, ..., an)

Una tabla lineal es la estructura lineal más simple, más básica y más utilizada (una estructura lineal se caracteriza por una relación lineal entre elementos de datos ). Tiene almacenamiento de estructura secuencial y almacenamiento de estructura en cadena , y sus principales operaciones básicas incluyen inserción, eliminación y búsqueda. En una tabla lineal, los tipos de elementos de datos son los mismos, o una tabla lineal es una estructura lineal compuesta por elementos de datos del mismo tipo.

La longitud de la tabla lineal: el número de elementos de datos en la tabla lineal

Lista vacía: una lista lineal con longitud igual a cero

Todo elemento, excepto el primero, tiene un único antecesor directo.

Todo elemento excepto el último tiene uno y sólo un sucesor inmediato.

    2. Características

Identidad : la tabla lineal se compone de elementos de datos similares, y cada a i debe pertenecer al mismo objeto de datos

Finitud : una tabla lineal consta de un número finito de elementos de datos, y la longitud de la tabla es el número de elementos de datos en la tabla

Orden : existe una relación de orden uniforme entre elementos de datos adyacentes en la tabla lineal <a i, a i +1>

  • El número de elementos de la tabla es limitado.
  • Los elementos de la tabla tienen un orden lógico y el orden de cada elemento de la secuencia tiene su propia secuencia.
  • Los elementos de la tabla son todos elementos de datos y cada elemento de la tabla es un único elemento.
  • Los tipos de datos de los elementos de la tabla son todos iguales. Esto significa que cada elemento de la tabla ocupa la misma cantidad de espacio de almacenamiento.

Primer elemento único, último elemento único , cada elemento excepto el primero tiene un predecesor , cada elemento excepto el último tiene un sucesor , cada elemento tiene un orden de bits

Nota: Nota: Una lista lineal es una estructura lógica que representa una relación de adyacencia uno a uno entre elementos. La lista de secuencias y la lista enlazada se refieren a la estructura de almacenamiento , que pertenecen a diferentes niveles de conceptos, así que no los confunda. 

 3. Almacenamiento secuencial de tabla lineal

        El almacenamiento secuencial de la tabla lineal ( Mapeo secuencial , denominado tabla secuencial ) : se refiere al uso de un grupo de unidades de almacenamiento con direcciones continuas para almacenar cada elemento en la tabla lineal en secuencia, de modo que los elementos de datos lógicamente adyacentes en el tabla lineal se almacenan en el adyacente en la unidad de almacenamiento físico.

         Dado que la matriz unidimensional del lenguaje C ocupa un área de almacenamiento con direcciones continuas en la memoria , el núcleo del almacenamiento secuencial es la matriz

         Una tabla lineal con una estructura de almacenamiento secuencial suele denominarse tabla secuencial.

        Suponiendo que hay n elementos en la tabla lineal , cada elemento ocupa k unidades (bytes) y la dirección del primer elemento es loc(a1) , entonces se puede calcular la dirección loc(a i ) del i- ésimo elemento :

                 lugar(ai) = lugar(a 1 )+(i-1)×k

donde loc(a 1 ) se llama la dirección base. Distinguir entre el número de serie del elemento y el subíndice de la matriz, como el número de serie de un 1 es 1 y su subíndice de matriz correspondiente es 0

         Las características de la tabla de secuencia: acceso aleatorio, complejidad de tiempo de búsqueda O (1), eliminar, insertar y mover una gran cantidad de elementos

          Descripción de la estructura de la tabla de secuencias    

               Declaración de un tipo de estructura :

                          lista de estructuras typedef

                             {

                                       ElemType data[MAXSIZE]; // Array almacena elementos de datos     

                                       int length; // La longitud actual de la tabla lineal

                              } SqList , *lista;

Nota: el funcionamiento de la tabla de secuencia

int isEmpty(SqList &L);//判断表是否为空
int getElem(SqList L, int i);//返回第i个位置的值
int listInsert(SqList &L, int i, int e);//在指定位置第i处插入数据e
int listDelete(SqList &L, int i);//删除指定位置的元素
void printList(SqList &L);//打印线性表
int listLength(SqList &L);//求线性表的长度
void initList(SqList &L);//初始化线性表
int locateElem(SqList &L, int x)//返回该值的位置
int destroylist(sqlist &l)//销毁链表

4. Asignación dinámica de la tabla de secuencia

       La tabla de secuencia asignada estáticamente tiene memoria fija, menos asignación de memoria, fácil de desbordar y más asignación de memoria desperdicia memoria, por lo que es mejor asignar dinámicamente, pero aún pertenece a la tabla de secuencia, no a la lista vinculada.

     La función malloc() se usa para asignar dinámicamente espacio de memoria

 Nota: El programa determina la liberación de la asignación estática, y la memoria se libera solo después de que se ejecuta la función principal.

        La liberación de asignación dinámica se libera manualmente, la palabra clave es libre (parámetro);

     La función realloc() se usa para reasignar el espacio de memoria, y su prototipo es: 
        void* realloc (void* ptr, size_t size);

[Descripción del parámetro] ptr es el puntero del espacio de memoria que se reasignará, y size es el tamaño de el nuevo espacio de memoria.

realloc() reasigna el espacio de tamaño a la memoria apuntada por ptr, y el tamaño puede ser mayor o menor que el original, y también puede permanecer sin cambios. Cuando  el espacio de memoria asignado por malloc() y calloc()  no es suficiente, se puede usar realloc() para ajustar la memoria asignada.

Si ptr es NULL, su efecto es el mismo que malloc(), es decir, asigna bytes de tamaño de espacio de memoria.

Si el valor de tamaño es 0, se liberará el espacio de memoria señalado por ptr, pero dado que no se ha abierto ningún espacio de memoria nuevo, se devolverá un puntero nulo; similar a llamar a free(  ) .

Algunos puntos a tener en cuenta:

  • El puntero ptr debe ser un puntero que se haya asignado con éxito en el espacio de memoria dinámica. No se permite un puntero en la siguiente forma: int *i; int a[2]; causará un error de tiempo de ejecución. Simplemente puede recuérdalo así: use malloc(), calloc(), realloc() El puntero asignado con éxito puede ser aceptado por la función realloc().
  • Después de asignar con éxito la memoria, el sistema recuperará ptr y no debe realizar ninguna operación en el puntero de ptr, incluido free(); por el contrario, puede realizar operaciones normales en el valor de retorno de la función realloc().
  • Si la operación es para expandir la memoria, los datos en la memoria señalados por ptr se copiarán en la nueva dirección (la nueva dirección también puede ser la misma que la dirección original, pero aún no puede realizar ninguna operación en el puntero original) ; si la operación es para reducir la memoria, los datos originales se borrarán Copiar y truncar a la nueva longitud.


【Valor devuelto】La asignación tiene éxito y devuelve la nueva dirección de memoria, que puede ser igual o diferente a ptr; si falla, devuelve NULL.

Nota: si la asignación falla, la memoria a la que apunta ptr no se liberará, su contenido no cambiará y aún se puede usar con normalidad.

Suplemento: uso de referencias

       Una referencia es un alias de una variable (objetivo), y la operación sobre la referencia es exactamente la misma que la operación directa sobre la variable. Pertenece a la misma unidad de almacenamiento

 
 Método de declaración de referencia: identificador de tipo y nombre de referencia = nombre de la variable de destino;

[Ejemplo 1]: int a; int &ra=a; //Definimos la referencia ra, que es la referencia de la variable a, es decir, un alias Explicación: (1) & aquí no es un cálculo de dirección, sino

  una

  identificación .

  (2) El identificador de tipo se refiere al tipo de la variable objetivo.

  (3)
Al declarar una referencia, debe inicializarse al mismo tiempo.

  (4) Una vez completada la declaración de referencia, significa que el nombre de la variable de destino tiene dos nombres, es decir, el nombre original del destino y el nombre de referencia, y el nombre de referencia no se puede utilizar como un alias de otros nombres de variables.

   ra=1; es equivalente a a=1;

  
(5) Declarar una referencia no define una nueva variable, solo significa que el nombre de referencia es un alias del nombre de la variable de destino, que en sí mismo no es un tipo de datos, por lo que el la referencia misma No hay ninguna unidad de almacenamiento ocupada y el sistema no asigna unidades de almacenamiento para las referencias. Por lo tanto: encontrar la dirección de la referencia es encontrar la dirección de la variable objetivo. &ra es igual a &a.

  (6) No se puede establecer una referencia a una matriz. Debido a que una matriz es una colección de varios elementos, no es posible crear un alias para una matriz.

Aplicación de referencia

  1. Referencia como parámetro

  Una función importante de referencia es como parámetro de una función
. En el pasado, el paso de parámetros de función en lenguaje C era el paso de valor. Si se pasaba un gran bloque de datos como parámetro, a menudo se usaban punteros, porque esto podía evitar empujar todo el bloque de datos a la pila y mejorar la eficiencia de el programa. Pero ahora (en C) hay una opción igualmente eficiente (y una opción necesaria en algunos casos especiales), es decir, las referencias.


  (1) Pasar una referencia a una función tiene el mismo efecto que pasar un puntero. En este momento, el parámetro formal de la función llamada se usa como un alias de la variable u objeto de parámetro real en la función de llamada original, por lo que la operación en la variable de parámetro formal en la función llamada es el objeto de destino correspondiente (en el principal función de llamada) función de llamada) operación.

  (2) Los parámetros de la función se pasan por referencia, y no se genera una copia del parámetro real en la memoria, se opera directamente en el parámetro real; mientras que los parámetros de la función se pasan por la variable general, cuando el ocurre una llamada de función, el almacenamiento debe asignarse al parámetro formal Unidad, la variable de parámetro formal es una copia de la variable de parámetro real; si se pasa un objeto, también se llamará al constructor de copia . Por tanto, cuando los datos que pasa el parámetro son grandes, la eficiencia y el espacio que ocupa la referencia son mejores que los de la variable general.

  (3) Aunque usar un puntero como parámetro de función también puede lograr el efecto de usar una referencia, en la función llamada, la unidad de almacenamiento también debe asignarse al parámetro formal, y la operación en forma de "*nombre de variable de puntero " debe repetirse. Esto es propenso a errores y la legibilidad del programa es deficiente; por otro lado, en el punto de llamada de la función de llamada, la dirección de la variable debe usarse como un parámetro real. Las referencias, por otro lado, son más fáciles de usar y más claras.

  Si desea usar referencias para mejorar la eficiencia del programa y proteger los datos pasados ​​a la función para que no se modifiquen en la función, debe usar referencias constantes.

  2.

  Referencias comunes El método de declaración de referencias comunes: identificador de tipo const & nombre de referencia = nombre de la variable de destino,

  las referencias declaradas de esta manera no pueden modificar el valor de la variable de destino a través de la referencia, por lo que el destino de la referencia se convierte en const, logrando Citation seguridad.

  La razón es que las cadenas foo() y "hello world" generan un objeto temporal y, en C, estos objetos temporales son de tipo const. Entonces, la expresión anterior está tratando de convertir un objeto de tipo const en un tipo que no es const, lo cual es ilegal.

  Los parámetros de referencia deben definirse como const tanto como sea posible si se pueden definir como const.

  3. Referencia como valor devuelto Para

  devolver un valor de función por referencia, la definición de función debe seguir el siguiente formato:

identificador de tipo y nombre de función (lista de parámetros formales y descripción de tipo)
{cuerpo de función}

  Descripción:

  (1) Devolver valor de función por referencia , al definir una función, debe agregar & antes del nombre de la función

  (2) La mayor ventaja de devolver un valor de función por referencia es que no se genera una copia del valor devuelto en la memoria.

  Las referencias como valores de retorno deben cumplir con las siguientes reglas:

  (1) No se pueden devolver referencias a variables locales. Este artículo puede referirse al Punto 31 de la Vigencia C [1]. La razón principal es que las variables locales se destruirán después de que la función regrese, por lo que la referencia devuelta se convierte en una referencia "nada" y el programa entrará en un estado desconocido.

  (2) No se puede devolver una referencia a la memoria asignada por new dentro de la función. Este artículo puede referirse al Punto 31 de la Vigencia C [1]. Aunque no hay problema de destrucción pasiva de variables locales, pero por esta situación (devolviendo una referencia a la memoria asignada por new dentro de la función), se enfrenta a otras situaciones embarazosas. Por ejemplo, la referencia devuelta por la función solo aparece como una variable temporal sin que se le asigne una variable real, luego el espacio al que apunta la referencia (asignado por new) no se puede liberar, lo que provoca una pérdida de memoria.

  (3) Se puede devolver una referencia a un miembro de la clase, pero preferiblemente constante. Este principio puede referirse al artículo 30 de la Vigencia C [1]. La razón principal es que cuando el atributo de un objeto se asocia con una determinada regla de negocio, su asignación suele estar relacionada con algunos otros atributos o el estado del objeto, por lo que es necesario encapsular la operación de asignación en una regla de negocio. Si otros objetos pueden obtener una referencia no constante (o puntero) a la propiedad, entonces una mera asignación a la propiedad rompería la integridad de las reglas comerciales.
  4. Referencias y polimorfismo

  Las referencias son otro medio además de los punteros que pueden producir efectos polimórficos. Esto significa que una referencia a una clase base puede apuntar a una instancia de su clase derivada.

  [Ejemplo 7]:

clase A;
clase B: public A{...};
B b;
A &Ref = b; // usar el objeto de clase derivado para inicializar la referencia

  Ref del objeto de clase base solo se puede usar para acceder el objeto de clase derivado de la base Los miembros heredados de una clase son referencias de clase base que apuntan a clases derivadas. Si hay una función virtual definida en la clase A, y esta función virtual se reescribe en la clase B, se pueden generar efectos polimórficos a través de la Ref.

  Resumen de referencias

  (1) En el uso de referencias, no tiene sentido dar simplemente un alias a una variable. El propósito de las referencias se utiliza principalmente en la transferencia de parámetros de función para resolver el problema de la eficiencia de transferencia insatisfactoria y el espacio de grandes bloques de pregunta sobre datos u objetos.

  (2) Pasar los parámetros de la función por referencia puede garantizar que no se genere ninguna copia durante la transferencia de parámetros, lo que mejora la eficiencia de la transferencia y, mediante el uso de const, se garantiza la seguridad de la transferencia de referencia.

    5. Lista enlazada

  1. Interpolación de encabezado: el orden de inserción es opuesto al orden en la lista enlazada
  2. Método de inserción de cola: el orden de inserción es el mismo que el orden en la lista enlazada

        ( 1) Características

          El orden lógico y el orden físico no son necesariamente lo mismo, la memoria física no requiere una relación lógica continua entre elementos expresados ​​por punteros

        (2) nodo

         Para representar correctamente la relación lógica entre nodos, es necesario almacenar la información de dirección (o posición) que indica su nodo sucesor mientras se almacena el valor de cada elemento de datos en la tabla lineal.La imagen de almacenamiento compuesta por estas dos partes de información se llama nodo.punto ( Nodo )

        (3) Lista enlazada simple

            lista única

Supongo que te gusta

Origin blog.csdn.net/Wang_kang1/article/details/82966533
Recomendado
Clasificación