Condivisione della tecnologia

24/07/11Struttura dei dati (6.1215) implementazione dello stack con doppia lista collegata

2024-07-12

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

Proprio come scrivere alcune interfacce funzionali per elenchi concatenati singolarmente, scriviamo prima alcune interfacce per elenchi concatenati doppiamente per familiarizzare con la sua struttura principale:

#includere<stdio.h>
#includere<stdlib.h>

typedef int LDataType;

//Il nodo dell'elenco collegato circolare bidirezionale
tipodef struct ElencoNodo{
LDataType _dati;
//Punta alla posizione iniziale del nodo successivo
struct ListNode* _next;
//Punta alla posizione iniziale del nodo precedente
struct LIst* _prev;
}NodoElenco;

//Elenco concatenato circolare con intestazione bidirezionale
tipodef struct Elenco{
struct ListNode* _testa;
}Elenco;

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

void ListInit(Elenco* lst){
//Elenco collegato vuoto
lst-&gt;_head = createListNode(0);
lst-&gt;_head-&gt;_next = lst-&gt;_head-&gt;_prev = lst-&gt;_head;

}
//Inserimento coda O(1) //Inserisce un dato davanti alla testa ListInsert(lst, lst-&gt;_head, val);
void ListpushBack(Elenco* lst, LDataType val){
se (lst == NULL){
ritorno;
struct ListNode* ultimo = lst-&gt;_head-&gt;_prev;
struct ListNode* newNode = createListNode(val);
//_head ... ultimo nuovoNodo
ultimo-&gt;_successivo = nuovoNodo;
newNode-&gt;_prev = ultimo;

nuovoNodo-&gt;_next = lst-&gt;_head;
lst-&gt;_head-&gt;_prev = newNode;
    }
}

//Tail delete://Elimina il nodo precedente della testa ListErase(lst, lst-&gt;_head-&gt;_prev);
void ListPopBack(Elenco* lst){
se (lst == NULL)
ritorno;
//Determina se l'elenco collegato è vuoto
se (lst-&gt;_head-&gt;_next == lst-&gt;_head)
ritorno;
struct ListNode* ultimo = lst-&gt;_head-&gt;_prev;
struct ListNode* prev = last-&gt;_prev;

libero(ultimo);

lst-&gt;_head-&gt;_prev = prev;
prev-&gt;_next = lst-&gt;_head;
}

void printList(Elenco* lst){
struct ListNode* cur = lst-&gt;_head-&gt;_next;
mentre (cur != lst-&gt;_head){
printf("%d", cur-&gt;_data);
curva = curva-&gt;_successivo;
    }
stampa("n");
}

//Inserisci intestazione//ListInsert(lst,lst-&gt;_head-&gt;_next,val);
void ListPushFront(Elenco* lst, LDataType val){
se (lst == NULL)
ritorno;
struct ListNode* next = lst-&gt;_head-&gt;_next;
struct ListNode* newNode = createListNode(val);

//_head, newNode, successivo
lst-&gt;_head-&gt;_next = newNode;
nuovoNodo-&gt;_prev = lst-&gt;_head;

newNode-&gt;_next = successivo;
successivo-&gt;_precedente = nuovoNodo;
}

//Elimina intestazione//ListErase(lst,lst-&gt;_head-&gt;_next);
void ListPopFront(Elenco* lst){
se (lst == NULL || lst-&gt;_head == lst-&gt;_head)
ritorno;
struct ListNode* next = lst-&gt;_head-&gt;_next;
struct ListNode* nextnext = next-&gt;_next;
    
successivosuccessivo-&gt;_precedente = successivo-&gt;_successivo;
lst-&gt;_head-&gt;_next = nextnext;

libero(successivo);
    
}

void ListErase(List* lst, struct ListNode* nodo){
//Impossibile eliminare il nodo head
se (lst == NULL || lst-&gt;_head == nodo)
ritorno;
//precedente, nodo, successivo
struct ListNode* prev = nodo-&gt;_prev;
struct ListNode* next = nodo-&gt;_next;

prev-&gt;_next = successivo;
successivo-&gt;_precedente = precedente;

libero(nodo);

}

void ListInsert(List* lst, struct ListNode* nodo, LDataType val){
se (lst == NULL)
ritorno;
struct ListNode* prev = nodo-&gt;_prev;
struct ListNode* newNode = createListNode(val);

//prev newNode nodo
prev-&gt;_next = nuovoNodo;
newNode-&gt;_prev = prev;

newNode-&gt;_next = nodo;
nodo-&gt;_prev = nuovoNodo;
}

