Compartir tecnología

24/07/11Estructura de datos (6.1215) implementación de lista doblemente enlazada-implementación de pila

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Al igual que escribir algunas interfaces funcionales para listas con enlaces simples, primero escribamos algunas interfaces para listas con enlaces dobles para familiarizarnos con su marco principal:

#incluir<stdio.h>
#incluir<stdlib.h>

tipo de definición int LDataType;

// El nodo de la lista enlazada circular de dos direcciones
typedef estructura ListaNodo{
LDataType _datos;
//Apunta a la posición inicial del siguiente nodo
estructura ListNode* _next;
//Apunta a la posición inicial del nodo anterior
estructura LIst* _prev;
}NodoLista;

//Lista enlazada circular con encabezados bidireccionales
typedef estructura Lista{
estructura ListaNodo* _cabeza;
}Lista;

estructura ListNode*createListNode(LDataType val){
struct ListNode* nodo = (struct ListNode*)malloc(sizeof(struct ListNode));
nodo-&gt;_data = val;
nodo-&gt;_siguiente = NULL;
nodo-&gt;_prev = NULL;
}

vacío ListInit(Lista* lst){
//Lista enlazada vacía
lst-&gt;_head = crearListNode(0);
lst-&gt;_cabeza-&gt;_siguiente = lst-&gt;_cabeza-&gt;_anterior = lst-&gt;_cabeza;

}
//Inserción de cola O(1) //Insertar datos delante del encabezado ListInsert(lst, lst-&gt;_head, val);
vacío ListpushBack(Lista* lst, LDataType val){
si (lst == NULL){
devolver;
estructura ListNode* último = lst-&gt;_head-&gt;_prev;
estructura ListNode* newNode = crearListNode(val);
//_head ... último nuevoNodo
último-&gt;_siguiente = nuevoNodo;
nuevoNodo-&gt;_prev = último;

nuevoNodo-&gt;_siguiente = lst-&gt;_head;
lst-&gt;_head-&gt;_prev = nuevoNodo;
    }
}

// Eliminación de cola: // Elimina el nodo anterior del encabezado ListErase(lst, lst-&gt;_head-&gt;_prev);
vacío ListPopBack(Lista* lst){
si (lst == NULL)
devolver;
//Determinar si la lista vinculada está vacía
si (lst-&gt;_cabeza-&gt;_siguiente == lst-&gt;_cabeza)
devolver;
estructura ListNode* último = lst-&gt;_head-&gt;_prev;
estructura ListNode* prev = last-&gt;_prev;

libre(ultimo);

lst-&gt;_head-&gt;_prev = anterior;
anterior-&gt;_siguiente = lst-&gt;_head;
}

void imprimirLista(Lista* lst){
estructura ListNode* cur = lst-&gt;_head-&gt;_next;
mientras (cur != lst-&gt;_head){
printf("%d", cur-&gt;_data);
cur = cur-&gt;_siguiente;
    }
printf("n");
}

//Inserción de encabezado//ListInsert(lst,lst-&gt;_head-&gt;_next,val);
vacío ListPushFront(Lista* lst, LDataType val){
si (lst == NULL)
devolver;
estructura ListNode* siguiente = lst-&gt;_head-&gt;_next;
estructura ListNode* newNode = crearListNode(val);

//_cabeza, nuevoNodo, siguiente
lst-&gt;_head-&gt;_next = nuevoNodo;
nuevoNodo-&gt;_prev = lst-&gt;_head;

nuevoNodo-&gt;_siguiente = siguiente;
siguiente-&gt;_prev = nuevoNodo;
}

//eliminar encabezado//ListErase(lst,lst-&gt;_head-&gt;_next);
vacío ListPopFront(Lista* lst){
si (lst == NULL || lst-&gt;_head == lst-&gt;_head)
devolver;
estructura ListNode* siguiente = lst-&gt;_head-&gt;_next;
estructura ListNode* nextnext = siguiente-&gt;_siguiente;
    
siguientesiguiente-&gt;_anterior = siguiente-&gt;_siguiente;
lst-&gt;_head-&gt;_next = siguientesiguiente;

libre(siguiente);
    
}

void ListErase(Lista* lst, estructura ListNode* nodo){
//No se puede eliminar el nodo principal
si (lst == NULL || lst-&gt;_head == nodo)
devolver;
//prev, nodo, siguiente
struct ListNode* prev = nodo-&gt;_prev;
struct ListNode* next = nodo-&gt;_siguiente;

prev-&gt;_next = siguiente;
siguiente-&gt;_prev = prev;

libre(nodo);

}

vacío ListInsert(List* lst, struct ListNode* nodo, LDataType val){
si (lst == NULL)
devolver;
struct ListNode* prev = nodo-&gt;_prev;
estructura ListNode* newNode = crearListNode(val);

//prev nuevoNodo nodo
prev-&gt;_next = nuevoNodo;
nuevoNodo-&gt;_prev = prev;

nuevoNodo-&gt;_siguiente = nodo;
nodo-&gt;_prev = nuevoNodo;
}

//destruir
ListaDestoty(Lista* lst){
si (lst){
si (lst-&gt;_head){
estructura ListNode* cur = lst-&gt;_head-&gt;_next;
mientras (cur != lst-&gt;_head){
struct ListNode* siguiente = cortar-&gt;_siguiente;
libre(cur);
cur = siguiente;
            }

libre(lst-&gt;_head);
        }
    }
}

