Kamis, 31 Mei 2018

PROGRAM SILSILAH KELUARGA (MENGGUNAKAN BINARY TREE) Dengan Bahasa C++

PROGRAM SILSILAH KELUARGA (BINARY TREE) Dengan Bahasa C++
oleh: satria imamudin

assalamualaikum wr.wb
berikut ini  PROGRAM SILSILAH KELUARGA (BINARY TREE) Dengan Bahasa C++ Namun menggunakan bahasa Inggris :

#define WINDOWS
//#define LINUX

/** FAMILY TREE */

#include<iostream>
#include<string.h>
#include<stdlib.h>

using namespace std;

struct node
{
    char name[50];
    short int age,x;    // x - height of node
    bool g;             // g- gender
    node* fc;           // Pointer to first child
    node* ns;           // Pointer to next sibiling

    node();
    void getData();
};

node::node()
{
    fc=ns=NULL;
    g=0;
    strcpy(name,"");
    age=x=0;
}

void node::getData()
{
    char ch;
    cout<<"\nName of the Person: ";
    cin>>name;
    cout<<"Age of "<<name<<": ";
    cin>>age;
    cout<<name<<" is (m/f): ";
    cin>>ch;
    if(ch=='m')
        g=1;
}

class familyTree
{

public:

    node* start;

    familyTree();

    node* traverseDown(node*,char[]);   // Search functions
    node* traverseRight(node*,char[]);
    node* search(char[]);

    void addSib(node*,node*);           // Functions for adding new members
    void addChild(node*,node*);
    void addNew();

    void find();                        // Function to find relations
    void show(node*);                   // Function to show details of particular person
    void display(node*);                // Function to display full tree
    void destroy(node*);                // Function to destroy full tree
    void updateX(node*,int);

};

familyTree::familyTree()
{
    start = NULL;
}

void familyTree::destroy(node* ptr)
{
    node* temp = ptr;

    if(ptr==NULL)
        return;

    while(ptr!=NULL)
    {
        destroy(ptr->fc);
        temp = ptr;
        ptr = ptr->ns;
        delete temp;
    }

    start = NULL;
}

void familyTree::show(node* ptr)
{
    char g[10];
    strcpy(g,"Female");
    if(ptr->g)
        strcpy(g,"Male");
    cout<<"\n\nName: "<< ptr->name <<endl;
    cout<<"Age: "<< ptr->age <<endl;
    cout<<"Gender: "<<g<<endl;
}

void familyTree::display(node* ptr)
{
    // Traverses the full n-array tree by recursion to display names of all people

    if(ptr==NULL)
        return;

    while(ptr!=NULL)
    {
        cout<< ptr->name <<endl;
        display(ptr->fc);
        ptr = ptr->ns;
    }
}

void familyTree::updateX(node* ptr,int x)
{
    // Traverses the full n-array tree by recursion and updates x value of all people

    if(ptr==NULL)
        return;

    while(ptr!=NULL)
    {
        updateX(ptr->fc,x++);
        if(ptr->ns!=NULL)
            ptr->ns->x = x;
        ptr = ptr->ns;
    }
}

