Ćwiczenie 7
Abstrakcyjne typy danych Listy uporządkowane 1. Definicja listy uporządkowanej
2. Przedstawienie abstrakcyjnego algorytmu wstawiania danych do listy uporządkowanej
3. Przedstawienie abstrakcyjnego algorytmu usuwania danych z listy uporządkowanej
4. Przedstawienie abstrakcyjnego algorytmu wyszukiwania danych na liście uporządkowanej
5. Definicja ADT typu Lista uporządkowana 6. Definicja interfejsu Listy uporządkowanej
7. Przedstawienie implementacji listy uporządkowanej w postaci rekurencyjnej struktury danych typu lista jednokierunkowa nieuporządkowana (lista wiązana)
l ilustracja wstawiania, usuwania i wyszukiwania
l
przedstawienie kodu w C++ (zastosowanie w kodzie funkcji zasady odseparowania wprowadzania danych i wyświetlania danych z tablicy od kodu funkcji tablicy! Dane do funkcji przekazywane są przez nagłówek, dane z funkcji można przekazywać podobnie lub przez instrukcję return) l Ocena czasochłonności operacji wstawiania, usuwania i wyszukiwania 8.Przedstawienie tablicowej implementacji listy uporządkowanej
l ilustracja wstawiania, usuwania i wyszukiwania
l
przedstawienie kodu w C++ (zastosowanie w kodzie funkcji zasady
odseparowania wprowadzania danych i wyświetlania danych z tablicy od
kodu funkcji tablicy! Dane do funkcji przekazywane są przez nagłówek,
dane z funkcji można przekazywać podobnie lub przez instrukcję return)
l Ocena czasochłonności operacji wstawiania, usuwania i wyszukiwania
Lista uporządkowana- jednokierunkowa Etap 1 - Opis ADT
Nazwa typu - Lista elementów
Własności typu: Potrafi przechować ciąg elementów o dowolnym rozmiarze Dostępne działania: Inicjalizacja listy
Określenie, czy lista jest pusta Dodanie elementu do listy,
Wyszukanie miejsca na liście przez większym lub równym elemencie na liście lub na końcu listy
Usuwanie z listy,
Etap 2 - Budowa interfejsu
typedef int dane;
// dane umieszczone liścietypedef struct ELEMENT* stos;
//nazwa wskaźnika na element stosustruct ELEMENT {
dane Dane;
stos Nastepny;
};
struct Lista
{ stos Poczatek;
stos Gdzie;
};
void Inicjalizacja(lista & Lista);
{działanie: inicjuje liste
warunki wstępne: Lista wskazuje na pierwszy element warunki końcowe: Lista zostaje zainicjowana jako pusta}
inline int Pusty(lista Lista) { return Lista.Poczatek==NULL; }
{działanie: określa, czy lista jest pusta; typ inline, bo często wywoływana warunki wstępne: Lista jest zainicjowana,
warunki końcowe: funkcja zwraca 1, jeśli lista pusta, w przeciwnym wypadku 0}
int Szukaj(lista& Lista, dane Dana);
{ działanie: szuka elementu na liście
warunki początkowe: Lista wskazuje na zainicjowaną listę,
warunki końcowe: funkcja zwraca wskazanie Lista.Gdzie na element wskazujący na element o wartości większej (wtedy funkcja zwraca wartość równą 3) lub równej wartości Dana (wtedy funkcja zwraca wartość równą 2) lub na końcu listy, gdy nie znaleziono większego lub równego elementu na liście – wtedy funkcja zwraca wartość równą 1 i wartość Lista.Gdzie wskazuje na ostatni element. Jeśli znaleziono miejsce na początku listy (pierwszy element jest większy lub równy Dana), Lista.Gdzie jest równe NULL. Gdy lista jest pusta, wtedy funkcja zwraca 0.}
int Wstaw(lista& Lista, dane Dana);
{ działanie: dodaje element w dowolne miejsce ciągu umieszczonego na liście warunki początkowe: Dane jest daną do wstawienia na miejscu pośrednio
wskazywanym przez Lista.Gdzie zainicjowanej listy Lista.
warunki końcowe: funkcja dodaje daną Dana na miejscu określonym przez funkcję Szukaj, jeśli zwróci wartość 0 (wstawianie do pustej listy), lub wartość 1 (wstawianie na końcu listy) lub wartość 2 i 3 (wstawianie wewnątrz listy, odpowiednio przed równym lub większym elementem lub na początku listy) i funkcja Wstaw zwraca 1, w przeciwnym wypadku zwraca 0}
int Usun(lista& Lista);
{ działanie: usuwa element na dowolnym miejscu w ciągu wstawionym do listy warunki początkowe: Lista jest zainicjowaną listą, Lista.Gdzie jest pośrednim
wskazaniem na element usuwany określony przez funkcję Szukaj, gdy zwróci wartość 2
warunki końcowe: funkcja usuwa z listy element określony przez funkcję
Szukaj, gdy zwróci ona wartość 2 oraz wraca dane umieszczone na
usuwanym elemencie }
szukanie i wstawianie do listy w przed większym lub równym elementem lub na końcu listy, gdy nie znaleziono elementu równego lub większego (wynik funkcji Szukaj jest dowolny)
1) Lista.Poczatek=NULL „B”
Nowy „A”
Lista.Gdzie=NULL Nowy
Nowy „B”
2) Lista.Poczatek=Nowy 1) Nowy->Nastepny=Lista.Poczatek NULL
Nowy
„B”
Lista.Poczatek
„Z” NULL Lista.Gdzie
1) Nowy->Nastepny=Lista.Gdzie->Nastepny 2) Lista.Gdzie->Nastepny=Nowy
„B”
Lista.Poczatek
„Z” NULL Lista.Gdzie=NULL
LL
1) Nowy->Nastepny=Lista.Poczatek Nowy
„B”
Lista.Poczatek
NULL „Z”
Lista.Gdzie
„B”
Lista.Poczatek
„Z” NULL Lista.Gdzie=NULL
LL
2) Lista.Poczatek=Nowy Gdzie->Nastepny=Nowy
Nowy „A”
Lista.Poczatek „B”
„Z” NULL
„A” Nowy
„B” „D”
Lista.Poczatek
Lista.Gdzie
„A”
„D”
„Z”
Lista.Gdzie
1) Nowy->Nastepny=Lista.Gdzie->Nastepny 2) Lista.Gdzie->Nastepny=Nowy
Nowy
NULL
szukanie i usuwanie z listy równych elementów (wynik funkcji Szukaj jest równy 2)
Lista.Gdzie=NULL
„B”
1) Pom=Lista.Poczatek
2) Lista.Poczatek=Lista.Poczatek->Nastepny NULL
Lista.Poczatek „B”
„Z” NULL Lista.Gdzie
1) Lista.Gdzie->Nastepny=Pom->Nastepny 2) Pom=Lista.Gdzie->Nastepny
Lista.Poczatek „B”
„Z” NULL Lista.Gdzie=NULL
LL
2)Lista.Poczatek=Lista.Poczatek->Nastepny
Lista.Poczatek „B”
Lista.Gdzie
„B”
Lista.Poczatek
„Z” NULL Lista.Gdzie=NULL
LL
1) Pom=Lista.Poczatek Gdzie->Nastepny=Nowy
„A”
Lista.Poczatek „B”
„Z” NULL
„A”
„B” „D”
Lista.Poczatek
Lista.Gdzie
„A” „Z”
Lista.Gdzie
2) Lista.Gdzie->Nastepny=Pom->Nastepny 1)Pom =Lista.Gdzie->Nastepny
NULL
NULL
//Zofia Kruczkiewicz
#include <conio.h>
#include <stdio.h>
//1. interfejs ADT listy nieuporządkowanej
typedef int dane; // dane umieszczone liście
typedef struct ELEMENT* stos; //nazwa wskaźnika na element listy struct ELEMENT
{
dane D ane;
stos Nastepny;
};
//funkcje ADT listy struct lista
{ stos Poczatek;
stos Gdzie;
};
void Inicjalizacja(lista& Lista);
inline int Pusty(lista Lista);
int Szukaj(lista& Lista, dane Klucz);
int Szukaj(lista& Lista, long Miejsce);
int Wstaw(lista& Lista, dane Dana);
dane Usun(lista& Lista);
//2. funkcje we/wy dla danych umieszczonych na liście void Pokaz_dane (dane Dana);
dane Dane(char* s);
//3. funkcje ogólnego przeznaczenia void Komunikat(char*);
char Menu(const int ile, char *Polecenia[]);
//4. elementy programu const int Esc=27;
const int POZ=4;
char * Tab_menu[POZ] = { "1 : Wstawianie do posortowanej listy ",
"2 : Usuwanie z posortowanej listy", "3 : Wydruk listy wraz z jej usuwaniem", " >Esc Koniec programu"};
//5. funkcje klienta korzystające ze listy void Wstaw_do_listy(lista& Lista);
void Usun_z_listy(lista& Lista);
void Wyswietl_usun_z_listy(lista& Lista);
void main(void)
{ lista Lista;
char Wybor;
clrscr();
Inicjalizacja(Lista);
do
{ Wybor= Menu(POZ, Tab_menu);
switch (Wybor)
{ case '1' : Wstaw_do_listy(Lista); break;
case '2' : if (Pusty(Lista))
Komunikat("\nLista pusta\n");
else (Usun_z_listy(Lista)); break;
case '3' : if (Pusty(Lista))
Komunikat("\nLista pusta\n") ;
else Wyswietl_usun_z_listy(Lista); break;
}
} while (Wybor !=Esc );
}
//**************funkcje klienta korzystające z listy***********
void Wstaw_do_listy(lista& Lista)
{ dane Dana= Dane("Podaj dane do wstawienia: ");
Szukaj(Lista,Dana);
if (!Wstaw(Lista, Dana))
Komunikat("\nBrak pamieci");
else Komunikat("\nWstawiono do listy");
}
void Usun_z_listy(lista& Lista)
{ dane Dana= Dane("Podaj dane do usuniecia: ");
if (Szukaj(Lista, Dana)==2) { Usun(Lista);
Komunikat("\n Usunieto z listy");}
else Komunikat("\nNie znaleziono danej");
}
void Wyswietl_usun_z_listy(lista& Lista) { dane d; lista Gdzie;
while (!Pusty(Lista)) { Szukaj(Lista, 1L);
d=Usun(Lista);
Pokaz_dane(d);}
}
//*********interfejs ADT listy************
void Inicjalizacja(lista& Lista) { Lista.Poczatek = NULL;}
inline int Pusty(lista Lista)
{ return Lista.Poczatek==NULL;}
int Szukaj(lista& Lista, dane Klucz ) { Lista.Gdzie = NULL;
if (Pusty(Lista)) return 0;
stos Nast=Lista.Poczatek;
while (Nast->Dane<Klucz && Nast->Nastepny !=NULL) { Lista.Gdzie= Nast;
Nast = Nast->Nastepny;
}
if (Nast->Dane<Klucz) { Lista.Gdzie= Nast;
return 1;}
else
if (Nast->Dane==Klucz) return 2;
else return 3;
}
int Szukaj(lista& Lista, long Miejsce) { long Numer= 1;
Lista.Gdzie = NULL;
if (Pusty(Lista)) return 0;
stos Nast = Lista.Poczatek;
while ((Nast->Nastepny !=NULL) && Miejsce != Numer) { Lista.Gdzie= Nast;
Nast = Nast->Nastepny;
Numer++;
}
if (Miejsce == Numer+1) { Lista.Gdzie= Nast;
return 1;}
else
if ( Miejsce == Numer) return 2;
else return 3;
}
int Wstaw(lista& Lista, dane Dana) { stos Nowy = new ELEMENT;
if (Nowy !=NULL) Nowy->Dane=Dana;
else return 0;
if (Lista.Gdzie==NULL)
{ Nowy->Nastepny= Lista.Poczatek;
Lista.Poczatek= Nowy;
} else {
Nowy->Nastepny = Lista.Gdzie->Nastepny;
Lista.Gdzie->Nastepny = Nowy;
}
return 1;
}
dane Usun(lista& Lista) { stos Pom;
if (Lista.Gdzie==NULL) {
Pom= Lista.Poczatek;
Lista.Poczatek= Lista.Poczatek->Nastepny;
} else {
Pom= Lista.Gdzie->Nastepny;
Lista.Gdzie->Nastepny= Pom->Nastepny;
}
dane d=Pom->Dane;
delete Pom;
return d;
}
//*******funkcje we/wy dla danych umieszczonych na liście*********
dane Dane(char* s) { int a;
do
{ fflush(stdin);
printf("\n\n%s",s);
} while (scanf("%d",&a)!=1);
return a;
}
void Pokaz_dane(dane Dana) {
printf("\nNumer: %d\n", Dana);
printf("Nacisnij dowolny klawisz...\n"); getch();
}
//*********funkcje ogólnego przeznaczenia************
char Menu(const int ile, char *Polecenia[]) {
clrscr();
for (int i=0; i<ile;i++)
printf("\n%s",Polecenia[i]);
return getch();
}
void Komunikat(char* s) { printf(s); getch(); }
Etap 3 - Implementacja za pomocą dynamicznej tablicy
//ile=3, Gdzie=1
1. for(int i=ile; i>Gdzie; i--) tab[i]=tab[i-1]
0 pamięć dynamiczna
(sterta) tab
2 pamięć statyczna
1
3 4 Gdzie
Wstawianie
2. tab[Gdzie]=dane (sterta)
3. ile++;
// ile=4
//ile=4, który=1
1. for(int i=Gdzie; i<ile-1; i++) tab[i]=tab[i+1]
//ile=4
0 pamięć dynamiczna
(sterta) tab
2 pamięć statyczna
1
3 4 Gdzie
Usuwanie
2. ile--;
// ile=3
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
//1. interfejs ADT listy uporządkowanej
typedef int dane; / / dane umieszczone liscie
struct lista {
int ile, rozmiar, Gdzie;
dane* tab;
};
//Identyczny tekst programu jak dla listy wykonanej w postaci listy //wiązanej
//funkcje ADT listy void Inicjalizacja(lista& Lista);
inline int Pusty(lista Lista);
int Szukaj(lista& Lista, dane Klucz);
int Szukaj(lista& Lista, long Miejsce);
int Wstaw(lista& Lista, dane Dana);
dane Usun(lista& Lista);
//2. funkcje we/wy dla danych umieszczonych na liście void Pokaz_dane (dane Dana);
dane Dane(char* s);
//3. funkcje ogólnego przeznaczenia void Komunikat(char*);
char Menu(const int ile, char *Polecenia[]);
//4. elementy programu const int Esc=27;
const int POZ=4;
char * Tab_menu[POZ] = { "1 : Wstawianie do posortowanej listy ",
"2 : Usuwanie z posortowanej listy", "3 : Wydruk listy wraz z jej usuwaniem", " >Esc Koniec programu"};
//5. funkcje klienta korzystające ze listy void Wstaw_do_listy(lista& Lista);
void Usun_z_listy(lista& Lista);
void Wyswietl_usun_z_listy(lista& Lista);
void main(void) { lista Lista;
char Wybor;
clrscr();
Inicjalizacja(Lista);
do
{ Wybor= Menu(POZ, Tab_menu);
switch (Wybor)
{ case '1' : Wstaw_do_listy(Lista); break;
case '2' : if (Pusty(Lista))
Komunikat("\nLista pusta\n");
else (Usun_z_listy(Lista));
break;
case '3' : if (Pusty(Lista))
Komunikat("\nLista pusta\n") ; else Wyswietl_usun_z_listy(Lista);
break;
}
} while (Wybor !=Esc );
}
//*********interfejs ADT listy-tablicy************
void Inicjalizacja(lista& Lista) {Lista.ile=Lista.rozmiar=0;
Lista.tab=NULL;
}
//prywatna funkcja do zmiany rozmiaru tablicy int Zmien(lista& Lista, int delta)
{ dane* pom;
pom = (dane*)realloc(Lista.tab,sizeof(dane)*(Lista.rozmiar+delta));
if (pom)
{ Lista.tab=pom;
Lista.rozmiar+=delta;}
return pom!=NULL;
}
int Pusty (lista Lista)
int Szukaj(lista& Lista, long Miejsce) { if (Lista.ile==0)
{Lista.Gdzie=0;
return 0;}
Lista.Gdzie=--Miejsce;
if (Miejsce>=0)
if( Miejsce<=Lista.ile-1) return 2;
else
if (Miejsce==Lista.ile) return 1;
return 3;
}
int Szukaj(lista& Lista, dane Klucz ) { if (Lista.ile==0)
{Lista.Gdzie=0;
return 0;}
Lista.Gdzie=0;
while (Lista.tab[Lista.Gdzie]<Klucz && Lista.Gdzie<Lista.ile) Lista.Gdzie++;
if (Lista.Gdzie==Lista.ile) return 1;
else
if (Lista.tab[Lista.Gdzie]==Klucz) return 2;
else return 3;
}
int Wstaw(lista& Lista, dane Dana) {if (!Zmien(Lista,1)) return 0;
for (int i=Lista.ile; i>Lista.Gdzie; i--) Lista.tab[i]=Lista.tab[i-1];
Lista.tab[Lista.Gdzie]=Dana;
Lista.ile++;
return 1;}
dane Usun(lista& Lista)
{dane d =Lista.tab[Lista.Gdzie];
for (int i=Lista.Gdzie; i<Lista.ile-1; i++) Lista.tab[i]=Lista.tab[i+1];
Lista.ile--;
Zmien(Lista,-1);
if (Lista.ile==0) Inicjalizacja(Lista);
return d; }