21.12.2013 Views

pekare - KTH

pekare - KTH

pekare - KTH

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

C-programmering ID120V<br />

Stack och Kö<br />

william@kth.se<br />

William Sandqvist william@kth.se


Data i länkad lista<br />

Det är enklast att nå länkade listor från ”ändarna”.<br />

Man lägger till eller tar bort element – men man flyttar<br />

inte om i listan.<br />

Stack<br />

Kö<br />

William Sandqvist william@kth.se


Två sätt att hantera data<br />

sist in<br />

Stack och Kö<br />

Stack<br />

LIFO<br />

först ut<br />

William Sandqvist william@kth.se


Två sätt att hantera data<br />

Stack och Kö<br />

först in först ut<br />

Kö<br />

FIFO<br />

William Sandqvist william@kth.se


Likna stacken med en stege<br />

Man kan bara kliva på i nedre ändan, push. Man kan bara kliva<br />

av i nedre ändan, pop. När någon ny kliver på måste inte alla<br />

andra på stegen ta ett kliv uppåt. Det räcker med att skapa en ny<br />

plats och ordna pekarna.<br />

När någon kliver av behöver inte alla ta ett steg<br />

nedåt. Det räcker med att ta bort platsen och<br />

ordna pekarna.<br />

Push<br />

William Sandqvist william@kth.se<br />

Vi behöver inte<br />

flytta elementen i<br />

listan – bara<br />

ordna pekarna.


Stack, exempel<br />

Ett exempel på hur man med en länkad lista<br />

och funktionerna push() och pop()<br />

skapar en datastack ( datastruktur ).<br />

• Programmet vänder på teckenordningen i<br />

en sträng<br />

• Att lagra och vända på ordningen är typiskt<br />

för stacken<br />

William Sandqvist william@kth.se


Datatyper och funktionsprototyp<br />

#include <br />

#include <br />

typedef struct {<br />

int heltalsData;<br />

} DataTyp ;<br />

Det data som vi vill lagra<br />

på stacken. Om man<br />

konstruerar Push() och<br />

Pop() för att ta en struct<br />

blir dessa funktioner<br />

generella.<br />

typedef struct StackElementTyp {<br />

DataTyp d; Nyttolast!<br />

struct StackElementTyp *next ;<br />

} StackElementTyp ;<br />

typedef StackElementTyp* BottenPekarTyp ;<br />

void Pop( BottenPekarTyp *b, DataTyp *x );<br />

void Push( BottenPekarTyp *b , DataTyp x ) ;<br />

int ArTom( BottenPekarTyp b );<br />

void Baklanges( char xString[] );<br />

William Sandqvist william@kth.se


Datatyper och funktionsprototyp<br />

#include <br />

#include <br />

typedef struct {<br />

int heltalsData;<br />

} DataTyp ;<br />

För att kunna lagra som en<br />

stack med en länkad lista så<br />

måste det finnas en next<strong>pekare</strong>.<br />

Denna tillfogas av<br />

Push() m h a denna struct<br />

typedef struct StackElementTyp {<br />

DataTyp d;<br />

struct StackElementTyp * next ;<br />

} StackElementTyp ;<br />

typedef StackElementTyp* BottenPekarTyp ;<br />

void Pop( BottenPekarTyp *b, DataTyp *x );<br />

void Push( BottenPekarTyp *b , DataTyp x ) ;<br />

int ArTom( BottenPekarTyp b );<br />

void Baklanges( char xString[] );<br />

William Sandqvist william@kth.se<br />

StackElementTyp<br />

Push()<br />

NULL


Datatyper och funktionsprototyp<br />

#include <br />

#include <br />

typedef struct {<br />

int heltalsData;<br />

} DataTyp ;<br />

För att tydligt kunna<br />

skapa en <strong>pekare</strong>,<br />

handtag, till stacken<br />

(botten). OBS <strong>pekare</strong>!<br />

typedef struct StackElementTyp {<br />

DataTyp d;<br />

struct StackElementTyp * next ;<br />

} StackElementTyp ;<br />

typedef StackElementTyp * BottenPekarTyp ;<br />

void Pop( BottenPekarTyp *b, DataTyp *x );<br />