void familyTree::find()
{

    /*
        Same hight: Sibiling if same parent, else cousin
        Difference of height = 1 - Parent if immediate, else uncule/aunt
        Difference oh height = 2 - Grand parents if same link, elss idk
    */

    char name1[50],name2[50];
    cout<<"Enter names of two persons:\n";
    cin>>name1>>name2;
    node* ptr1 = search(name1);
    node* ptr2 = search(name2);
    node* ptr;
    node* ptrk=ptr1;
    node* ptrk1=ptr2;

    switch(ptr1->x - ptr2->x)
    {

    case 0:
            char s[50];
            strcpy(s,"sister");
            if(ptr1->g)
                strcpy(s,"brother");

            ptr = ptr1;
            while(ptr!=NULL)
            {
                if(ptr==ptr2)
                {
                    cout<<endl<<name1<<" is "<<name2<<"'s "<<s<<endl;
                    return;
                }
                ptr = ptr->ns;
            }
            ptr = ptr2;
            while(ptr!=NULL)
            {
                if(ptr==ptr1)
                {
                    cout<<endl<<name1<<" is "<<name2<<"'s "<<s<<endl;
                    return;
                }
                ptr = ptr->ns;
            }
            cout<<endl<<name1<<" and "<<name2<<" are Cousins";
            break;

    case 1:
            char str3[50];
            strcpy(str3,"daughter");
            if(ptr1->g)
                strcpy(str3,"son");
            ptr2 = ptr2->fc;
            while(ptr2!=NULL)
            {
                if(ptr2==ptr1)
                {
                    cout<<endl<<name1<<" is "<<name2<<"'s "<<str3;
                    return;
                }
                ptr2=ptr2->ns;
            }
            strcpy(str3,"niece");
            if(ptr1->g)
                strcpy(str3,"nephew");
            cout<<endl<<name1<<" is "<<name2<<"'s "<<str3;
            break;
    case -1:
            char str[10];
            strcpy(str,"mother");
            if(ptrk->g)
                strcpy(str,"father");

            ptr = ptrk->fc;
            while(ptr!=NULL)
            {
                if(ptr==ptrk1)
                {
                    cout<<endl<<name1<<" is "<<name2<<"'s "<<str;
                    return;
                }
                ptr=ptr->ns;
            }
            strcpy(str,"aunt");
            if(ptrk->g)
                strcpy(str,"uncule");
            cout<<endl<<name1<<" is "<<name2<<"'s "<<str;
            break;

    case 2:
            char str1[50];
            strcpy(str1,"daughter");
            if(ptr2->g)
                strcpy(str1,"son");
            ptr2 = ptr2->fc->fc;
            while(ptr2!=NULL)
            {
                if(ptr2==ptr1)
                {
                    cout<<endl<<name1<<" is grand "<<str1<<" of "<<name2;
                    return;
                }
                ptr2 = ptr2->ns;
            }
            break;
    case -2:
            char str2[50];
            strcpy(str2,"mother");

            if(ptr1->g)
                strcpy(str2,"father");

             ptr1 = ptr1->fc->fc;

            while(ptr1!=NULL)
            {
                if(ptr1==ptr2)
                {
                    cout<<endl<<name1<<" is grand "<<str2<<" of "<<name2;
                    return;
                }
                ptr1 = ptr1->ns;
            }

            break;
    default:
            cout<<"Too far relationship";
            break;
    }
}



node* familyTree::search(char s[50])
{
    /*
        Searches for the given name from start to it's sibilings and their children
        Returns the pointer of node where the name is present
    */

    node *ptr = start;

    if(strcmp(ptr->name,s)==0)
        return ptr;
    else if(traverseRight(start,s)!=NULL)
        return traverseRight(start,s);
    else if(traverseDown(start,s)!=NULL)
        return traverseDown(start,s);
    else
    {
        return NULL;
        cout<<"***Not found***8";
    }
}

node* familyTree::traverseDown(node* ptr, char s[50])
{
    // Searches all the children

    ptr = ptr->fc;

    while(ptr!=NULL)
    {
        if(  strcmp(ptr->name,s)==0 )
            return ptr;
        else if(traverseRight(ptr,s)!=NULL)
            return traverseRight(ptr,s);
        else
            ptr = ptr->fc;
    }
    return NULL;
}

node* familyTree::traverseRight(node* ptr, char s[50])
{

    //  Searches all the sibilings

    ptr = ptr->ns;

    while(ptr!=NULL)
    {
        if(strcmp(ptr->name,s)==0)
            return ptr;
        else if (traverseDown(ptr,s)!=NULL)
            return traverseDown(ptr,s);
        else
            ptr = ptr->ns;
    }
    return NULL;
}