prueba nula(){
Lista lst;
ListaInit(&lst);
ListaPushFront(&lst, 5);
imprimirLista(&lst);
ListaPushFront(&lst, 1);
imprimirLista(&lst);
ListaPushFront(&lst, 2);
imprimirLista(&lst);
ListaPushFront(&lst, 3);
imprimirLista(&lst);
ListaPushFront(&lst, 4);
imprimirLista(&lst);
ListaPopFront(&lst);
imprimirLista(&lst);
ListaPopFront(&lst);
imprimirLista(&lst);
ListaPopFront(&lst);
imprimirLista(&lst);

/*ListPopBack(&lst);
imprimirLista(&lst);
ListaPopBack(&lst);
imprimirLista(&lst);
ListaPopBack(&lst);
imprimirLista(&lst);
ListaPopBack(&lst);
imprimirLista(&lst);*/
}

int principal(){

prueba();
sistema("pausa");
devuelve 0;
}

La diferencia y conexión entre lista de secuencia y lista enlazada:

Ventajas y desventajas de la tabla de secuencia: Excelente: el espacio es continuo, admite acceso aleatorio, tiene una alta utilización del espacio y no es probable que cause fragmentación de la memoria, y tiene una alta eficiencia de inserción y eliminación de colas.

Desventajas: 1. La complejidad temporal de insertar y eliminar la parte intermedia o frontal es O (N) 2. El costo de expansión de capacidad es relativamente alto: solicite la liberación de la copia

Ventajas y desventajas de las listas enlazadas (listas enlazadas aleatorias bidireccionales dirigidas)

Ventajas: 1. La complejidad temporal de insertar y eliminar en cualquier posición es O (1) 2. No hay problema de expansión de capacidad, insertar uno abre un espacio y la eficiencia de insertar y eliminar en cualquier posición es alta

Desventajas: se almacena en unidades de nodos, no admite el acceso aleatorio y la baja utilización del espacio puede provocar fácilmente la fragmentación de la memoria.

pilas y colas

Pila: una lista lineal especial que solo permite la inserción y eliminación de elementos en un extremo. El extremo donde se realizan las operaciones de inserción y eliminación de datos se denomina parte superior de la pila y el otro extremo se denomina parte inferior de la pila. en la pila sigue el principio LIFO (último en entrar, primero en salir)

Empujar la pila: la operación de inserción de la pila se llama empujar/empujar/empujar, y los datos insertados están en la parte superior de la pila.

Pop: la operación de eliminación de la pila se llama popping, y los datos que se extraen también están en la parte superior de la pila.

Implementación de la operación push push---&gt;almacenar elementos desde la parte superior de la pila

Tabla de secuencia: puede considerarse como una operación de inserción de cola.

Lista enlazada: (lista enlazada circular con encabezado bidireccional) el encabezado de la lista se considera la parte superior de la pila, que es la inserción del encabezado, y la cola de la lista se considera la parte superior de la pila, que es la inserción de la cola.

Operación emergente pop---&gt;eliminar elementos de la parte superior de la pila

Tabla de secuencia: el final de la tabla se considera la parte superior de la pila y la operación de eliminación final.

Lista enlazada: (lista enlazada circular con encabezado bidireccional) el encabezado de la lista se considera la parte superior de la pila, que es la eliminación del encabezado, y la cola de la lista se considera la parte superior de la pila, que es la eliminación de cola.

#incluir<stdio.h>
#incluir<stdlib.h>

tipo de definición int STDataType;
//La tabla de secuencia implementa una pila
typedef estructura pila{
STDataType* _datos;
int _tamaño;
int _capacidad;
}pila;

vacío stackInit(pila* st){
si (st == NULL)
devolver;
st-&gt;_data = NULL;
st-&gt;_tamaño = st-&gt;_capacidad = 0;
}

anular comprobaciónCapacidad(pila* st){
si (st-&gt;_tamaño == st-&gt;_capacidad){
int nuevaCapacidad = st-&gt;_capacidad == 0 ? 1 : 2 * st-&gt;_capacidad;
st-&gt;_data = (STDataType*)realloc(st-&gt;_data, tamaño de(STDataType)* nuevaCapacidad);
st-&gt;_capacidad = nuevaCapacidad;
    }

}

// Empujar para apilar
vacío pilaPush(pila* st, STDataType val){
si (st == NULL)
devolver;
comprobarCapacidad(st);
//inserción de cola
st-&gt;_datos[st-&gt;_tamaño++] = val;

}

//estallido
void pilaPop(pila* st){
si (st == NULL)
devolver;
si (st-&gt;_tamaño &gt; 0)
st-&gt;_tamaño--;
}

STDataType pilaTop(pila* st){
devuelve st-&gt;_data[st-&gt;_size - 1];
}

int tamañopila(pila* st){
si (st == NULL)
devuelve 0;
retorna st-&gt;_size;
}

prueba nula(){
pila st;
pilaInit(&st);
pilaPush(&st, 1);
pilaPush(&st, 2);
pilaPush(&st, 3);
pilaPush(&st, 4);
para (int i = 0; i &lt; 4; ++i){
printg("%d", pilaTop(&st));
pilaPop(&st);
    }
printf("n");
}

int principal(){
prueba();
sistema("pausa");
devuelve 0;
}