void Push( BottenPekarTyp *b , DataTyp x ) ;<br />

int ArTom( BottenPekarTyp b );<br />

void Baklanges( char xString[] );<br />

William Sandqvist william@kth.se<br />

StackElementTyp<br />

BottenPekarTyp<br />

NULL


Datatyper och funktionsprototyp<br />

#include <br />

#include <br />

typedef struct {<br />

int heltalsData;<br />

} DataTyp ;<br />

För att lägga till, i<br />

botten, stackelement<br />

på stacken<br />

typedef struct StackElementTyp {<br />

DataTyp d;<br />

struct StackElementTyp * next ;<br />

} StackElementTyp ;<br />

NULL<br />

typedef StackElementTyp * BottenPekarTyp ;<br />

void Pop( BottenPekarTyp *b, DataTyp *x );<br />

void Push( BottenPekarTyp *b , DataTyp x ) ;<br />

int ArTom( BottenPekarTyp b );<br />

void Baklanges( char xString[] );<br />

William Sandqvist william@kth.se<br />

BottenPekarTyp


Bokstäver i omvänd ordning<br />

int main(int argc, char *argv[])<br />

{<br />

char strang[21] = {'\0'};<br />

printf("Ge en str\204ng, max 20 tecken: --> ");<br />

scanf("%s", strang );<br />

baklanges( strang );<br />

}<br />

printf ("\nBakl\204nges blir det:\t%s\n", strang );<br />

system("PAUSE");<br />

return 0;<br />

William Sandqvist william@kth.se


aklanges()<br />

void Baklanges( char xString[] )<br />

{<br />

int i;<br />

DataTyp data;<br />

BottenPekarTyp bottenPek = NULL ;<br />

for ( i=0 ; xString[i] != '\0' ; ++i )<br />

{<br />

data.heltalsData = xString[i];<br />

Push( &bottenPek , data );<br />

}<br />

for ( i=0 ; xString[i] != '\0' ; ++i )<br />

{<br />

Pop( &bottenPek , &data );<br />

xString[i] = data.heltalsData ;<br />

}<br />

return;<br />

William Sandqvist william@kth.se<br />

}<br />

bottenPek<br />

Fyller på stacken<br />

NULL<br />

A<br />

n<br />

d<br />

e<br />

r<br />

s


Push()<br />

Både data in resp data ut<br />

Skapar stackelement ,<br />

data + <strong>pekare</strong><br />

void Push( BottenPekarTyp *b , DataTyp x )<br />

{<br />

utvärde<br />

BottenPekarTyp temp;<br />

invärde<br />

temp = malloc(sizeof( StackElementTyp ));<br />

temp->d = x ;<br />

temp->next = *b ;<br />

invärde<br />

*b = temp ;<br />

return;<br />

}<br />

utvärde<br />

invärde<br />

NULL<br />

A<br />

n<br />

d<br />

e<br />

r<br />

s<br />

William Sandqvist william@kth.se<br />

bottenPek


aklanges()- Pop()<br />

void Baklanges( char xString[] )<br />

{<br />

int i;<br />

DataTyp data;<br />

BottenPekarTyp bottenPek = NULL ;<br />

for ( i=0 ; xString[i] != '\0' ; ++i )<br />

{<br />

data.heltalsData = xString[i];<br />

Push( &bottenPek , data );<br />

}<br />

for ( i=0 ; xString[i] != '\0' ; ++i )<br />

{<br />

Pop( &bottenPek , &data );<br />

xString[i] = data.heltalsData ;<br />

}<br />

return;<br />

William Sandqvist william@kth.se<br />

}<br />

bottenPek<br />

NULL<br />

A<br />

n<br />

d<br />

e<br />

r<br />

s


Både data in resp data ut<br />

Tar bort stackelement och<br />

återför data i den borttagna<br />

tunnan via *x .<br />

Pop()<br />

invärde<br />

void Pop( BottenPekarTyp *b, DataTyp *x )<br />

{<br />

invärde<br />

BottenPekarTyp b1 = *b ;<br />

if ( !ArTom( b1 ))<br />

{<br />

*x = b1 -> d ;<br />

utvärde<br />

*b = b1 -> next ;<br />

free( b1 );<br />

}<br />

else printf("Tom stack!\n"); utvärde<br />

return;<br />

William Sandqvist william@kth.se<br />

} bottenPek<br />