void familyTree::addNew()
{
    node* temp = new node;
    temp->getData();

    if(start == NULL)
    {
        start = temp;
        temp->x=0;
    }

    else
    {
        cout<<"\nEnter any relation's name: ";
        char name[50];
        cin>>name;
        cout<<"\n1. Child\n2. Sibiling\n\n"<< temp->name <<" is ____ to "<<name<<" : ";
        int opt;
        cin>>opt;
        switch(opt)
        {
            case 1:
                    addChild(search(name),temp);
                    break;
            case 2:
                    addSib(search(name),temp);
                    break;

        }
    }
    cout<<"\nPerson sucessfully added.\n";
}

void familyTree::addSib(node* a,node* b)
{
    // b is added as sibling of a

    while(a->ns!=NULL)
        a=a->ns;
    a->ns = b;

    b->x = a->x;
}

void familyTree::addChild(node* a,node* b)
{

    // b is added as child as a (or) b is added as sibiling to last child of a

    if(a->fc==NULL)
        a->fc = b;
    else
        addSib(a->fc,b);

    b->x = a->x+1;
}

void connect(familyTree *T1, familyTree *T2)
{
    char name[50];
    int opt;
    int x;
    cout<<"Name of person in 1st tree to merge: ";
    cin>>name;
    cout<<T2->start->name<<" is __ to "<<name<<"\n1. Child 2. Sibling - ";;
    cin>>opt;
    node *ptr = T1->search(name);
    switch(opt)
    {
        case 1:
            T1->addChild(ptr,T2->start);
            x = ptr->x + 1;
            break;
        case 2:
            T1->addSib(ptr,T2->start);
            x = ptr->x;
            break;
     }
     T2->updateX(T2->start,x);
     T2->destroy(T2->start);
     cout<<"\nMerged\n";
}

int main()
{
    familyTree T[100];
    int opt,n,n1,n2;
    char c,name[50];
    cout<<"\nEnter the family tree number = ";
    cin>>n;
    while(1)
    {
#ifdef WINDOWS
        system("cls");
#endif // WINDOWS
#ifdef LINUX
        system("clear");
#endif // LINUX
        cout<<"\n\n\n\tFamily tree no = "<<n<<"\n\n\t1. Add new person\n\t2. Find relationship b/w two persons\n\t3. Search\n\t4. Destroy\n\t5. Display\n\t6. Change family tree\n\t7. Connect two family trees\n\t8. Exit\n\n\tEnter your choice = ";
        cin>>opt;
        cout<<endl;

        switch(opt)
        {

        default:
                cout<<"Invalid input";
                break;

        case 1:
                T[n].addNew();
                break;

        case 2:
                T[n].find();
                break;

        case 3:
                cout<<"Enter name of person to search: ";
                cin>>name;
                T[n].show(T[n].search(name));
                break;

        case 4:
                T[n].destroy(T[n].start);
                cout<<"Tree "<<n<<" has been destroyed sucessfully";
                break;

        case 5:
                T[n].display(T[n].start);
                break;

        case 6:
                cout<<"Enter family tree number: ";
                cin>>n;
                break;

        case 7:
               cout<<"Merge __ to __ \n";
               cin>>n2>>n1;
               connect(&T[n1],&T[n2]);
               break;

        case 8:
            return 0;

        }
        cout<<"\n\nPress any key to continue.....";
        cin>>c;
    }
}
 

Dan Setelah Dicompile akan muncul Output(Hasil) Seperti dibawah ini :

Itulah program untuk sisilah keluarga menggunakan binary tree dengan bahasa C++, mohon maaf jika mungkin terjadi error dalam program tersebut..semoga bermanfaat!!

wassalamualaikum wr. wb

referensi : Modul Praktikum Struktur Data Pendidikan Telnil Informatika Universitas Muhammadiyah Surakarta

Selasa, 06 Maret 2018

Latihan soal

