Drzewo binarne
Projekt: przedstawiający strukturę drzewa binarnego.
Wymagania programu:
– plik wejściowy input.txt posiada:
- w linii 1 – ciąg liczb oddzielonych średnikami,
- w linii 2 – liczbę wyszukiwaną,
– plik wyjściowy output.txt posiada:
- w linii 1 – ilość szukaną,
- w linii 2 – czas wyszukania,
- w linii 3 – rodzica (jeśli liczba istnieje w drzewie, jeśli nie wystosowany jest odpowiedni komunikat a sam plik się na tym kończy),
- w linii 4 – lewe dziecko (lub jego brak – NULL),
- w linii 5 – prawe dziecko (lub jego brak – NULL),
- w linii 6 – ścieżkę do liczby wyszukanej oddzielaną myślnikami.
Zasada działania:
Użytkownik po wystartowaniu programu posiada dwie możliwości:
1. Wygenerować nowy plik input po podaniu ilości linii drzew (tworzone są w taki sposób aby zapełnić całe drzewo np. dla 3 linii losowanych jest 7 liczb),
2. Wykorzystać własny plik input (w przypadku jego braku zostanie wygenerowany nowy),
po czym podaje liczbę do wyszukania, tworzony jest plik wyjściowy z zapisanymi danymi.
Dodatkowo wyświetlane jest czytelne drzewo binarne oraz krótkie w razie konieczności komunikaty.
Wykorzystane dane wejściowe…
-593;-389;-506;744;-6;381;-655;-50;357;-60;-817;-647;449;488;-446
-6
Dane wyjściowe…
Liczba do wyszukania: -6
Czas wykonania (w milisekundach): 0
Rodzic to: -389
Lewo: 744
Prawo: 381
Ścieżka: (-6)-(-389)-(-593)
Galeria:
Kod programu:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.StringTokenizer;
import javax.swing.JOptionPane;
public class glowna
public static void main(String[] args) throws IOException {
//Program posiada 2 możliwosci:
// A)użytkownik posiada swój własny plik input.txt
// B)program generuje wlasny, użytkownik ustala ilość linii drzewa oraz wyszukiwany element
File pliko = new File("output.txt"); //Tworzy plik output.txt
pliko.createNewFile();
int ilosc_liczb = 0; //Zmienna potrzebna do obliczenia ilosci liczb w zaleznosci od linii drzew (opcja B)
//lub odczytania ilosci liczb z pliku (opcja A)
int czyIstnieje = 0; //Switch wybierający pomiedzy opcją A lub B
String linia; //Do wykorzystania string tokenizera
int ile_liczb=3; //Ilość fragmentów w linii (liczba lub zbiór spacjii)
double ilosc_spacji=20; // Ustala odstępy pomiędzy liczbami podczas rysowania drzewa w programie (im więcej
//linii tym większe odstępy
int m=1; //Dodatkowa zmienna
String liczba; //Tymczasowa zmienna wykorzystana przy odczytywaniu zmiennych z pliku
int ilosc_lin = 100; //Startowa zmienna (później modyfikowana)
int n=0; //Liczba wyszukiwana (później modyfikowana)
int sw=0; //Zmienna wykorzystywana w switchu
try{ //Zabezpieczenie gdy zostanie podana np. litera lub nieprzyjmowana wartość plik będzie wygenerowany
sw = Integer.parseInt(JOptionPane.showInputDialog("1.Mam swoj plik input \n2.Wygeneruj\n\nWybierz 1 lub 2!"));
}catch(Exception e){
System.out.print("BŁĄD ");}
switch (sw){
case 1 : {
File plikz = new File("input.txt");
if(plikz.exists() == true)
{
czyIstnieje=1; //Na podstawie tej zmiennej uruchamiane są niektóre fragmenty kodu
FileReader plik=new FileReader("input.txt");
BufferedReader bufor=new BufferedReader(plik);
linia = bufor.readLine();
StringTokenizer token=new StringTokenizer(linia,";");
ilosc_liczb=token.countTokens(); //Zliczenie ilości liczb w przypadku własnego pliku
bufor.close();
}
else
{
System.out.print("Plik nie istnieje zostanie więc wygenerowany\n");
czyIstnieje=0;
}
break;
}
case 2 : {
czyIstnieje=0;
break;
}
default : {
System.out.print("Podano złą daną. Plik zostanie wygenerowany\n");
czyIstnieje=0;
}
}
if(czyIstnieje==0) //Generowanie pliku
{
File pliki = new File("input.txt");
pliki.createNewFile();
//Zapis losowych liczb do pliku z przedziału ((-1000)-1000)////////////////////////////////////
ilosc_lin=Integer.parseInt(JOptionPane.showInputDialog("Ile linii drzewa chcesz utworzyć?"));
int liczb_w_lini=1; //Wymagane do obliczenia ilości liczb
for(int s=1;s<ilosc_lin;s++) //Oblicza odstępy w zależności od ilości lini (im więcej tym większe)
ilosc_spacji=ilosc_spacji*2;
for (int z=1;z<=ilosc_lin;z++) //Pętla obliczająca ilość liczb
{
ilosc_liczb=ilosc_liczb+liczb_w_lini;
liczb_w_lini=liczb_w_lini*2;
}
}
int tab[] = new int[ilosc_liczb+1]; //Tablica o rozmiarze ilości wszystkich liczb
int ile; //Zmienna dbająca o unikatowość losowanych liczb
if(czyIstnieje==0)
{
FileWriter plik2 = new FileWriter("input.txt");
BufferedWriter buforWy = new BufferedWriter(plik2);
for (int y=1;y<tab.length-1;y++) //Pętla losująca liczby i odrazu zapisująca wartości do tablicy a potem do pliku
{
do{
ile=0;
tab[y]=(int) (Math.random()*2000-1000);
for(int il=0;il<tab.length-1;il++)
{
if(tab[il]==tab[y])
ile++;
}
}while(ile!=1);
buforWy.write(Integer.toString(tab[y]));
buforWy.write(";");
}
do{
ile=0;
tab[ilosc_liczb-1]=(int) (Math.random()*2000-1000); //Ostatnia liczba zapisywana do pliku aby nie tworzyć
//zbędnego średnika w pliku (na końcu)
for(int il=0;il<tab.length-1;il++)
{
if(tab[il]==tab[ilosc_liczb-1])
ile++;
}
}while(ile!=1);
buforWy.write(Integer.toString(tab[ilosc_liczb-1]));
buforWy.close();
//"Narysowanie" drzewa w programie (opcja B)///////////////////////////////////////
FileReader plik=new FileReader("input.txt");
BufferedReader bufor=new BufferedReader(plik);
while((linia = bufor.readLine())!=null)
{
StringTokenizer token=new StringTokenizer(linia,";");
for(int i=0;i<ilosc_lin;i++)
{
ilosc_spacji=ilosc_spacji/2; //Obliczanie odstępów pomiędzy liczbami
for(int j=ile_liczb;j>0;j--)
{
if((j-1) % 3==1) //Program sprawdza czy wypisać liczbę czy utworzyć odstęp
{
liczba=token.nextToken(); //Pobieranie elementu z pliku
System.out.print(liczba); //Wypisanie elementów w programie
tab[m]=Integer.parseInt(liczba); //Zapisanie elementu ponownie w tablicy
m++; //Przejscie do następnego elementu tablicy
}
else
{
for(double k=0;k<ilosc_spacji-1.75;k++)
{
System.out.print(" "); //Tworzenie odstępu
}
}
}
System.out.print("\n");
ile_liczb=ile_liczb*2;
}
}
bufor.close();
FileWriter plik4 = new FileWriter("input.txt");
BufferedWriter buforDod = new BufferedWriter(plik4);
for (int y=1;y<tab.length-1;y++)
{
buforDod.write(Integer.toString(tab[y]));
buforDod.write(";");
}
buforDod.write(Integer.toString(tab[ilosc_liczb]));
n=Integer.parseInt(JOptionPane.showInputDialog("Co chcesz wyszukac?"));
buforDod.newLine();
buforDod.write(Integer.toString(n));
buforDod.close();
}
else
{
FileReader plik=new FileReader("input.txt");
BufferedReader bufor=new BufferedReader(plik);
linia = bufor.readLine();
StringTokenizer token=new StringTokenizer(linia,";");
for(int z=1;z<tab.length;z++)
{
liczba=token.nextToken();
tab[z]=Integer.parseInt(liczba);
}
n=Integer.parseInt(bufor.readLine());
bufor.close();
//"Narysowanie" drzewa w programie (opcja A)///////////////////////////////////////
ilosc_lin=0;
for (double y=tab.length;y>1;y=y/2)
{
ilosc_lin++;
}
for(int s=1;s<ilosc_lin;s++) //Oblicza odstępy w zależności od ilości lini (im więcej tym większe)
ilosc_spacji=ilosc_spacji*2;
int il=1;
for(int i=0;i<ilosc_lin;i++)
{
ilosc_spacji=ilosc_spacji/2; //Obliczanie odstępów pomiędzy liczbami
for(int j=ile_liczb;j>0;j--)
{
if((j-1) % 3==1) //Program sprawdza czy wypisać liczbę czy utworzyć odstęp
{
if(il<ilosc_liczb+1)
{
System.out.print(tab[il]); //Wypisanie elementów w programie
il++; //Przejscie do następnego elementu tablicy
}
}
else
{
for(double k=0;k<ilosc_spacji-1.75;k++)
{
System.out.print(" "); //Tworzenie odstępu
}
}
}
System.out.print("\n");
ile_liczb=ile_liczb*2;
}
}
long start=System.nanoTime(); //Obliczanie czasu
//Zapisanie wyników w pliku output///////////////////////////////////////////////////
FileWriter plik3 = new FileWriter("output.txt");
BufferedWriter buforWy2 = new BufferedWriter(plik3);
buforWy2.write("Liczba do wyszukania: "+Integer.toString(n));
buforWy2.newLine();
int miejsce=0; //Pierwsze położenie wyszukiwanego elementu
for (int y=1;y<tab.length;y++) //Wyszukiwanie wymaganego elementu w tablicy
{
if(tab[y]==n)
miejsce=y;
}
long stop=System.nanoTime(); //Koniec obliczania czasu
buforWy2.write("\nCzas wykonania (w milisekundach): "+(stop-start)/1000000);
buforWy2.newLine();
if(miejsce==0)
buforWy2.write("BRAK WYSZUKIWANEJ LICZBY!");
else
{
if(miejsce==1) //Wyjątek dla pierwszego elementu
{
buforWy2.write("NULL!!");
buforWy2.newLine();
if(ilosc_liczb==1)
{
buforWy2.write("NULL!!");
buforWy2.newLine();
}
else
{
buforWy2.write("NULL!!");
buforWy2.newLine();
buforWy2.write("Prawo: "+tab[miejsce+1]);
buforWy2.newLine();
}
}
else if(miejsce % 2==1) //Wyszukiwanie rodzica, prawego jak i lewego sąsiada
{
buforWy2.write("Rodzic to: "+tab[(miejsce-1)/2]);
buforWy2.newLine();
buforWy2.write("Lewo: "+tab[miejsce-1]);
buforWy2.newLine();
if(miejsce==ilosc_liczb)
buforWy2.write("Prawo: NULL!!");
else
buforWy2.write("Prawo: "+tab[miejsce+1]);
buforWy2.newLine();
}
else
{
buforWy2.write("Rodzic to: "+tab[miejsce/2]);
buforWy2.newLine();
buforWy2.write("Lewo: "+tab[miejsce-1]);
buforWy2.newLine();
if(miejsce==ilosc_liczb)
buforWy2.write("Prawo: NULL!!");
else
buforWy2.write("Prawo: "+tab[miejsce+1]);
buforWy2.newLine();
}
if(miejsce==1) //Ścieżka dla pierwszego elementu
{
if(tab[1]<0)
buforWy2.write("Ścieżka: ("+tab[1]+")");
else
buforWy2.write("Ścieżka: "+tab[1]);
buforWy2.newLine();
}
else //Ścieżka dla reszty
{
if(tab[miejsce]<0)
buforWy2.write("Ścieżka: ("+tab[miejsce]+")");
else
buforWy2.write("Ścieżka: "+tab[miejsce]);
for(int x=1;x<ilosc_lin;x++)
{
if(miejsce % 2==1)
{
if(miejsce!=1)
{
if(tab[(miejsce-1)/2]<0)
buforWy2.write("-("+tab[(miejsce-1)/2]+")");
else
buforWy2.write("-"+tab[(miejsce-1)/2]);
miejsce=(miejsce-1)/2;
}
}
else
{
if(miejsce!=1)
{
if(tab[miejsce]/2<0)
buforWy2.write("-("+tab[(miejsce)/2]+")");
else
buforWy2.write("-"+tab[(miejsce)/2]);
miejsce=(miejsce)/2;
}
}
}
}
}
buforWy2.close();
}
} 
