Galería de mapas mentales tabla lineal de estructura de datos
Estructura de datos Capítulo 2 Mapa mental de tabla lineal: 1. Definición y operaciones básicas de una tabla lineal Una tabla lineal es una secuencia finita de n elementos de datos con el mismo tipo de datos. , 2. Representación secuencial de listas lineales (listas secuenciales), 3. Representación encadenada de listas lineales, etc.
Editado a las 2022-03-31 18:41:13,Este es un mapa mental sobre una breve historia del tiempo. "Una breve historia del tiempo" es una obra de divulgación científica con una influencia de gran alcance. No sólo presenta los conceptos básicos de cosmología y relatividad, sino que también analiza los agujeros negros y la expansión. del universo. temas científicos de vanguardia como la inflación y la teoría de cuerdas.
¿Cuáles son los métodos de fijación de precios para los subcontratos de proyectos bajo el modelo de contratación general EPC? EPC (Ingeniería, Adquisiciones, Construcción) significa que el contratista general es responsable de todo el proceso de diseño, adquisición, construcción e instalación del proyecto, y es responsable de los servicios de operación de prueba.
Los puntos de conocimiento que los ingenieros de Java deben dominar en cada etapa se presentan en detalle y el conocimiento es completo, espero que pueda ser útil para todos.
Este es un mapa mental sobre una breve historia del tiempo. "Una breve historia del tiempo" es una obra de divulgación científica con una influencia de gran alcance. No sólo presenta los conceptos básicos de cosmología y relatividad, sino que también analiza los agujeros negros y la expansión. del universo. temas científicos de vanguardia como la inflación y la teoría de cuerdas.
¿Cuáles son los métodos de fijación de precios para los subcontratos de proyectos bajo el modelo de contratación general EPC? EPC (Ingeniería, Adquisiciones, Construcción) significa que el contratista general es responsable de todo el proceso de diseño, adquisición, construcción e instalación del proyecto, y es responsable de los servicios de operación de prueba.
Los puntos de conocimiento que los ingenieros de Java deben dominar en cada etapa se presentan en detalle y el conocimiento es completo, espero que pueda ser útil para todos.
Capítulo 2 Tabla lineal
1. Definición y operaciones básicas de tablas lineales.
Definición de tabla lineal
Una tabla lineal es una secuencia finita de n elementos de datos del mismo tipo de datos.
Concepto: elemento de cabecera, elemento de cola, antecesor directo, sucesor directo.
Operaciones básicas de tablas lineales.
Establecer InitList(&L) es inicializar y destruir DestroyList(&L) Agregue ListInsert(&L,i,e) para insertar EliminarListaEliminar(&L,i,e) ComprobarLocateElem(L,e),GetElem(L,e) Longitud (L) longitud de la tabla, salida PrintList (L), vacío (juicio vacío)
2. Representación secuencial de tablas lineales (tablas secuenciales)
Definición de tabla de secuencia
Implementar tablas lineales utilizando almacenamiento secuencial; Almacenamiento secuencial: Almacene elementos lógicamente adyacentes en unidades de almacenamiento que también sean físicamente adyacentes. La relación se refleja en la relación de adyacencia de las unidades de almacenamiento.
Implementación de tabla de secuencia.
asignación estática
// La asignación estática define la tabla de secuencia. El espacio de almacenamiento es estático y el tamaño se fija desde el principio. #define MaxSize 10//Definir la longitud máxima estructura typedef { ElemType data[MaxSize]; //Utiliza una "matriz" estática para almacenar elementos de datos int length; //Longitud actual de la tabla de secuencia }SqList; // Definición de tipo de lista de secuencia (método de asignación estática) ElemType se refiere al tipo de datos definido por usted mismo, como int, double //Tabla de secuencia de inicialización #incluir<stdio.h> #definir tamaño máximo10 estructura typedef { int datos[MaxSize]; longitud interna; }ListaCuad; void ListaInit(SqList &L){ para(int i=0;i<MaxSize;i) L.data[i]=0; //Establece todos los elementos de datos a los valores iniciales predeterminados L.length=0; //Establece la longitud inicial de la tabla de secuencia en 0 } int principal(){ SqList L; //Declarar una lista de secuencia InitList(L): //Lista de secuencia de inicialización ... devolver 0; } // Tabla de secuencia de implementación de asignación dinámica, el tamaño se puede cambiar #incluir<stiod.h> #define InitSize 10 //Longitud máxima predeterminada estructura typedef { int *data; //Puntero que indica una matriz asignada dinámicamente int MaxSize; //Capacidad máxima de la tabla de secuencia int length; //Longitud actual de la tabla de secuencia }SeqList; //Definición de lista de secuencias int principal(){ SeqList L; //Declarar una lista de secuencia ListaInit(L): //Inserta varios elementos aleatoriamente en la tabla de secuencia de la red AumentarTamaño(L,5); devolver 0; } void ListaInit(ListaSeq &L){ //Utiliza la función malloc para solicitar un espacio de almacenamiento continuo L.data(int *)malloc(InitSize*sizeof(int)); L.longitud=0; L.MaxSize=InitSize; } //Aumentar la longitud de la matriz dinámica void AumentarTamaño(SeqList &L,int len){ int *p=L.datos; L.data(int *)malloc((L.MaxSize len)*sizeof(int)): for(int i=0;i<L.length;i ){ L.data[i]=p[i]; //Copiar datos a una nueva área } L.MaxSize=L.MaxSize len; //La longitud máxima de la tabla de secuencia aumenta en len; free(p); //Libera el espacio de memoria original }
asignación dinámica
L.data=(ElemType *)malloc(tamaño de ElemType *InitSize) La función malloc devuelve un puntero, que debe convertirse en un puntero al tipo de elemento de datos que definió.
Características de las tablas de secuencia: ① Acceso aleatorio ②Alta densidad de almacenamiento ③Es inconveniente ampliar la capacidad. ④ Las operaciones de inserción y eliminación son inconvenientes y requieren mover una gran cantidad de elementos
Inserción y eliminación de tabla de secuencia.
Inserción en tabla de secuencia.
ListInsert(&L,I,e), inserta el elemento especificado e en la i-ésima posición
//Inserción secuencial de elementos de tabla #definir tamaño máximo 10 estructura typedef { Datos ElemType[MaxSize]; longitud interna; }ListaCuad; void ListInsert(SqList &L,int I,int e){ for(int j=L.length;j>I;j--){ //Mover el elemento i-ésimo y los elementos subsiguientes hacia atrás L.datos[j]=L.datos[j-1]; } L.data[i-1]=e; //Coloca e en la i-ésima posición L.longitud; //Longitud 1 } int principal(){ ListaSq L; ListaInit(L): //Omitido aquí, puedes insertar una serie de elementos. ListaInsertar(L,3,3); devolver 0; } // Para evitar insertar elementos sin retroalimentación, por ejemplo, si la memoria está llena, se debe modificar la función Insertar para que tenga un valor de retorno. bool ListInsert(SqList &L,int I,int e){ si(i<1 || i>L.longitud 1) falso retorno; si(L.longitud>=MaxSize) falso retorno; para(int j=L.length;j>i;j--) L.datos[j]=L.datos[j-1]; L.datos[i-1]=e; L.longitud; falso retorno; }
Complejidad temporal de la inserción: mejor O(1), peor O(n), promedio O(n)
Eliminación de la tabla de secuencia.
ListDelete(SqList &L,int i,int &e), elimina el elemento en la posición i en la tabla L y devuelve el valor del elemento
//Eliminar tabla de secuencia bool ListDelete(SqList &L,int i,int &e){ if(i<1 || i>L.length 1) //Determina si el rango de i es válido falso retorno; e=L.datos[i-1]; para(int j=1;j<L.length;j) L.datos[j-1]=L.datos[j]; L.longitud--; devolver verdadero; } int principal(){ ListaSq L; ListaInit(L); int e=-1; si(ListDelete(L,3,e)) printf("Eliminar el tercer elemento, el valor del elemento eliminado es =%d/n",e); demás pprintf("El orden de bits i es ilegal, la eliminación falló "); devolver 0; }
Complejidad temporal de la eliminación: O(1) en el mejor de los casos, O(n) en el peor, O(n) en promedio
Búsqueda de tabla de secuencia
búsqueda bit a bit
GetElem(L,i), obtiene el valor del elemento en la i-ésima posición en la tabla L
//Buscar por bit //Asignación estática #definir tamaño máximo estructura typedef { ElemType data[MaxSize]; //Utiliza una "matriz" estática para almacenar elementos de datos int length; //Longitud actual de la tabla de secuencia }SqList; // Definición de tipo de lista de secuencia (método de asignación estática) ElemType GetElem(SqList L,int i){ return L.data[i-1]; //Llama a la función GetElem() para devolver el valor del i-ésimo elemento } //Asignación dinámica #definirtamañoinicial estructura typedef { TipoElem *datos; int Tamaño máximo; longitud interna; }ListaSeq; ElemType GetElem(SeqList L,int i){ devolver L.datos[i-1]; }
Buscar por valor
LocateElem(L,e), encuentra el elemento con el valor de palabra clave dado en la tabla L
//Buscar por valor #defineInitSize 10 estructura typedef { TipoElem *datos; int Tamaño máximo; longitud interna; }ListaSeq; //Encuentra el elemento cuyo valor del primer elemento es igual a e en la lista de secuencia L y devuelve su orden de bits int LocalizarElem(SeqList L,ElemType e){ para(int i=0;i<L.longitud,i) si(int i=0;o<L.length;i) return i 1; // El valor del elemento marcado i en la matriz es igual a e y su orden de bits se devuelve i 1 return 0; //Salir del ciclo, indicando que la búsqueda falló }
Complejidad del tiempo: mejor O (1), peor O (n), promedio O (n)
Comparación de tipos de estructuras
3. Representación en cadena de una tabla lineal.
lista única
Definición de lista enlazada individualmente
Además de almacenar elementos de datos, cada nodo también almacena un puntero al siguiente nodo.
Representación de código de lista enlazada única
estructura LNodo{ datos ElemType; //Definir el tipo de nodo de lista enlazada única struct LNode *next;//Cada nodo almacena un elemento de datos } struct LNode *p=(struct LNode *)malloc(sizeof(struct LNode)); // Cada vez que se agrega un nuevo nodo, solicita un espacio de nodo en la memoria y usa el puntero p para apuntar a este nodo. También puedes usar typedef struct LNode LNode; en lugar de LNode *p=(LNode *)maloc(sizeof(LNode));
// Libro de texto, define una lista enlazada individualmente typedef struct LNode{} //Definir el tipo de nodo de lista enlazada única datos ElemType; //campo de datos struct LNode *siguiente; //campo de puntero LNode,*LinkList; //Se cambia el nombre de LNode, *LinkList es el puntero a este nodo. Utilice LNode * para enfatizar que se trata de un nodo. Utilice LinkList para enfatizar que se trata de una lista enlazada individualmente
Dos implementaciones
nodo líder
//Lista enlazada individualmente con nodo principal estructura typedef LNode{ datos de tipo elemento; puntal LNode *siguiente; }LNodo,*ListaEnlaces; //Inicializa una lista enlazada individualmente vacía bool ListaInit(ListaEnlaces &L){ L=NULL; //Tabla vacía, coloca datos sucios devolver verdadero; } prueba nula(){ LinkList L; //Declarar un puntero a una lista enlazada individualmente //Inicializa una tabla vacía ListaInit(L); //....Código posterior } //Determinar si la lista enlazada individualmente está vacía bool Vacío(ListaEnlaces L){ retorno (L=NULL); }
Sin nodo principal
//Lista enlazada individualmente sin nodo principal estructura typedef LNode{ datos de tipo elemento; estructura LNode *siguiente; }LNodo,*ListaEnlaces; //Inicializa una lista enlazada individualmente con nodos de encabezado bool ListaInit(ListaEnlaces &L){ L=(LNode *)malloc(sizeof(LNode));//Asignar un nodo principal si(L==NULL) falso retorno; L->siguiente=NULL; devolver verdadero; } prueba nula(){ LinkList L; //Declarar un puntero a una lista enlazada individualmente //Inicializa una tabla vacía ListaInit(L); //...Siguiente código } //Determinar si la lista enlazada individualmente está vacía (con encabezado) bool Vacío(ListaEnlaces L){ si(L->siguiente==NULL) devolver verdadero; demás falso retorno; }
Inserción y eliminación de lista enlazada individualmente.
insertar
Insertar en orden de bits
//Inserta el elemento e (nodo principal) en la i-ésima posición en orden de bits ListInsert(&L,int i,ElemType e){ si(yo<1) falso retorno; LNode *p; //El puntero p apunta al nodo actualmente escaneado int j=0; // ¿A qué nodo apunta la p actual? p=L; //L apunta al nodo principal, que es el nodo 0 (no se almacenan datos) while(p!=NULL&&j<i-1){ //Bucle para encontrar el nodo i-1 p=p->siguiente; j; } if(p=NULL) //El valor de i es ilegal falso retorno; LNode *s =(LNode *)malloc(sizeof(LNode));//Solicite un nuevo espacio de nodo para almacenar nuevos elementos s->data=e; //El campo de datos del nuevo nodo almacena el contenido del nuevo elemento s->next=p->next; // El siguiente puntero del nuevo nodo apunta al siguiente puntero señalado por el nodo i-1, que se denomina elemento i-ésimo. p->next=s; //El nodo anterior al lado del nuevo nodo apunta al nuevo nodo devolver verdadero; } estructura typedef LNode{ datos de tipo elemento; estructura LNode *siguiente; }LNodo,*ListaEnlaces;
//// Inserte el elemento e en la i-ésima posición en orden de bits (sin el nodo principal) bool ListInsert(ListaEnlaces &L,int i,ElemType e){ si(yo<1) falso retorno; if(i==1){ // La operación de inserción en el primer nodo es diferente de la operación de otros nodos LNodo *s=(LNodo *)malloc(tamañode(LNodo)); s->datos=e; s->siguiente=L; L=s; //El puntero principal apunta al nuevo nodo devolver verdadero; } LNodo *p; intj=1; p=L; mientras(p!=NULL && j<i-1){ p=p->siguiente; j; } si(p==NULL) falso retorno; s->datos=e; s->siguiente=p->siguiente; p->siguiente=s; return verdadero; //Inserción exitosa } estructura typedef LNode{ datos de tipo elemento; estructura LNode *siguiente; }LNodo,*ListaEnlaces;
Operación posterior a la inserción del nodo especificado
// Operación posterior a la inserción, inserte el elemento e después del nodo p bool InsertNextNode(LNode *p,ElemType e){ si(p==NULL) LNodo *s=(LNodo *)malloc(tamañode(LNodo)); if(s==NULL) //Asignación de memoria insuficiente falso retorno; s->data=e; //Utiliza el nodo s para guardar el elemento de datos e s->siguiente=p->siguiente; p->next=s; //Conectar el nodo s después de p devolver verdadero; } estructura typedef LNode{ datos de tipo elemento; estructura LNode *siguiente; }LNodo,*ListaEnlaces;
Operación de inserción directa del nodo especificado
InsertPriorNode (LinkList L, LNode * p, ElemType e), dado el nodo principal, luego recorra toda la tabla para encontrar el nodo anterior de p. Por conveniencia, copie directamente este nodo y cambie el contenido de este nodo, lo que hace que el tiempo. complicado. El grado es O (n)
// Operación de inserción directa, inserte el nodo s antes del nodo p bool InsertarNodoPrior(LNodo *p,LNodo *s){ si(p==NULL || s==NULL) falso retorno; s->siguiente=p->siguiente; p->siguiente=s; ElemType temp=p->datos; p->datos=s->datos; s->datos=temp; devolver verdadero; }
borrar
Eliminar en orden de bits
ListDelete(&L,i,&e): operación de eliminación. Elimine el elemento en la posición i en la tabla L y use e para devolver el valor del elemento eliminado.
//La lista enlazada individualmente se elimina en orden de bits bool ListDelete(ListaEnlaces &L,int I,TipoElem &s){ si(yo<1) falso retorno; LNode *p; //El puntero p apunta al nodo actualmente escaneado int j=0; //j indica a qué nodo p apunta actualmente p=L; //L apunta al nodo principal, que es el nodo 0 (no se almacenan datos) while(p!=NULL&&j<j-1){ //Bucle para encontrar el nodo i-1 p=p->siguiente; j; } if(p==NULL) //el valor i es ilegal falso retorno; if(p->next==NULL) //No hay otros nodos después del i-1º nodo falso retorno; LNode *q=p->next; //Dejemos que q apunte al nodo eliminado e=q->data; //Utiliza e para devolver el valor del elemento p->next=q->next; //"Desconectar" el nodo *q de la cadena free(q); //Libera el espacio de almacenamiento del nodo return true; //Eliminar con éxito } estructura typedef LNode{ datos de tipo elemento; estructura LNode *siguiente; }LNodo,*ListaEnlaces;
Eliminación del nodo especificado
EliminarNodo(LNodo *p), eliminar puntero p
//Eliminar el nodo p especificado de la lista enlazada individualmente bool EliminarNodo (LNodo *p){ si(p==NULL) falso retorno; LNode *q=p->next; //Dejemos que q apunte al nodo sucesor de *p p->data=p->next->data; //Intercambiar campos de datos con nodos posteriores p->next=q->next; //"Desconectar" el nodo *q de la cadena free(q); //Libera el espacio de almacenamiento de los nodos posteriores. devolver verdadero; }
Buscar en lista enlazada individualmente
búsqueda bit a bit
//Búsqueda bit a bit en una lista enlazada individualmente LNodo *GetElem(ListaEnlaces L,int i){ si(yo<0) devolver NULO; LNodo *p; intj=0; p=L; mientras(p!=NULL&&j<1){ p=p->siguiente; j; } devolver p; }
Buscar por valor
LocateElem(LinkList L,ElemType e), encuentra la ubicación del nodo con el campo de datos e
//Buscar por valor en una lista enlazada individualmente y encontrar el nodo cuyo campo de datos devuelve ==e LNodo *LocateElem(LinkList L,ElemType e){ LNodo *p = L->siguiente; //Comienza desde el primer nodo para encontrar el nodo con el campo de datos e mientras(p != NULL&&p->datos!=e) p=p->siguiente; return p; // Devuelve el puntero del nodo después de encontrarlo; de lo contrario, devuelve NULL }
Encuentra la longitud de la mesa.
//Buscar la longitud de la tabla int longitud(ListaEnlaces L){ longitud int=0; LNodo *p=L; mientras(p->siguiente!= NULL){ p=p->siguiente; len ; } devolver len; }
Creación de lista enlazada individualmente
Paso 1: Inicializar una lista enlazada individualmente Paso 2: Retire un elemento de datos a la vez e insértelo en la cabecera/pie de la mesa.
método de inserción de la cola
Inicialice una lista enlazada individualmente, establezca la longitud variable para registrar la longitud de la lista enlazada, establezca el puntero final de la lista e inserte un elemento de datos a la vez al final de la lista.
//Método de inserción de cola para crear una lista enlazada individualmente LinkList List_TailInsert(LinkList &L){ //Crear hacia adelante una lista enlazada individualmente int x; //Establece ElemType como entero L=(LinkList)malloc(sizeof(LNode)); //Crea el nodo principal LNode *s,*r=L; //r es el puntero final de la tabla scanf(“%d”,&x); //Ingrese el valor del nodo while(x!9999){ //Ingrese 9999 para indicar el final s=(LNodo *)malloc(tamañode(LNodo)); s->datos=x; r->siguiente=s; r=s; //r apunta al nuevo puntero final de la tabla scanf(“%d”,&x); } r->next=NULL; //Establece el puntero del nodo de cola en nulo devolver L; }
Método de inserción de la cabeza
//El método de inserción de encabezado crea una lista enlazada individualmente LinkList List_HeadInsert(LinkList &L){ //Crear de forma inversa una lista enlazada individualmente LNodo *s; intx; L=(LinkList)malloc(sizeof(LNode)); //Crea el nodo principal L->next=NULL; //Lista enlazada inicialmente vacía scanf(“%d”,&x); //Ingrese el valor del nodo while(x!=9999){ //Ingrese 9999 para indicar el final s=(LNode*)malloc(sizeof(LNode)); //Crea un nuevo nodo s->datos=x; s->siguiente=L->siguiente; L->next=s; //Inserta el nuevo nodo en la tabla, L es el puntero principal scanf(“%d”,&x); } devolver L; }
lista doblemente enlazada
Inicialización de lista doblemente enlazada
Lista enlazada individualmente: una lista enlazada individualmente no se puede recuperar a la inversa, lo que a veces resulta inconveniente. Lista doblemente enlazada: puede avanzar y retroceder, reducir la densidad de almacenamiento
//Inicialización de lista doblemente enlazada (nodo principal) bool InitDLinkList(DLinklist &L){ L=(DNodo *)malloc(tamañode(DNodo)); si(L==NULL) flash de retorno; L->anterior=NULL; L->siguiente=NULL; devolver verdadero; } anular pruebaDLinkList(){ //Inicializa lista doblemente enlazada DLista de enlaces L; InitDLinkList(L); //...Siguiente código } estructura typedef DNodo{ datos de tipo elemento; estructura DNodo *anterior,*siguiente; }DNodo,*DLista de enlaces; //Determinar si la lista doblemente enlazada está vacía (nodo principal) bool Vacío(DLinklist L){ si(L->siguiente==NULL) devolver verdadero; demás falso retorno; }
Inserción en lista doblemente enlazada
//Inserción en lista doblemente enlazada bool InsertNextDNode(DNodo *p,DNodo *s){ s->next=p->next; //Insertar nodo *s después del nodo *p p->siguiente->anterior=s; s->antes=p; p->siguiente=s; }
Eliminación de lista doblemente enlazada
//Eliminar lista doblemente enlazada bool EliminarSiguienteNodoD(NodoD *p){ if(p==NULL) devuelve flash; DNode *q=p->next; //Encontrar el nodo sucesor q de p if(q==NULL) return false //p no tiene un nodo sucesor p->siguiente=q->siguiente; if(q->next!=NULL) //El nodo q no es el último nodo q->siguiente->anterior=p; free(q); //Liberar espacio de nodo devolver verdadero; } anular DestoryList(DLinklist &L){ // Bucle para liberar cada nodo de datos mientras(L->siguiente!=NULL) EliminarSiguienteDNodo(L); free(L); //Libera el nodo principal L=NULL; //El puntero de la cabeza apunta a NULL }
Recorrido de lista doblemente enlazada
//recorrido de lista doblemente enlazada while(p!=NULL){ //Recorrido hacia atrás //Hacer el procesamiento correspondiente para el nodo p p=p->siguiente; } while(p!=NULL){ //Recorrido hacia adelante p=p->prioe; } while(p->prioe!=NULL){ //Recorrido hacia adelante, omitir el nodo principal p=p->antes; }
lista circular enlazada
Lista circular individualmente enlazada
Lista enlazada única: a partir de un nodo, solo se pueden encontrar los nodos posteriores, pero se desconocen los nodos anteriores. Lista circular individualmente enlazada: a partir de un nodo, puede encontrar cualquier otro nodo.
//Definir lista circular enlazada individualmente typedef struct LNode{ //Definir el tipo de nodo de lista enlazada única datos ElemType; //Cada nodo almacena un elemento de datos struct LNode *next; //los datos apuntan al siguiente nodo }LNodo,*ListaEnlaces; //Inicializa una lista circular enlazada individualmente bool ListaInit(ListaEnlaces &L){ L=(LNode *)malloc(sizeof(LNode)); //Asignar un nodo principal if(L==NULL) //Memoria insuficiente, la asignación falló falso retorno; L->next = L; //El nodo principal Next apunta al nodo principal devolver verdadero; } //Determinar si la lista circular individualmente enlazada está vacía bool Vacío(ListaEnlaces L){ si(L->siguiente==L) devolver verdadero; demás flash de retorno; } // Determinar si el nodo p es el nodo final de la lista circular individualmente enlazada bool isTail(ListaEnlaces L,NodoL *p){ si(p->siguiente==L) devolver verdadero; demás falso retorno; }
Lista circular doblemente enlazada
//Inicializa lista circular doble enlazada vacía bool InitDLinkList(DLinklist &L){ L=(DNode *)malloc(sizeof(DNode)); //Asignar un nodo principal if(L==NULL) //Memoria insuficiente, la asignación falló falso retorno; L->prior=L; // La prioridad del nodo principal apunta al nodo principal L->next=L; // el siguiente del nodo principal apunta al nodo principal devolver verdadero; } anular pruebaDLinkList(){ //Inicializa lista circular doble enlazada DLista de enlaces L; InitDLinkList(L); //...Siguiente código } //Determinar si la lista circular doblemente enlazada está vacía bool Vacío(DLinklist){ si(L->siguiente==L) devolver verdadero; demás falso retorno; } //Determinar si el nodo p es el nodo final de la lista circular doblemente enlazada bool isTail(DLinklist L,DNodo *p){ si(p->siguiente==L) devolver verdadero; demás falso retorno; } estructura typedef DNodo{ datos de tipo elemento; estructura DNodo *anterior,*siguiente; }DNodo,*DLista de enlaces;
lista enlazada estática
definición
Lista enlazada individualmente: cada nodo se asigna aleatoriamente en la memoria. Lista enlazada estática: asigne una parte completa de espacio de memoria continua y cada nodo se coloque en el centro.
representación de código
//Definir lista enlazada estática #definir tamaño máximo 10 typedef sreuct{} datos de tipo elemento; int siguiente; } anular pruebaSLinkList(){ estructura Nodo a[MaxSize]; //...código posterior } //También puedes crear una lista enlazada estática con el siguiente código #define MaxSize 10 //Longitud máxima de la lista enlazada estática typedef struct{ // Definición del tipo de estructura de lista enlazada estática datos ElemType; //elementos de datos de almacenamiento int next; // subíndice de matriz del siguiente elemento } ListaEnlaceS[TamañoMax]; prueba nulaSLinkLst(){} ListaEnlaceS a; //...Siguiente código }
Implementación de operaciones básicas.
Implementación de listas de secuencias y listas enlazadas.
estructura lógica
Todas son tablas lineales y estructuras lineales.
Resultados de estructura física/almacenamiento
Ventajas de las tablas de secuencia: admiten acceso aleatorio y alta densidad de almacenamiento. Desventajas: es inconveniente asignar grandes áreas de espacio continuo y es inconveniente cambiar la capacidad. Ventajas de las listas vinculadas: los espacios pequeños y discretos son fáciles de asignar y la capacidad es fácil de cambiar. Desventajas: sin acceso aleatorio, baja densidad de almacenamiento.
Operaciones de datos/operaciones básicas
Creación de tabla de secuencia: Es necesario preasignar un gran espacio contiguo. Si el espacio asignado es demasiado pequeño, será inconveniente ampliar la capacidad más adelante; si el espacio asignado es demasiado grande, se desperdiciarán recursos de memoria. Asignación estática: matriz estática, capacidad inmutable Asignación dinámica: matriz dinámica (malloc, gratuita), la capacidad se puede cambiar, pero requiere mover una gran cantidad de elementos, lo que lleva mucho tiempo. Destrucción: modifique la longitud = 0, el espacio asignado estáticamente se recuperará automáticamente, la aplicación malloc asignada dinámicamente debe liberarse manualmente Insertar/eliminar elementos requiere mover los elementos siguientes hacia adelante o hacia atrás. La complejidad del tiempo es O (n) y la sobrecarga de tiempo proviene principalmente de elementos en movimiento. Si el elemento móvil es grande, el coste del tiempo de movimiento es elevado. Búsqueda: Búsqueda bit a bit: O(1). Buscar por valor: O(n). Si los elementos de la tabla están ordenados, se pueden encontrar en tiempo O(log2n).
Creación de lista enlazada: Solo necesita asignar un nodo principal (también puede omitir el nodo principal y solo declarar un puntero principal), que se puede expandir fácilmente más adelante. Destruir: elimina cada nodo por turno (gratis) Insertar/eliminar elementos solo requiere modificar el puntero. La complejidad del tiempo es O (n), y la sobrecarga de tiempo proviene principalmente de encontrar el elemento objetivo. El coste de tiempo para encontrar elementos es menor. Búsqueda: Búsqueda bit a bit: O(n). Buscar por valor: O(n).
Utilice una lista secuencial o una lista vinculada: la longitud de la lista es difícil de estimar y, a menudo, es necesario agregar, restar o eliminar elementos, así que utilice una lista vinculada. La longitud de la tabla se puede estimar y hay muchas operaciones de consulta (búsqueda), así que utilice una tabla secuencial. Pregunta: Describa la lista de secuencia y la lista vinculada... ¿Cuál es mejor usar la lista de secuencia o la lista vinculada? Las estructuras lógicas de las listas de secuencia y las listas enlazadas son resultados lineales y ambas pertenecen a listas lineales. Sin embargo, las estructuras de almacenamiento de los dos son diferentes. La tabla de secuencia usa almacenamiento secuencial... (características, ventajas y desventajas) la lista vinculada usa almacenamiento en cadena... (ventajas y desventajas). Debido al uso de diferentes métodos de almacenamiento, la eficiencia de implementación de las operaciones básicas también es diferente. Al inicializar... al insertar un elemento de datos... al eliminar un elemento de datos... al buscar un elemento de datos...
Apéndice
tabla de secuencia
estructura de almacenamiento
Los elementos de datos que son lógicamente adyacentes también lo son físicamente
Método para realizar
asignación estática
Implementado usando "matriz estática"
Una vez determinado el tamaño, no se puede cambiar.
asignación dinámica
Implementado usando "matriz dinámica"
L.data=(ElemType *)malloc (tamaño de (El;emType)* tamaño)
Cuando la tabla de secuencia está llena, se puede utilizar malloc para expandir dinámicamente el rendimiento máximo de la tabla de secuencia.
Preste atención a malloc y funciones gratuitas.
Es necesario copiar los elementos de datos a una nueva área de almacenamiento y utilizar la función gratuita para liberar el área original.
Características
acceso aleatorio
Puede encontrar el i-ésimo elemento en tiempo O(1)
Alta densidad de almacenamiento
Ampliar la capacidad es inconveniente
Insertar y eliminar elementos de datos es inconveniente
mesa lineal
estructura lógica
Cálculos/operaciones básicas
Almacenamiento/Estructura física
Tabla de secuencia (almacenamiento secuencial)
Definición (cómo implementarla en código)
Implementación de operaciones básicas.
Lista vinculada (almacenamiento vinculado)
lista única
Definición (cómo implementarla en código)
Implementación de operaciones básicas.
lista doblemente enlazada
lista circular enlazada
lista enlazada estática
Inserción y eliminación de tabla de secuencia.
insertar
ListaInsertar(&L,i,e)
Inserte el elemento e en la i-ésima posición de L
Los elementos después de la posición de inserción deben moverse hacia atrás y la longitud de la mesa aumenta en 1
complejidad del tiempo
Mejor O(1), peor O(n), promedio O(n)
borrar
ListaEliminar(&L,i,&e)
Elimina el i-ésimo elemento de L y devuélvelo con e
Los elementos después de la posición eliminada deben moverse hacia adelante y la longitud de la tabla se reduce en 1
complejidad del tiempo
Mejor O(1), peor O(n), promedio O(n)
Puntos de código
Tenga en cuenta la diferencia entre el orden de bits i y el subíndice de matriz
El algoritmo debe ser robusto y determinar la legalidad de i
Preste atención a si el elemento movido comienza desde el elemento frontal o desde el elemento trasero.
Analiza por qué hay '&'
Búsqueda de tabla de secuencia
búsqueda bit a bit
ObtenerElem(L,i)
Obtenga el valor del elemento en la posición i en la tabla L
Utilice el subíndice de la matriz para obtener el i-ésimo elemento L.data[i-1]
Análisis de complejidad del tiempo.
La mejor/peor/complejidad temporal promedio es O(1)
Buscar por valor
LocalizarElem(L,e)
Encuentre el elemento cuyo valor del primer elemento sea igual a e en la lista de secuencia L y devuelva su orden de bits
Buscar comenzando desde el primer elemento y retrocediendo
Análisis de complejidad del tiempo.
La mejor complejidad temporal es O(1)
Peor complejidad de tiempo O(n)
Complejidad de tiempo promedio O (n)
Definición de lista enlazada individualmente
¿Qué es una lista enlazada individualmente?
El uso de "almacenamiento en cadena" (estructura de almacenamiento) realiza una "estructura lineal" (estructura lógica)
Un nodo almacena un elemento de datos.
La relación de secuencia entre cada nodo está representada por un puntero.
Definir una lista enlazada individualmente usando código
typedef struct LNode{ //Definir el tipo de nodo de lista enlazada única datos ElemType; //campo de datos struct LNode *siguiente; //campo de puntero }LNodo,*ListaEnlaces;
Dos implementaciones
nodo líder
Juicio de tabla vacía: L == NULL
Código fácil de escribir
Sin nodo principal
Juicio de tabla vacía: L->next==NULL;
Escribir código es inconveniente
Otros puntos a tener en cuenta
Cómo utilizar la palabra clave typedef
LinkList es equivalente a LNode LinkList enfatiza una lista vinculada; LNode enfatiza un nodo
Inserción y eliminación de listas enlazadas únicas
insertar
Insertar en orden de bits
nodo líder
Sin nodo principal
Operación posterior a la inserción del nodo especificado
Operación de inserción directa del nodo especificado
borrar
Eliminar en orden de bits
Eliminación del nodo especificado
Buscar en lista enlazada individualmente
búsqueda bit a bit
Tenga en cuenta la comparación con la "tabla de secuencias".
Una lista enlazada individualmente no tiene la característica de "acceso aleatorio" y solo se puede escanear de forma secuencial.
Buscar por valor
Encuentre la longitud de la lista enlazada individualmente
Llave
La complejidad temporal de las tres operaciones básicas es O (n)
Cómo escribir lógica de código que recorra cada nodo
Preste atención al procesamiento de condiciones de contorno.
Creación de lista enlazada individualmente
Paso 1: Inicializar una lista enlazada individualmente Paso 2: Tome un elemento de datos a la vez e insértelo en la cabecera/pie de la mesa.
método de inserción de la cola
Método de inserción de la cabeza
lista doblemente enlazada
inicialización
La prioridad y el siguiente del nodo principal apuntan a NULL.
Insertar (inserto trasero)
Preste atención a las modificaciones del puntero de los nodos recién insertados, los nodos predecesores y los nodos sucesores.
Caso límite: el ganglio recién insertado está en la última posición y requiere un tratamiento especial
Eliminar (posterior a la eliminación)
Preste atención a la modificación de los punteros del nodo predecesor y del nodo sucesor del nodo eliminado.
Caso límite: si el nodo eliminado es el último nodo de datos, se requiere un procesamiento especial
atravesar
A partir de un nodo determinado, la implementación del recorrido hacia atrás y hacia adelante (condición de terminación del bucle)
Las listas enlazadas no tienen características de acceso aleatorio y las operaciones de búsqueda solo se pueden lograr mediante un recorrido secuencial.
lista circular enlazada
Lista circular individualmente enlazada
Mesa vacía
tabla no vacía
Lista circular doblemente enlazada
Mesa vacía
tabla no vacía
problema de código
Cómo juzgar corto
Cómo determinar si el nodo p es el nodo cabeza/pie de la tabla
lista circular enlazada
¿Qué es una lista enlazada estática?
Asigne centralmente una dirección contigua completa para almacenar elementos de datos
Cómo definir una lista enlazada estática
Describir brevemente la implementación de las operaciones básicas.