Wykład 5

Transkrypt

Wykład 5
WYKŁAD 10
Zmienne o złożonej budowie
Statyczne i dynamiczne struktury danych:
lista, kolejka, stos, drzewo
Programy: c5_1.c, c5_2, c5_3, c5_4, c5_5
Tomasz Zieliński
ZMIENNE O ZŁOŻONEJ BUDOWIE (1)
Zmienne typu prostego:
char, short, int, long, float, double
(unsigned) char, short, int, long
Przykład:
char
c, s[10];
int
i, j, k, l, m[3][3], n[5][5][5];
float
x, y, z
c = getchar();
strcpy(s, ”Kowalski”);
i = 10; j = 20;
k = i+j; l = i*j;
m[0][1] = 1;
n[0][1][2] = m[1][2] + 128;
ZMIENNE O ZŁOŻONEJ BUDOWIE (2)
Zmienne typu złożonego (struktury)
Przykład:
struct osoba { <--------------- typ zmiennych osoba
char nazwisko[20];
char imie[10];
int wiek;
int wzrost;
} student;
<--------------- delaracja zmiennej student typu osoba
strcpy( student.nazwisko, ”Kowalski” );
strcpy( student.imię, ”Jan” );
student.wiek = 23;
student.wzrost = 187;
// inicjalizacja zmiennej
//
//
//
struct osoba pacjent, student = {”Kowalski”, ”Jan”, 23, 187};
ZMIENNE O ZŁOŻONEJ BUDOWIE (3)
Przykład:
struct osoba { <---------- typ zmiennych osoba
char nazwisko[20];
char imie[10];
int wiek;
int wzrost;
} *pstudent;
<--------- delaracja wskaźnika do zmiennej student
ZASADA ZAPISU:
*xxx.yyy = xxx->yyy
strcpy( pstudent->nazwisko, ”Kowalski” ); // inicjalizacja zmiennej
strcpy( pstudent->imię, ”Jan” );
// inicjalizacja zmiennej
pstudent->wiek = 23;
pstudent->wzrost = 187;
struct osoba *ppacjent, *pstudent = {”Kowalski”, ”Jan”, 23, 187};
STRUKTURY DANYCH (1) - statyczne i dynamiczne
Lista:
Kolejka:
Stos:
Drzewo:
Statycznie:
użytkowników komputera, uczestników wycieczki,
studentów, pacjentów, ...
dokumentów czekających na wydrukowanie przez
drukarkę sieciową
danych o przerwanych (zawieszonych) programach,
czekających na wykonanie przez procesor
katalogów zbiorów na dysku komputera
tablica, składająca się z wielu elementów jednego
typu, często nie w pełni wypełniona, czasami
przepełniona
Dynamicznie: łańcuch węzłów (bloków komórek w pamięci), które na
siebie pokazują
STRUKTURY DANYCH (2) - statyczne i dynamiczne
Kolejka statycznie
A
B
początek
I
J
K
L
C
D
Kolejka dynamicznie
wezeł nr 1
komórki
pamięci
E
koniec
A
F
G
wezeł nr 2
komórki
pamięci
adr
adr
C
adr
H
początek
koniec
B
wezeł nr 3
komórki
pamięci
adres pierwszego
węzła
początek
struct kolejka {
int
początek;
int
koniec;
struct osoba tablica[ MAX ];
}
|
|
|
|
|
|
|
|
koniec
adres ostatniego
węzła
struct kolejka {
int początek;
int koniec;
}
struct węzeł {
struct osoba student;
struct węzeł *następny;
}
DYNAMICZNE STRUKTURY DANYCH (1)
Węzły
=====================================================
struct węzeł1 {
struct węzeł2 {
struct element info;
struct element info;
struct węzeł1 *następny;
struct węzeł2 *poprzedni;
};
struct węzeł2 *następny;
};
=====================================================
Przykład:
struct element {
// w każdym węźle jest umieszczona
int
liczba;
// jedna liczba, np. 220
char litera;
// i jedna litera, np. V (voltów)
};
Dynamiczna alokacja pamięci dla węzła i jej zwalnianie:
pwęzeł = (struct węzeł *) malloc( sizeof( struct węzeł ) );
free( pwęzeł );
DYNAMICZNE STRUKTURY DANYCH (2)
Lista jednostronna
info A
adr
info B
adr
adr
info B
adr
info X
adr
info Y
początek
info A
info C
początek
info A
początek
info X
adr
info B
adr
adr
info Y
DODAWANIE
adr
info X
adr
info Y
USUWANIE
DYNAMICZNE STRUKTURY DANYCH (3)
Lista dwustronna
info A
adr
adr
info B
adr
adr
info X
adr
adr
info Y
info B
adr
adr
info X
adr
adr
info Y
info B adr
adr
wskaźnik
adr
info A
adr
adr
adr
wskaźnik
info B adr
adr
adr
info C adr
info X adr
DODAWANIE
info A adr
adr
USUWANIE
info X adr
DYNAMICZNE STRUKTURY DANYCH (4)
Kolejka FIFO (First In First Out) w statycznym buforze kołowym
A
B
C
D
początek
A
B
E
koniec
C
D
E
początek
A
I
J
B
F
koniec
C
D
E
F
początek
koniec
L
F
K
koniec
G
początek
H
DYNAMICZNE STRUKTURY DANYCH (5)
Kolejka FIFO (First In First Out) dynamicznie
A
adr
B
adr
początek
A
C
adr
koniec
adr
B
adr
C
adr
początek
A
D
adr
koniec
adr
B
początek
adr
C
adr
D
koniec
adr
DYNAMICZNE STRUKTURY DANYCH (6)
STOS statycznie i dynamicznie
Statyczna tablica
A
B
C
D
Dynamiczna struktura
E
C
B
C
D
E
F
ostatni
A
B
C
D
ostatni
B
adr
A
adr
ostatni
ostatni
A
adr
D
adr
C
adr
B
adr
A
adr
adr
C
adr
B
adr
A
adr
ostatni
D
ostatni
DYNAMICZNE STRUKTURY DANYCH (7) - drzewo binarne
A
14
adr L adr P
B
C
9
adr L adr P
adr L
D
21
E
5
16
F
30
adr L adr P
adr P
G
6
H
15
WYPISYWANIE ELEMENTÓW:
IN-ORDER
lewo, wypisz, prawo
I
20
5, 6, 9, 14, 15, 16, 20, 21, 30
D, G, B, A, H, E, I, C, F
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
PRE-ORDER
POST-ORDER
wypisz, lewo, prawo
lewo, prawo, wypisz
A, B, D, G, C, E, H, I, F
G, D, B, H, I, E, F, C, A
DYNAMICZNE STRUKTURY DANYCH (8) - drzewo binarne
Poprzednia strona:
struct węzeł {
struct element
struct węzeł
struct węzeł
};
info;
*lewy;
*prawy;
np. ------>
struct element {
char litera;
int
liczba;
}
Przykład:
+
A
A + (B - C) * (D + E)
*
-
B
+
C
D
E
/* Przyklad 5.5 - DRZEWO BINARNE - jako struktura dynamiczna
/*
wprowadzaj liczby naturalne z klawiatury
/*
znajdz szybko pierwsze powtorzenie
/*
wydrukuj od najmniejszej do najwiekszej
*/
*/
*/
*/
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
struct wezel {
int
struct wezel
struct wezel
};
/* struktura wezla */
info;
*lewy;
*prawy;
typedef struct wezel *ADRwezel;
ADRwezel PobierzWezel( void );
/* deklaracja adresu do wezla */
/* pobranie wolnego wezla
*/
ADRwezel NowaGałąź( int x );
void PoLewej( ADRwezel p, int x);
void PoPrawej( ADRwezel p, int x);
/* wygeneruj kolejna galaz
*/
/* wstaw liczbe x do lewej galezi */
/* wstaw liczbe x do prawej galezi */
void Preorder( ADRwezel p );
void
Inorder( ADRwezel p );
void Postorder( ADRwezel p );
/* kolejnosc 1 */
/* kolejnosc 2 */
/* kolejnosc 3 */
/* program glowny ---------------------------------------------------------------------- */
void main()
{
int liczba;
ADRwezel
ADRwezel
pdrzewo;
p, q;
printf( "\n Podawaj liczby naturalne. Koniec = jakas litera ! \n\n ");
scanf( "%d", &liczba );
pdrzewo = NowaGałąź( liczba );
/* podaj pierwsza liczbe
*/
/* bedzie ona korzeniem drzewa */
while ( scanf("%d", &liczba ) != NULL )
// wczytuj kolejne liczby
{
p = q = pdrzewo;
while( liczba != p->info && q != NULL ) // powtarzaj kiedy rozne
{
// 1. rozne liczby
p = q;
// 2. drzewo jest nizej
if ( liczba < p->info )
q = p->lewy;
// jesli mniejsze, to w lewo
else
q = p->prawy;
// jesli wieksze, to w prawo
}
if ( liczba == p->info )
// znaleziono podana liczbe/
printf(" Liczba %d zostala juz wczytana !\n", liczba );
else if ( liczba < p->info )
// koniec galezi drzewa
PoLewej( p, liczba );
// wstaw liczbe do lewej odnogi
else
PoPrawej( p, liczba);
// wstaw liczbe do prawej odnogi
}
printf("\n Inorder :\n");
Inorder( pdrzewo );
// Rozne sposowy wyszukiwania
// elementow w drzwie binarnym
printf("\n Preorder :\n");
Preorder( pdrzewo );
printf("\n Postorder :\n");
Postorder( pdrzewo );
printf("\n");
}
/* Funkcje pomocnicze----------------------------------------------------------------- */
ADRwezel PobierzWezel( void )
{
ADRwezel p;
/* zwraca adres nowego wezla */
p = (ADRwezel) malloc( sizeof( struct wezel ) ) ;
return( p );
}
/*------------------------------------------------------------------------------------------------*/
ADRwezel NowaGałąź( int x )
{ ADRwezel p;
/* wygeneruj kolejna galaz */
p = PobierzWezel();
p->info = x;
p->lewy = NULL; p->prawy = NULL;
return( p );
}
/*------------------------------------------------------------------------------------------------*/
void PoLewej( ADRwezel p, int x )
/* wstaw liczbe x do lewej galezi */
{
if ( p == NULL )
printf( "Brak pamieci !\n" );
else if ( p->lewy != NULL )
printf( "Lewy zajety !\n" );
else
p->lewy = NowaGałąź( x );
}
/*------------------------------------------------------------------------------------------------*/
void PoPrawej( ADRwezel p, int x) /* wstaw liczbe x do prawej galezi */
{
if ( p == NULL )
printf( "Brak pamieci !\n");
else if ( p->prawy != NULL )
printf( "Prawy zajety !\n");
else
p->prawy = NowaGałąź( x );
}
/*------------------------------------------------------------------------------------------------*/
void Preorder( ADRwezel p )
{ if ( p != NULL )
{
printf(" %5d ", p->info);
Preorder( p->lewy );
Preorder( p->prawy );
}
}
/* kolejnosc 1 */
/* info
*/
/* idz w lewo */
/* idz w prawo */
/*------------------------------------------------------------------------------------------------*/
void Inorder( ADRwezel p )
/* kolejnosc 2 */
{
if ( p != NULL )
{
Inorder( p->lewy );
/* idz w lewo */
printf(" %5d ", p->info);
/* info
*/
Inorder( p->prawy );
/* idz w prawo */
}
}
/*------------------------------------------------------------------------------------------------*/
void Postorder( ADRwezel p )
{
if ( p != NULL )
{
Postorder( p->lewy );
Postorder( p->prawy );
printf(" %5d ", p->info);
}
}
/* kolejnosc 3 */
/* idz w lewo */
/* idz w prawo */
/* info
*/