NULL<br />

A<br />

A<br />

n<br />

d<br />

e<br />

r<br />

s


Baklanges()<br />

void Baklanges( char xString[] )<br />

{<br />

int i;<br />

DataTyp data;<br />

}<br />

BottenPekarTyp bottenPek = NULL ;<br />

for ( i=0 ; xString[i] != '\0' ; ++i )<br />

{<br />

data.heltalsData = xString[i];<br />

Push( &bottenPek , data );<br />

}<br />

for ( i=0 ; xString[i] != '\0' ; ++i )<br />

{<br />

Pop( &bottenPek , &data );<br />

xString[i] = data.heltalsData ;<br />

}<br />

return;<br />

William Sandqvist william@kth.se<br />

Funktionen<br />

Baklanges() tar slut<br />

och har via referensen<br />

xString uppdaterat<br />

strängen i main().<br />

bottenPek<br />

NULL<br />

A<br />

n<br />

d<br />

e<br />

r<br />

s


Kör main()<br />

int main(int argc, char *argv[])<br />

{<br />

char strang[21] = {'\0'};<br />

printf("Ge en str\204ng, max 20 tecken: --> ");<br />

scanf("%s", strang );<br />

baklanges( strang );<br />

printf ("\nBakl\204nges blir det:\t%s\n", strang );<br />

system("PAUSE");<br />

return 0;<br />

}<br />

William Sandqvist william@kth.se


Implementera en kö<br />

• en kö kan realiseras som en länkad lista<br />

via ett ”köhandtag” (struktur) håller man<br />

reda på början och slut i kön<br />

• med ”köhandtaget” kan man då lägga till<br />

data sist i kön resp plocka bort i början<br />

NULL<br />

Själva<br />

kön<br />

data<br />

<strong>pekare</strong><br />

data<br />

<strong>pekare</strong><br />

data<br />

<strong>pekare</strong><br />

William Sandqvist william@kth.se<br />

data<br />

<strong>pekare</strong><br />

”köhandtaget”<br />

börjanPek<br />

slutPek


Kö funktionsprototyper<br />

void StallDigIKon( KoTyp* , DataTyp);<br />

• placerar data sist i kön.<br />

void Nasta( KoTyp* , DataTyp* );<br />

• återför datat som är först i kön<br />

och tar sedan bort det från kön<br />

int ArTom( KoTyp );<br />

• returnerar 1 om kön är tom annars 0.<br />

DataTyp VemPaTur( KoTyp );<br />

• returnerar datat som ligger först i kön<br />

William Sandqvist william@kth.se


Kö programexempel<br />

Detta program tar emot heltal från<br />

tangentbordet och lagrar dem i en kö.<br />

På kommando kan det första talet i kön<br />

plockas bort.<br />

Provkör vid lab!<br />

William Sandqvist william@kth.se


* queue.c */<br />

#include <br />

#include <br />

typedef struct {<br />

int heltal;<br />

} DataTyp ;<br />

typedef struct KoElementTyp {<br />

DataTyp d;<br />

struct KoElementTyp * next ;<br />

} KoElementTyp ;<br />

Hur det fungerar<br />

Datat som programmet skall<br />

bearbeta inläses till en struct av<br />

typen DataTyp. Funktionen<br />

StallDigIKon() tillfogar en<br />

next-<strong>pekare</strong> och lagrar detta , data<br />

och <strong>pekare</strong>, i en ny struktur av<br />

typen KoElementTyp. Denna<br />

inlänkas sedan sist i kön.<br />

NULL<br />

Själva<br />

kön<br />

data<br />

<strong>pekare</strong><br />

data<br />

<strong>pekare</strong><br />

data<br />

<strong>pekare</strong><br />

William Sandqvist william@kth.se<br />

data<br />

<strong>pekare</strong><br />

”köhandtaget”<br />

börjanPek<br />

slutPek


Hur det fungerar<br />

typedef struct KoElementTyp<br />