1.       CARA MEMBUAT PROGRAM YANG BAGUS
Untuk bisa menghasilkan program yang baik memerlukan analisis yang baik pula, baik itu analisis sistem, stuktur data maupun analisis requirement, selin itu juga dipelukan persiapan-persiapan yang matang. Hal ini berlaku bagi siapapun, bahkan seorang programmer professional sekalipun.  Sedangkan tahapan apas aja untuk membuat program yang baik akan saya jelaskan dibawah.


Program memang sudah menjadi kebutuhan pokok bagi masyarakat IT. karena segala sesuatu yang dilakukan di dalam IT pastilah memerlukan program. Program yang paling sederhana sekalipun setidaknya memiliki 3 bagian: 

  • Input – Masukan data.

  • Proses – pemrosesan input.

  • Output – keluaran program, kebutuhan yang kita harapkan.



Dalam membuat program, pemrograman adalah pokok dari proses pembuatan program itu sendiri namun pemrograman bergantung dari pemahaman persoalan, analisis sistem, perencanaan-perencanaan  dalam mendesain program itu sendiri,
http://wa2n.staff.uns.ac.id/2008/09/14/tahapan-membuat-program-dengan-baik/



2.   JENIS JENIS STRUKTUR DATA SECARA UMUM
Jenis Struktur Data
1. Struktur Data Sederhana
a. Array (Larik).
adalah struktur data statik yang menyimpan sekumpulan elemen bertipe sama.
Setiap elemen diakses secara langsung melalui indeksnya. Indeks larik harus tipe data yang menyatakan keterurutan, misalnya: integer atau karakter. Banyaknya elemen larik harus sudah diketahui sebelum program dieksekusi. Tipe elemen larik dapat berupa tipe sederhana, tipe terstruktur atau tipe larik lain. Nama lain dari Array adalah Larik, tabel, atau vektor.

b. Record (catatan)
adalah kumpulan data yang terdiri dari beberapa field(isian) dengan berbagai macam tipe data.

2. Struktur Data Majemuk
a. Linier
Stack(tumpukan)
adalah list linier yang dikenali berupa elemen puncaknya(top), aturan penyisipan dan penghapusan elemennya tertentu (penyisipan selalu dilakukan "diatas"(top) dan penghapusan selalu dilakukan pada "top").

Karena aturan penyisipan dan penghapusan semacam itu, "top" adalah satu- satunya alamat tempat terjadinya operasi. Elemen yang paling akhir ditambahkan akan menjadi elemen yang akan dihapus. Dapat dikatakan elemen stack akan tersusun secara LIFO(last in first out).

Queue(antrian)
adalah list linier yang dikenali berupa elemen pertama(head) dan elemen terakhir(tail), dimana aturan penyisipan dan penghapusan elemennya didefinisikan sebagai penyisipan selalu dilakukan setelah elemen terakhir, penghapusan selalu dilakukan pada elemen pertama dengan kondisi satu elemen dengan elemen lainnya dapat diakses melalui informasi "next".

List dan Multi-List(Daftar)
adalah sekumpulan list linier yang dengan elemen yang bertype sama, yang memiliki keterurutan tertentu, yang setiap elemennya terdiri dari 2 bagian.

b. Non-Linier.

Binary-Tree(Pohon biner)
adalah himpunan terbatas yang mungkin kosong atau terdiri dari sebuah simpul yang disebut sebagai akar dan dua buah himpunan lain yang disjoint yang merupakan pohon biner yang disebut sebagai sub-pohon kiri(left) dan sub-pohon kanan(right) dari pohon biner tersebut.

Pohon biner merupakan type yang sangat penting dari struktur data dan banyak dijumpai dalam berbagai terapan. Karakteristik yang dimiliki oleh pohon biner adalah bahwa setiap simpul yang paling banyak hanya memiliki dua buah anak, dan mungkin tidak punya anak.
Istilah- istilah yang digunakan sama dengan istilah pada pohon secara umum.

