Teknologian jakaminen

24/07/11Tietorakenne (6.1215) kaksoislinkitetty luettelo toteutus-pinon toteutus

2024-07-12

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

Aivan kuten kirjoitettaessa joitain toiminnallisia käyttöliittymiä yksitellen linkitetyille listoille, kirjoitetaan ensin joitain käyttöliittymiä kaksinkertaisesti linkitetyille listoille, jotta tutustumme sen pääkehykseen:

#sisältää<stdio.h>
#sisältää<stdlib.h>

typedef int LDataType;

//Kaksisuuntaisen pyöreän linkitetyn luettelon solmu
typedef struct ListNode{
LDataType _data;
// Osoita seuraavan solmun aloituspaikkaan
struct ListNode* _next;
// Osoita edellisen solmun aloituspaikkaan
struct LIst* _prev;
}ListNode;

//Kaksisuuntainen pyöreä linkitetty luettelo
typedef struct List{
struct ListNode* _head;
}Lista;

struct ListNode* createListNode(LDataType val){
struct ListNode* solmu = (struct ListSolmu*)malloc(koko(rakenne ListSolmu));
solmu-&gt;_data = arvo;
solmu-&gt;_seuraava = NULL;
solmu-&gt;_edellinen = NULL;
}

void ListInit(List* lst){
//Tyhjä linkitetty lista
lst-&gt;_head = createListNode(0);
lst-&gt;_head-&gt;_ext = lst-&gt;_head-&gt;_prev = lst-&gt;_head;

}
//Hännön lisäys O(1) //Lisätä data otsikon eteen ListInsert(lst, lst-&gt;_head, val);
void ListpushBack(List* lst, LDataType val){
if (lst == NULL){
palata;
struct ListNode* last = lst-&gt;_head-&gt;_prev;
struct ListSolmu* newNode = createListNode(val);
//_head ... viimeinen uusiNode
last-&gt;_next = uusiSolmu;
newNode-&gt;_prev = viimeinen;

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

//Tail delete://Poista pään edellinen solmu ListErase(lst, lst-&gt;_head-&gt;_prev);
void ListPopBack(List* lst){
if (lst == NULL)
palata;
//Määritä, onko linkitetty luettelo tyhjä
if (lst-&gt;_head-&gt;_seuraava == lst-&gt;_head)
palata;
struct ListNode* last = lst-&gt;_head-&gt;_prev;
struct ListNode* prev = viimeinen-&gt;_edellinen;

vapaa(viimeinen);

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

void printList(List* lst){
struct ListNode* cur = lst-&gt;_head-&gt;_next;
while (cur != lst-&gt;_head){
printf("%d", cur-&gt;_data);
cur = cur-&gt;_next;
    }
printf("n");
}

//Head insert//ListInsert(lst,lst-&gt;_head-&gt;_next,val);
void ListPushFront(List* lst, LDataType val){
if (lst == NULL)
palata;
struct ListNode* next = lst-&gt;_head-&gt;_next;
struct ListSolmu* newNode = createListNode(val);

//_head, newNode, next
lst-&gt;_head-&gt;_next = uusiSolmu;
newNode-&gt;_prev = lst-&gt;_head;

newNode-&gt;_next = seuraava;
seuraava-&gt;_edellinen = uusiSolmu;
}

//Otsikon poistaminen//ListErase(lst,lst-&gt;_head-&gt;_next);
void ListPopFront(List* lst){
if (lst == NULL || lst-&gt;_head == lst-&gt;_head)
palata;
struct ListNode* next = lst-&gt;_head-&gt;_next;
struct ListNode* nextnext = next-&gt;_next;
    
nextnext-&gt;_prev = seuraava-&gt;_seuraava;
lst-&gt;_head-&gt;_next = seuraavaseuraava;

ilmainen (seuraava);
    
}

void ListErase(List* lst, struct ListNode* solmu){
//Et voi poistaa pääsolmua
if (lst == NULL || lst-&gt;_head == solmu)
palata;
//edellinen, solmu, seuraava
struct ListNode* prev = solmu-&gt;_edellinen;
struct ListNode* next = solmu-&gt;_seuraava;

prev-&gt;_next = seuraava;
seuraava-&gt;_edellinen = edellinen;

vapaa(solmu);

}

void ListInsert(List* lst, struct ListNode* node, LDataType val){
if (lst == NULL)
palata;
struct ListNode* prev = solmu-&gt;_edellinen;
struct ListSolmu* newNode = createListNode(val);

//edellinen uusiSolmusolmu
prev-&gt;_next = uusiSolmu;
newNode-&gt;_prev = edellinen;

newNode-&gt;_next = solmu;
solmu-&gt;_edellinen = uusiSolmu;
}

//tuhota
ListDesto(List* lst){
if (lst){
if (lst-&gt;_head){
struct ListNode* cur = lst-&gt;_head-&gt;_next;
while (cur != lst-&gt;_head){
struct ListNode* next = cut-&gt;_next;
vapaa(cur);
cur = seuraava;
            }

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

void testi(){
List lst;
ListInit(&lst);
ListPushFront(&lst, 5);
printList(&lst);
ListPushFront(&lst, 1);
printList(&lst);
ListPushFront(&lst, 2);
printList(&lst);
ListPushFront(&lst, 3);
printList(&lst);
ListPushFront(&lst, 4);
printList(&lst);
ListPopFront(&lst);
printList(&lst);
ListPopFront(&lst);
printList(&lst);
ListPopFront(&lst);
printList(&lst);

/*ListPopBack(&lst);
printList(&lst);
ListPopBack(&lst);
printList(&lst);
ListPopBack(&lst);
printList(&lst);
ListPopBack(&lst);
printList(&lst);*/
}

int main(){

testata();
system("tauko");
paluu 0;
}

Ero ja yhteys sekvenssiluettelon ja linkitetyn luettelon välillä:

Sekvenssitaulukon edut ja haitat: Erinomainen: Tila on jatkuva, tukee satunnaiskäyttöä, sillä on korkea tilankäyttö, eikä se todennäköisesti aiheuta muistin pirstoutumista, ja sillä on korkea hännän lisäys- ja hännänpoistotehokkuus.

Haitat: 1. Keski- tai etuosan lisäämisen ja poistamisen aika monimutkaisuus on O(N) 2. Kapasiteetin laajentamiskustannukset ovat suhteellisen korkeat: hae kopion vapauttamista

Linkitettyjen luetteloiden edut ja haitat (johtineet kaksisuuntaiset satunnaiset linkitetyt luettelot)

Edut: 1. Lisäyksen ja poistamisen aika monimutkaisuus missä tahansa kohdassa on O(1) 2. Kapasiteetin laajentamiseen ei ole ongelmaa, yhden lisääminen avaa tilaa ja lisäämisen ja poistamisen tehokkuus missä tahansa kohdassa on korkea

Haitat: Se on tallennettu solmuyksiköihin, ei tue satunnaiskäyttöä ja alhainen tilankäyttö voi helposti aiheuttaa muistin pirstoutumista.

pinot ja jonot

Pino: Erityinen lineaarinen luettelo, joka sallii elementtien lisäämisen ja poistamisen vain toisessa päässä. Päätä, jossa tietojen lisäys- ja poistotoiminnot suoritetaan, kutsutaan pinon yläpääksi ja toista päätä kutsutaan pinon alaosaksi pinossa noudattaa LIFO-periaatetta (last in first out).

Pinon työntäminen: Pinon lisäystoimintoa kutsutaan push/push/push, ja lisätyt tiedot ovat pinon päällä

Pop: Pinon poistotoimintoa kutsutaan poppingiksi, ja poksattavat tiedot ovat myös pinon päällä.

Push-operaation toteutus push---&gt;varasto elementtejä pinon yläosasta

Järjestystaulukko: Sitä voidaan pitää hännän lisäysoperaationa

Linkitetty luettelo: (kaksisuuntainen pyöreä linkitetty luettelo) luettelon yläosaa pidetään pinon yläpäänä, joka on otsikon lisäys, ja luettelon loppuosaa pidetään pinon yläpäänä, joka on hännän asettaminen.

Pop-toiminto pop---&gt;poista elementit pinon yläosasta

Järjestystaulukko: Taulukon loppua pidetään pinon yläosana ja sitä pidetään tail delete -operaationa.

Linkitetty lista: (kaksisuuntainen pyöreä linkitetty luettelo) listan yläosaa pidetään pinon yläpäänä, mikä on otsikon poisto, ja luettelon loppuosaa pidetään pinon yläpäänä, joka on hännän poisto.

#sisältää<stdio.h>
#sisältää<stdlib.h>

typedef int STDataType;
//Sekvenssitaulukko toteuttaa pinon
typedef struct pino{
STDataType* _data;
int _size;
int _kapasiteetti;
}pino;

void stackInit(pino* st){
jos (st == NULL)
palata;
st-&gt;_data = NULL;
st-&gt;_koko = st-&gt;_kapasiteetti = 0;
}

void checkCapcacity(pino* st){
if (st-&gt;_size == st-&gt;_capacity){
int newCapcacity = st-&gt;_capacity == 0 ? 1 : 2 * st-&gt;_kapasiteetti;
st-&gt;_data = (STDataType*)realloc(st-&gt;_data, sizeof(STDataType)* newCapcacity);
st-&gt;_kapasiteetti = uusi Kapasiteetti;
    }

}

//Paina pinoamaan
void stackPush(pino* st, STDataType val){
jos (st == NULL)
palata;
checkCapacity(st);
//Hännän lisäys
st-&gt;_data[st-&gt;_size++] = arvo;

}

//pop
void stackPop(pino* st){
jos (st == NULL)
palata;
jos (st-&gt;_size &gt; 0)
st-&gt;_size--;
}

STDataType pinoTop(pino* st){
palauttaa st-&gt;_data[st-&gt;_size - 1];
}

int stackSize(pino* st){
jos (st == NULL)
paluu 0;
return st-&gt;_size;
}

void testi(){
pino st;
stackInit(&st);
stackPush(&st, 1);
stackPush(&st, 2);
stackPush(&st, 3);
stackPush(&st, 4);
for (int i = 0; i &lt; 4; ++i){
printg("%d", pinoTop(&st));
stackPop(&st);
    }
printf("n");
}

int main(){
testata();
system("tauko");
paluu 0;
}