le mie informazioni di contatto
Posta[email protected]
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->_dati = val;
nodo->_next = NULL;
nodo->_prev = NULL;
}
void ListInit(Elenco* lst){
//Elenco collegato vuoto
lst->_head = createListNode(0);
lst->_head->_next = lst->_head->_prev = lst->_head;
}
//Inserimento coda O(1) //Inserisce un dato davanti alla testa ListInsert(lst, lst->_head, val);
void ListpushBack(Elenco* lst, LDataType val){
se (lst == NULL){
ritorno;
struct ListNode* ultimo = lst->_head->_prev;
struct ListNode* newNode = createListNode(val);
//_head ... ultimo nuovoNodo
ultimo->_successivo = nuovoNodo;
newNode->_prev = ultimo;
nuovoNodo->_next = lst->_head;
lst->_head->_prev = newNode;
}
}
//Tail delete://Elimina il nodo precedente della testa ListErase(lst, lst->_head->_prev);
void ListPopBack(Elenco* lst){
se (lst == NULL)
ritorno;
//Determina se l'elenco collegato è vuoto
se (lst->_head->_next == lst->_head)
ritorno;
struct ListNode* ultimo = lst->_head->_prev;
struct ListNode* prev = last->_prev;
libero(ultimo);
lst->_head->_prev = prev;
prev->_next = lst->_head;
}
void printList(Elenco* lst){
struct ListNode* cur = lst->_head->_next;
mentre (cur != lst->_head){
printf("%d", cur->_data);
curva = curva->_successivo;
}
stampa("n");
}
//Inserisci intestazione//ListInsert(lst,lst->_head->_next,val);
void ListPushFront(Elenco* lst, LDataType val){
se (lst == NULL)
ritorno;
struct ListNode* next = lst->_head->_next;
struct ListNode* newNode = createListNode(val);
//_head, newNode, successivo
lst->_head->_next = newNode;
nuovoNodo->_prev = lst->_head;
newNode->_next = successivo;
successivo->_precedente = nuovoNodo;
}
//Elimina intestazione//ListErase(lst,lst->_head->_next);
void ListPopFront(Elenco* lst){
se (lst == NULL || lst->_head == lst->_head)
ritorno;
struct ListNode* next = lst->_head->_next;
struct ListNode* nextnext = next->_next;
successivosuccessivo->_precedente = successivo->_successivo;
lst->_head->_next = nextnext;
libero(successivo);
}
void ListErase(List* lst, struct ListNode* nodo){
//Impossibile eliminare il nodo head
se (lst == NULL || lst->_head == nodo)
ritorno;
//precedente, nodo, successivo
struct ListNode* prev = nodo->_prev;
struct ListNode* next = nodo->_next;
prev->_next = successivo;
successivo->_precedente = precedente;
libero(nodo);
}
void ListInsert(List* lst, struct ListNode* nodo, LDataType val){
se (lst == NULL)
ritorno;
struct ListNode* prev = nodo->_prev;
struct ListNode* newNode = createListNode(val);
//prev newNode nodo
prev->_next = nuovoNodo;
newNode->_prev = prev;
newNode->_next = nodo;
nodo->_prev = nuovoNodo;
}
//distruggere
ListDestoty(Elenco* lst){
se (primo){
se (lst->_testa){
struct ListNode* cur = lst->_head->_next;
mentre (cur != lst->_head){
struct ListNode* next = cut->_next;
libero(corr);
cur = successivo;
}
libero(lst->_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--->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--->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->_data = NULL;
st->_dimensione = st->_capacità = 0;
}
controllo vuotoCapcacity(pila* st){
se (st->_dimensione == st->_capacità){
int nuovaCapacità = st->_capacità == 0 ? 1 : 2 * st->_capacità;
st->_data = (STDataType*)realloc(st->_data, sizeof(STDataType)* newCapcacity);
st->_capacity = nuovaCapacità;
}
}
//Premi per impilare
void stackPush(stack* st, STDataType val){
se (st == NULL)
ritorno;
controllaCapacità(st);
//Inserimento della coda
st->_data[st->_size++] = val;
}
//pop
pila vuotaPop(pila* st){
se (st == NULL)
ritorno;
se (st->_size > 0)
st->_dimensione--;
}
Tipo di dati ST stackTop(stack* st){
restituisci st->_data[st->_size - 1];
}
int dimensione pila(pila* st){
se (st == NULL)
restituisci 0;
restituisci st->_size;
}
prova nulla(){
pila st;
{NS} = ...
stackPush(&st, 1);
stackPush(&st, 2);
stackPush(&st, 3);
stackPush(&st, 4);
per (int i = 0; i < 4; ++i){
printg("%d", stackTop(&st));
## ...
}
stampa("n");
}
int principale(){
test();
sistema("pausa");
restituisci 0;
}