//distruggere
ListDestoty(Elenco* lst){
se (primo){
se (lst-&gt;_testa){
struct ListNode* cur = lst-&gt;_head-&gt;_next;
mentre (cur != lst-&gt;_head){
struct ListNode* next = cut-&gt;_next;
libero(corr);
cur = successivo;
            }

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

prova nulla(){
Elenco lst;
ElencoInit(&lst);
## ...
stampaLista(&lst);
## ...
stampaLista(&lst);
## ...
stampaLista(&lst);
## ...
stampaLista(&lst);
## ...
stampaLista(&lst);
{NS} ...
stampaLista(&lst);
{NS} ...
stampaLista(&lst);
{NS} ...
stampaLista(&lst);

/*ListPopBack(&lst);
stampaLista(&lst);
{NS} ...
stampaLista(&lst);
{NS} ...
stampaLista(&lst);
{NS} ...
stampaElenco(&lst);*/
}

int principale(){

test();
sistema("pausa");
restituisci 0;
}

La differenza e la connessione tra elenco di sequenze e elenco collegato:

Vantaggi e svantaggi della tabella di sequenza: Eccellente: lo spazio è continuo, supporta l'accesso casuale, ha un elevato utilizzo dello spazio e non è probabile che causi la frammentazione della memoria e ha un'elevata efficienza di inserimento ed eliminazione della coda.

Svantaggi: 1. La complessità temporale per l'inserimento e l'eliminazione della parte centrale o anteriore è O(N) 2. Il costo dell'espansione della capacità è relativamente elevato: richiedere il rilascio della copia

Vantaggi e svantaggi delle liste collegate (liste collegate casuali bidirezionali guidate)

Vantaggi: 1. La complessità temporale dell'inserimento e dell'eliminazione in qualsiasi posizione è O(1) 2. Non vi è alcun problema di espansione della capacità, l'inserimento di uno apre uno spazio e l'efficienza dell'inserimento e dell'eliminazione in qualsiasi posizione è elevata

Svantaggi: viene archiviato in unità di nodi, non supporta l'accesso casuale e un basso utilizzo dello spazio può facilmente causare la frammentazione della memoria.

pile e code

Stack: uno speciale elenco lineare che consente l'inserimento e l'eliminazione di elementi solo a un'estremità. L'estremità in cui vengono eseguite le operazioni di inserimento ed eliminazione dei dati è denominata parte superiore dello stack, mentre l'altra estremità è denominata parte inferiore dello stack nello stack segue il principio LIFO (last in first out).

Push dello stack: l'operazione di inserimento dello stack è chiamata push/push/push e i dati inseriti si trovano in cima allo stack

Pop: l'operazione di eliminazione dello stack è chiamata popping e anche i dati pop sono in cima allo stack.

Implementazione dell'operazione push push---&gt;memorizza elementi dalla cima dello stack

Tabella di sequenza: può essere considerata come un'operazione di inserimento della coda

Lista concatenata: (lista concatenata circolare bidirezionale) la testa della lista è considerata come la cima dello stack, che è l'inserimento della testa, e la coda della lista è considerata come la cima della pila, che è la inserimento della coda

Operazione pop pop---&gt;rimuove gli elementi dalla cima dello stack

Tabella di sequenza: la fine della tabella è considerata la parte superiore dello stack ed è considerata l'operazione di eliminazione della coda.

Elenco concatenato: (elenco concatenato circolare bidirezionale) l'inizio dell'elenco è considerato come la parte superiore dello stack, che è l'eliminazione della testa, e la coda dell'elenco è considerata come la parte superiore dello stack, che è la eliminazione della coda.

#includere<stdio.h>
#includere<stdlib.h>

tipodef int STDataType;
//La tabella di sequenza implementa uno stack
pila di strutture typedef{
STDataType* _dati;
int _dimensione;
int _capacità;
}pila;

pila vuotaInit(pila* st){
se (st == NULL)
ritorno;
st-&gt;_data = NULL;
st-&gt;_dimensione = st-&gt;_capacità = 0;
}

controllo vuotoCapcacity(pila* st){
se (st-&gt;_dimensione == st-&gt;_capacità){
int nuovaCapacità = st-&gt;_capacità == 0 ? 1 : 2 * st-&gt;_capacità;
st-&gt;_data = (STDataType*)realloc(st-&gt;_data, sizeof(STDataType)* newCapcacity);
st-&gt;_capacity = nuovaCapacità;
    }

}

//Premi per impilare
void stackPush(stack* st, STDataType val){
se (st == NULL)
ritorno;
controllaCapacità(st);
//Inserimento della coda
st-&gt;_data[st-&gt;_size++] = val;

}

//pop
pila vuotaPop(pila* st){
se (st == NULL)
ritorno;
se (st-&gt;_size &gt; 0)
st-&gt;_dimensione--;
}

Tipo di dati ST stackTop(stack* st){
restituisci st-&gt;_data[st-&gt;_size - 1];
}

int dimensione pila(pila* st){
se (st == NULL)
restituisci 0;
restituisci st-&gt;_size;
}

prova nulla(){
pila st;
{NS} = ...
stackPush(&st, 1);
stackPush(&st, 2);
stackPush(&st, 3);
stackPush(&st, 4);
per (int i = 0; i &lt; 4; ++i){
printg("%d", stackTop(&st));
## ...
    }
stampa("n");
}

int principale(){
test();
sistema("pausa");
restituisci 0;
}