Graph(graf)
merupakan struktur data yang paling umum. Jika struktur linier memungkinkan pendefinisian keterhubungan sekuensial antar entitas data, struktur data tree memungkinkan pendefinisian keterhubungan hirarkis, maka struktur graph memungkinkan pendefinisian keterhubungan tak terbatas antara entitas data.

Banyak entitas- entitas data dalam masalah- masalah nyata secara alamiah memiliki keterhubungan langsung(adjacency) secara tak terbatas. 


3.  BEBERAPA APLIKASI PERANGKAT LUNAK KOMPUTER YANG MENGGUNAKAN STRUKTUR DATA SEBAGAI DASAR PENGEMBANGANNYA.

Penjelasan penggunaan Struktur data pada perangkat lunak :
Dalam teknik pemograman, struktur data berarti tata letak data yang berisi kolom-kolom data, baik itu kolom yang tampak oleh pengguna (user) maupun kolom yang digunakan untuk keperluan pemograman yang tidak tampak oleh pengguna.

Analisis & Desain Model
Analisis terhadap kebutuhan dapat menggunakan beberapa alat seperti :
1. Data Flow Diagram (DFD)
2. Entity Relationship Diagram (ERD)
3. State Transition Diagram (STD)

untuk menganalisis kebutuhan dibutuhkan suatu bekal dapat memudahkan penganalisisan suatu kebutuhan, bekal yang dibutuhkan ialah Data Dictionary.
Data Dictionary berisi gambaran objek data yang diperlukan dan akan dihasilkan oleh software. Diagram-diagram diatas mempunyai karakteristik masing masing.
DFD memberi gambaran bagaimana data berubah dalam sistem. ERD menggambarkan relasi antara objek data. STD menggambarkan bagaimana kerja sistem melalui kondisi dan kejadian yang menyebabkan data berubah, STD juga menggambarkan proses yang dilakukan karena kejadian tertentu.
Hasil  yang diperoleh dari proses penganalisian adalah model analisis yang kemudian menjadi bekal untuk melakukan desain. 


4.  ALGORITMA YAMH MENGANALOGIKAN ABSTRAKSI PERANGKAT ELEKTRONIK


Analogi abstaction pada windows phone.
Saya telah menetapkan bahwa memiliki perakitan "inti" per platform untuk kode portabel (viewmodel, pembantu, dll.) Dan perakitan terpisah per basis data / toko penyimpanan (SqlCe, Sqlite, dll.) Bahwa rakitan inti spesifik platform nampaknya bekerja Ini berarti kelas model saya masih didefinisikan dalam majelis DAL, namun setidaknya saya bisa menyediakan antarmuka umum sederhana (yang didefinisikan di setiap majelis DAL, sayangnya, karena kelas model DAL) yang masih memberi saya dukungan IQueryable.

Berkat "copy as link" dalam Visual Studio, menyiapkan majelis inti dan memastikan bahwa antarmuka layanan database umum sama untuk setiap perakitan DAL cukup mudah. Dengan # ifdef saya bahkan dapat menggunakan kembali banyak file kelas model DAL dan mengkompilasi atribut secara bersyarat, kode khusus database, dll. Yang memungkinkan saya untuk menggunakan "copy as link" untuk mereka juga.

public interface IDataService
{
IQueryable<ModelType1> ModelType1 { get; }
IQueryable<ModelType2> ModelType2 { get; }

void AddModelType1(ModelType1 item);
void RemoveModelType1(ModelType1 item);

void AddModelType2(ModelType2 item);
void RemoveModelType2(ModelType2 item);

void CreateDatabase();
void ResetDatabase();
}
The resulting map of references is kind of like this:

System.Data.Linq -> App.Data.SqlCe -> App.Core.WP -> App.WP
/                   /
(some shared code)  (all shared code)
/                /
Sqlite -> App.Data.Sqlite -> App.Core.Win8 -> App.Win8
Tempat itu sama bersihnya seperti yang kuinginkan, tapi setidaknya sepertinya berhasil.

5. PERBANDINGAN PENDEKATAN YANG DAPAT DIGUNAKAN UNTUK MERANCANG SEBUAH ALGORITMA.