{<br />

DataTyp d;<br />

struct KoElementTyp *next ;<br />

} KoElementTyp ;<br />

typedef KoElementTyp * KoElementPekarTyp ;<br />

typedef struct KoTyp<br />

{<br />

KoElementPekarTyp koBorjanPek, koSlutPek ;<br />

} KoTyp ; StackElementTyp *BottenPekarTyp ;<br />

NULL<br />

Själva<br />

kön<br />

data<br />

<strong>pekare</strong><br />

data<br />

<strong>pekare</strong><br />

data<br />

<strong>pekare</strong><br />

William Sandqvist william@kth.se<br />

data<br />

<strong>pekare</strong><br />

”köhandtaget”<br />

börjanPek<br />

slutPek


Ny till slutet av kön<br />

Ställ dig i kön<br />

data<br />

<strong>pekare</strong><br />

NULL<br />

data<br />

<strong>pekare</strong><br />

data<br />

<strong>pekare</strong><br />

data<br />

<strong>pekare</strong><br />

”köhandtaget”<br />

börjanPek<br />

slutPek<br />

NULL<br />

data<br />

<strong>pekare</strong><br />

data<br />

<strong>pekare</strong><br />

data<br />

<strong>pekare</strong><br />

data<br />

<strong>pekare</strong><br />

”köhandtaget”<br />

börjanPek<br />

William Sandqvist william@kth.se<br />

slutPek


StallDigIKon()<br />

void StallDigIKon( KoTyp* koPek, DataTyp x)<br />

{<br />

KoElementPekarTyp temp;<br />

temp = malloc(sizeof(KoElementTyp)) ;<br />

temp->d = x;<br />

temp->next = NULL ;<br />

if ( ArTom( *koPek ))<br />

koPek->koBorjanPek = koPek->koSlutPek = temp ;<br />

else<br />

{<br />

koPek->koSlutPek->next = temp ;<br />

koPek->koSlutPek = temp ;<br />

}<br />

return ;<br />

}<br />

William Sandqvist william@kth.se


Nästa!<br />

Ska betjänas<br />

NULL<br />

data<br />

<strong>pekare</strong><br />

data<br />

<strong>pekare</strong><br />

data<br />

<strong>pekare</strong><br />

data<br />

<strong>pekare</strong><br />

”köhandtaget”<br />

börjanPek<br />

Ny först i kön!<br />

slutPek<br />

NULL<br />

data<br />

<strong>pekare</strong><br />

data<br />

<strong>pekare</strong><br />

data<br />

<strong>pekare</strong><br />

”köhandtaget”<br />

börjanPek<br />

William Sandqvist william@kth.se<br />

slutPek


Nasta()<br />

void Nasta( KoTyp* koPek, DataTyp* xPek)<br />

{<br />

KoElementPekarTyp temp = koPek->koBorjanPek ;<br />

}<br />

if ( !ArTom( *koPek ) )<br />

{<br />

*xPek = temp -> d ;<br />

koPek->koBorjanPek = temp->next ;<br />

free( temp );<br />

}<br />

else<br />

printf("Tom k\224! \n");<br />

return;<br />

William Sandqvist william@kth.se


int main(int argc, char *argv[])<br />

{<br />

char c ;<br />

DataTyp data;<br />

KoTyp ko = {NULL, NULL};<br />

Info();<br />

main()<br />

}<br />

while (printf("--> "),scanf(" %c",&c), c != 'a' )<br />

{<br />

if ( c=='+'){scanf("%d", &data.heltal); StallDigIKon( &ko, data ); }<br />

else if ( c=='-' )<br />

if ( ArTom( ko ))<br />

printf("Tom k\224! \n");<br />

else {<br />

Nasta( &ko, &data );<br />

printf("%d har tagits bort från k\224n!\n", data.heltal);<br />

}<br />

}<br />

system("PAUSE");<br />

return 0;<br />

William Sandqvist william@kth.se


ArTom()<br />

int ArTom(KoTyp k)<br />

{<br />

if(k.koBorjanPek != NULL)<br />

return 0; /* Är INTE tom */<br />

else<br />

return 1; /* Är tom */<br />

}<br />

Inte mycket att bråka om …<br />

William Sandqvist william@kth.se

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!