Terdapat dua pendekatan Umum yang bisa digunakan dalam merancang algoritma, yaitu pendekatan perancangan top down dan bottom-up,  pendekatan perancangan secara top-down dimulai dengan cara membagi algoritma yang kompleks menjadi satu atau lebih dari satu modul. Modul yang terbagi ini masih bisa duraikan lagi menjadi beberapa sub-modul, dan proses ini dilakukan berulang-ulang hingga kompleksitas modul yang diinginkan terpenuhi. Metode perancangan top-down merupakan bentuk perbaikan secara bertahap yang dimulai dengan modul paling atas kemudian secara bertahap menambah modul lain yang dipanggil.
Untuk pendekatan secara bottom-up, merupakan kebalikan dari top down.  Dimana modul ini dimulai dengan pembuatan modul paling dasar, kemudian dilanjutkan ke perancangan modul tingkat yang lebih tinggi.
Dari kedua pendekatan diatas, yaitu  top-down dan bottom-up, apakah strategi top down / bottom-up,  tentu tergantung pada aplikasi yang ditangani. Pendekatan top-down  mengkuti perbaikan secara bertahap dengan menguraikan algoritma ke dalam modul secara terkelola. Sementara pendekatan bottom-up mendefinisikan modul terlebih dahulu baru kemudian mengelompokan beberapa , modul secara bersama untuk membentuk modul baru tingkat lebih tinggi. Pendekatan top-down sangat bagus dalam hal kemudahan membuat dokumentasi modul, menghasilkan uji kasus, implementasi kode, dan debugging.  Namun, terdaopat kekurangan karena sub-modul dianalisis dalam sebuah isolasi tanpa memperhatikan komuikasi dengan modul lain sehingga mengabaikan konsep penyembunyian informasi.
Referensi (Hal.136)

6. ALGORITMA UNTUK PROGRAM KALKULATOR
Algoritma :
Inisialisaikan bil1, bil2, oprs, hasil
Input nilai a, b
Pilih salah satu operasi dari (+),(-),(x),(:)
Jika anda memilih operasi (+), maka hasil = a + b
Jika anda memilih operasi (-), maka hasil = a - b
Jika anda memilih operasi (x), maka hasil = a * b
Jika anda memilih operasi (:), maka hasil = a / b
Cetak hasil

Flowchart
7.     7. Notasi
Pernyataan “f(x) adalah O(g(x))” sebagaimana didefinisikan sebelumnya, biasa ditulis f(x) = O(g(x)) Pernyataan ini adalah penyalahgunaan notasi. Persamaan dari dua buah fungsi tidak dinyatakan. Properti O(g(x)) tidaklah simetrik: Karena alasan ini, beberapa penulis lebih memilih menggunakan notasi himpunan dan menulis Menganggap O(g) sebagai himpunan dari fungsi fungsi yang didominasi oleh g. Dalam penggunaan yang lebih rumit, , O( ) dapat muncul pada tempat yang berbeda di dalam sebuah persamaan, bahkan beberapa kali untuk masing-masing sisi.
Misalnya, pernyataan berikut benar untuk (n + 1)2 = n2 + O(n) nO(1) = O(en)
Maksud dari pernyataan diatas adalah :
Untuk setiap fungsi yang memenuhi untuk setiap O( ) pada sisi kiri, terdapat fungsi-fungsi yang memenuhi masing-masing O( ) pada sisi kanan, melakukan substitusi untuk semua fungsi-fungsi ini ke dalam persamaan menyebabkan kedua sisi menjadi sama. Misalnya, persamaan ke-3 diatas berarti: “Untuk setiap fungsi f(n) = O(1), terdapat fungsi-fungsi g(n) = O(en) sehingga nf(n) = g(n)”.
https://azisnurc.wordpress.com/2014/12/28/penggunaan-notasi-big-o-untuk-menganalisa-efisiensi-algoritma/