Saturday, December 24, 2016

Bab 14. Pemrograman C# Belajar Dari Contoh


14. Struktur Data







Pengantar

Struktur data yang telah dipelajari sejauh ini, seperti array subskript-tunggal dan array subskript-ganda, adalah struktur data berukuran tetap. Bab ini akan mengintroduksi struktur data dinamais, yang dapat bertumbuh dan menyusut pada saat eksekusi. Senarai berantai adalah koleksi item data, dimana pengguna dapat menyisipkan dan menghapus sembarang item di mana saja di dalam senarai tersebut. Tumpukan penting pada kompiler dan sistem operasi; penyisipan dan penghapusan hanya berlaku untuk item pada posisi paling atas tumpukan. Antrian merepresentasikan baris antrian; penyisipan hanya dilakukan di belakang (disebut juga dengan ekor) antrian, dan penghapusan hanya dilakukan di depan (disebut pula dengan kepala) antrian. Pohon biner memfasilitasi pencarian dan pengurutan kecepatan-tinggi, dimana di dalamnya dilakukan eliminasi efisien atas item-item data duplikat. Antrian merepresentasikan hirarki sistem-file dan kompilasi ekspresi menjadi bahasa mesin.

Pada bab ini, akan didiskusikan setiap tipe struktur data dan diimplementasikan beberapa program yang menciptakan dan memanipulasi setiap struktur data tersebut. Kelas, pewarisan, dan komposisi diciptakan sehingga dapat meningkatkan kapabilitas struktur data.


Kelas Referensi-Diri
Sebuah kelas referensi-diri memuat sebuah anggota referensi yang menunjuk ke suatu objek kelas yang memili tipe kelas yang sama. Sebagai contoh, definisi kelas pada kode 14.1 mendefinisikan tipe Simpul. Tipe ini memiliki dua variabel instans private, data dan referensi Simpul berikutnya.

Anggota berikutnya mereferensi sebuah objek bertipe Simpul, tipe yang sama dengan kelasnya. Jadi, istilah referensi-diri sangat tepat untuk kasus ini. Anggota berikutnya dikenal dengan sebuah link atau rantai (ini berarti bahwa berikutnya dapat dipakai untuk “merantai atau mengikat” sebuah objek bertipe Simpul dengan objek lain bertipe sama). Kelas Simpul juga memiliki dua properti: satu untuk variabel data, dinamai Data, dan yang lain untuk variabel berikutnya, dinamai Berikutnya.

Objek referensi-diri dapat dirantai atau dihubungkan bersama untuk membentuk struktur data, seperti senarai, antrian, tumpukan, dan pohon. Gambar 14.1 mengilustrasikan pengikatan dua objek referensi-diri untuk membentuk sebuah senarai. Garis-miring (backslash) \, yang merepresentasikan referensi null), ditempatkan pada anggota dari objek referensi-diri kedua bertujuan untuk mengindikasikan bahwa link atau rantai tidak menunjuk ke objek lain. Referensi null biasanya mendefinisikan akhir sebuah struktur data.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Simpul
{
    private int data;
    private Simpul berikutnya;

    public Simpul( int d )
    {
        // tubuh konstruktor
    }

    public int Data
    {
        get
        {
            // tubuh get
        }

        set
        {
            // tubuh set
        }
    }

    public Simpul Berikutnya
    {
        get
        {
            // tubuh get
        }

        set
        {
            // tubuh set
        }
    }
 }

Kode 14.1 Definisi kelas Simpul


Gambar 14.1 Dua objek kelas referensi-diri dirantai atau dihubungkan bersama


Penciptaan struktur data dinamis memerlukan alokasi memori dinamis, yaitu kemampuan program untuk mendapatkan memori tambahan (untuk menampung variabel-variabel baru) dan untuk melepaskan memori yang sudah tidak lagi dibutuhkan pada saat eksekusi. Ingat bahwa program C# secara otomatis melakukan koleksi sampah memori.

Katakunci new penting dalam alokasi memori dinamis. Katakunci new mengambil nama kelas suatu objek sebagai operand. Ia kemudian secara dinamis mengalokasikan memori untuk objek yang baru, memanggil konstruktor kelas, dan menghasilkan sebuah referensi yang menunjuk ke objek yang baru saja diciptakan. Sebagai contoh, statemen:

Simpul simpulYgAkanDitambahkan = new Simpul( 10 );

mengalokasikan sejumlah memori tertentu untuk menyimpan sebuah Simpul dan menyimpan sebuah referensi yang menunjuk ke objek ini di dalam simpulYgAkanDitambahkan.

Beberapa topik ke depan akan mendiskusikan senarai, tumpukan, antrian, dan pohon. Semua struktur data tersebut diciptakan dan dikembangkan dengan alokasi memori dinamis dan kelas referensi-diri.


Senarai Berantai
Senarai berantai adalah sebuah koleksi linier (runtun) atas objek-objek kelas referensi-diri, yang dinamakan dengan simpul, yang dikoneksi oleh rantai-rantai referensi. Program dapat mengakses sebuah senarai berantai melalui referensi yang menunjuk ke simpul pertama pada senarai. Setiap simpul diakses via anggota referensi pada simpul sekarang. Secara konvensi, referensi pada simpul terakhir ditetapkan menjadi null untuk menandai akhir senarai. Data disimpan pada sebuah senarai berantai secara dinamis, dimana setiap simpul diciptakan jika diperlukan. Simpul dapat memuat sembarang tipe data, termasuk objek-objek dari kelas lain.

Meskipun array juga dapat menyimpan koleksi data, senarai berantai memberikan beberapa keuntungan dan keunggulan lebih. Sangat tepat untuk menggunakan senarai berantai apabila jumlah elemen data yang akan disajikan pada struktur data tidak dapat diprediksi. Tidak seperti senarai berantai, ukuran dari array C# konvensional tidak dapat diubah, karena ukuran array tetap ketika array diciptakan. Array konvensional bisa menjadi penuh, tetapi senarai berantai hanya bisa penuh ketika sistem tidak lagi mempunyai memori untuk memenuhi permintaan pengalokasian dinamis.

Programer dapat mengembangkan (membengkakkan ukuran dari) senarai berantai secara berurutan hanya dengan menyisipkan setiap elemen baru pada titik yang tepat di dalam senarai. Jadi, penyisipan elemen baru tidak menyebabkan pemindahan elemen-elemen yang sudah ada.

Normalnya, memori tidak menyimpan simpul-simpul senarai berantai secara bertetangga di dalam memori. Gambar 14.2 mengilustrasikan sebuah senarai berantai yang memuat beberapa simpul.


Gambar 14.2 Representasi grafikal atas senarai berantai


Program pada kode 14.2-14.3 menggunakan sebuah objek kelas Senarai untuk memanipulasi sekumpulan objek bertipe Object. Metode Main pada module UjiSenarai (Kode 14.3) menciptakan beberapa objek, menyisipkan objek di awal senarai (menggunakan metode Senarai SisipDiDepan), menyisipkan objek di akhir senarai (menggunakan metode Senarai SisipDiBelakang), menghapus objek dari depan senarai (menggunakan metode Senarai HapusDariDepan), dan menghapus objek dari belakang senarai (menggunakan metode Senarai HapusDariBelakang). Setiap operasi penyisipan atau penghapusan akan memanggil metode Senarai Tampil untuk menampilkan isi senarai sekarang. Diskusi detil atas program akan diberikan. Sebuah EksepsiSenaraiKosong terjadi jika percobaan untuk menghapus sebuah item dari senarai kosong dilakukan.

Program memuat empat kelas, SimpulSenarai (kode 14.2, baris 9-52), Senarai (kode 14.2, baris 55-193), EksepsiSenaraiKosong (kode 14.2, baris 196-203), dan kelas UjiSenarai (kode 14.3). Kelas-kelas pada kode 14.2 menciptakan sebuah pustaka senarai-berantai. Ketiga kelas tersebut berada di dalam namespace PustakaSenaraiBerantai.

Terenkapsulasi di dalam tiap objek Senarai adalah sebuah senarai berantai yang memuat objek-objek SimpulSenarai. Kelas SimpulSenarai (kode 14.2, baris 9-52) memuat dua variabel anggota, data dan berikutnya. Anggota data dapat menunjuk ke sembarang objek. Anggota berikutnya menyimpan sebuah referensi yang menunjuk ke objek SimpulSenarai berikutnya pada senarai berantai. Sebuah Senarai mengakses variabel-variabel anggota SimpulSenarai melalui properti Data (baris 44-50) dan Berikutnya (baris 30-41).

Kelas Senarai memuat anggota-anggota private simpulPertama (sebuah referensi yang menunjuk ke SimpulSenarai pertama pada sebuah Simpul) dan simpulAkhir (sebuah referensi yang menunjuk ke SimpulSenarai terakhir pada sebuah Simpul). Konstruktor (baris 62-66 dan 69-71) menginisialisasi kedua referensi menjadi null. Metode SisipDiDepan (baris 76-87), SisipDiBelakang (baris 92-104), HapusDariDepan (baris 107-125), dan HapusDariBelakang (baris 128-156) adalah metode-metode utama pada kelas Senarai. Setiap metode menggunakan blok lock untuk memastikan bahwa objek-objek CSenarai menjadi multithread safe.

Metode ApaKosong (baris 159-165) adalah metode predikat yang menentukan apakah senarai kosong (apakah referensi ke simpul pertama senarai adalah null). Metode predikat secara umum menguji sebuah kondisi dan tidak memodifikasi objek. Jika senarai kosong, metode ApaKosong menghasilkan true; sebaliknya, ia menghasilkan false. Metode Tampil (baris 168-191) menampilkan isi senarai. Kedua metode ApaKosong dan metode Tampil menggunakan blok lock untuk memastikan bahwa keadaan senarai tidak berubah ketika metode-metode tersebut melakukan tugasnya.

Kelas EksepsiSenaraiKosong (baris 196-203) mendefinisikan sebuah kelas eksepsi untuk menangani operasi-operasi ilegal pada Senarai yang kosong. Sebagai contoh, sebuah EksepsiSenaraiKosong terjadi jika program mencoba menghapus sebuah simpul dari Senarai yang kosong.

Kelas UjiSenarai (kode 14.3) menggunakan pustaka senarai-berantai untuk menciptakan dan memanipulasi sebuah senarai berantai. Baris 14 menciptakan sebuah instans bertipe Senarai, dinamai senarai. Kemudian, baris 17-20 menciptakan data yang akan ditambahkan ke dalam senarai. Baris 23-30 menggunakan metode-metode penyisipan Senarai untuk menyisipkan objek-objek dan menggunakan metode Senarai Tampil untuk menampilkan isi senarai setelah tiap penyisipan dilakukan. Kode di dalam blok try (baris 36-53) menghapus objek-objek (menggunakan metode-metode penghapusan Senarai), menampilkan objek yang dihapus, dan menampilkan isi senarai setelah setiap penghapusan dilakukan. Jika terdapat percobaan untuk menghapus sebuah objek dari senarai kosong, maka blok try (baris 68-69) akan menangkap EksepsiSenaraiKosong. Perhatikan bahwa kelas UjiSenarai menggunakan namespace LinkedListLibrary. Jadi, projek yang memuat kelas UjiSenarai harus memuat sebuah referensi yang menunjuk ke pustaka kelas PustakaSenaraiBerantai.

Pada beberapa halaman ke depan, akan didisikusikan setiap metode dari kelas Senarai secara detil. Metode SisipDiDepan (kode 14.2, baris 76-87) menempatkan sebuah simpul baru di depan senarai. Metode ini terdiri-dari tiga langkah, yang dapat dijelaskan berikut:
1.       Memanggil ApaKosong untuk menentukan apakah senarai kosong (baris 80).

2.       Jika senarai kosong, kedua simpulPertama dan simpulAkhir ditetapkan untuk menunjuk ke SimpulSenarai yang baru yang diinisialisasi dengan objek itemSisip (baris 81-82). Konstruktor SimpulSenarai pada baris 16-19 (kode 14.2) memanggil konstruktor SimpulSenarai  pada baris 23-27 (kode 14.2) untuk menetapkan variabel instans data untuk menunjuk ke object yang dilewatkan sebagai argumen pertama dan kemudian menetapkan berikutnya untuk menunjuk ke null.

3.       Jika senarai tidak kosong, maka simpul baru dirantaikan ke dalam senarai dengan menetapkan simpulPertama agar menunjuk ke objek SimpulSenarai yang baru, yang diinisialisasi dengan objek itemSisip dan simpulPertama (baris 84-85). Ketika konstruktor SimpulSenarai (baris 23-27 pada kode 14.2) dieksekusi, ia akan menetapkan variabel instans data agar menunjuk ke object yang dilewatkan sebagai argumen pertama dan melakukan penyisipan dengan menetapkan referensi berikutnya agar menunjuk ke SimpulSenarai yang dilewatkan sebagai argumen kedua.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
// Kode 14.2: PustakaSenaraiBerantai.cs
// Definisi Kelas SimpulSenarai dan kelas Senarai.

using System;

namespace PustakaSenaraiBerantai
{
    // kelas untuk merepresentasikan satu simpul di dalam senarai
    class SimpulSenarai
    {
        private object data;
        private SimpulSenarai berikutnya;

        // konstruktor untuk menciptakan SimpulSenarai yang menunjuk ke nilaiData
        // dan merupakan simpul akhir di dalam senarai
        public SimpulSenarai( object nilaiData )
            : this( nilaiData, null )
        {
        }

        // konstruktor untuk menciptakan SimpulSenarai yang menunjuk ke nilaiData
        // dan menunjuk ke SimpulSenarai berikutnya di dalam senarai
        public SimpulSenarai( object nilaiData, SimpulSenarai simpulBerikutnya )
        {
            data = nilaiData;
            berikutnya = simpulBerikutnya;
        }

        // properti Berikutnya
        public SimpulSenarai Berikutnya
        {
            get
            {
                return berikutnya;
            }

            set
            {
                berikutnya = value;
            }
        }

        // properti Data
        public object Data
        {
            get
            {
                return data;
            }
        }

    } // akhir kelas SimpulSenarai

    // definisi kelas Senarai
    public class Senarai
    {
        private SimpulSenarai simpulPertama;
        private SimpulSenarai simpulAkhir;
        private string nama; // string seperti "senarai" untuk ditampilkan

        // menciptakan Senarai kosong dengan nama yang dispesifikasi
        public Senarai( string namaSenarai )
        {
            nama = namaSenarai;
            simpulPertama = simpulAkhir = null;
        }

        // menciptakan Senarai kosong dengan "senarai" sebagai namanya
        public Senarai() : this( "senarai" )
        {
        }

        // Menyisipkan objek di depan Senarai. Jika Senarai kosong,
        // maka simpulPertama dan simpulAkhir akan menunjuk ke objek yang sama.
        // Sebaliknya, simpulPertama menunjuk ke simpul yang baru.        
        public void SisipDiDepan( object itemSisip )
        {
            lock ( this )
            {
                if ( ApaKosong() )
                    simpulPertama = simpulAkhir =
                        new SimpulSenarai( itemSisip );
                else
                    simpulPertama =
                        new SimpulSenarai( itemSisip, simpulPertama );
            }
        }

        // Menyisipkan objek di akhir Senarai. Jika Senarai kosong,
        // maka simpulPertama dan simpulAkhir akan menunjuk ke objek yang sama.
        // Sebaliknya, properti Berikutnya pada simpulAkhir akan menunjuk ke simpul baru.
        public void SisipDiBelakang( object itemSisip )
        {
            lock ( this )
            {
                if ( ApaKosong() )
                    simpulPertama = simpulAkhir =
                        new SimpulSenarai( itemSisip );

                else
                    simpulAkhir = simpulAkhir.Berikutnya =
                        new SimpulSenarai( itemSisip );
            }
        }

        // menghapus simpul pertama dari Senarai
        public object HapusDariDepan()
        {
            lock ( this )
            {
                if ( ApaKosong() )
                    throw new EksepsiSenaraiKosong( nama );

                object itemHapus = simpulPertama.Data; // mengambil data

                // mereset referensi simpulPertama dan simpulAkhir
                if ( simpulPertama == simpulAkhir )
                    simpulPertama = simpulAkhir = null;

                else
                    simpulPertama = simpulPertama.Berikutnya;

                return itemHapus; // menghasilkan data terhapus
            }
        }

        // menghapus simpul akhir dari Senarai
        public object HapusDariBelakang()
        {
            lock ( this )
            {
                if ( ApaKosong() )
                    throw new EksepsiSenaraiKosong( nama );

                object itemHapus = simpulAkhir.Data; // mengambil data

                // mereset referensi simpulPertama dan simpulAkhir
                if ( simpulPertama == simpulAkhir )
                    simpulPertama = simpulAkhir = null;

                else
                {
                    SimpulSenarai sekarang = simpulPertama;

                    // loop selama simpul sekarang tidak simpulAkhir
                    while ( sekarang.Berikutnya != simpulAkhir )
                        sekarang = sekarang.Berikutnya; // maju ke simpul berikutnya

                    // sekarang adalah simpulAkhir yang baru
                    simpulAkhir = sekarang;
                    sekarang.Berikutnya = null;
                }
               
                return itemHapus; // menghasilkan item terhapus
            }
        }

        // menghasilkan true jika Senarai kosong
        public bool ApaKosong()
        {
            lock ( this )
            {
                return simpulPertama == null;
            }
        }

        // menampilkan isi Senarai
        virtual public void Tampil()
        {
            lock ( this )
            {
                if ( ApaKosong() )
                {
                    Console.WriteLine( nama + " Kosong" );
                    return;
                }

                Console.Write( "# " + nama + " adalah: " );

                SimpulSenarai sekarang = simpulPertama;

                // menampilkan data simpul sekarang apabila tidak di akhir senarai
                while ( sekarang != null )
                {
                    Console.Write( sekarang.Data + " " );
                    sekarang = sekarang.Berikutnya;
                }

                Console.WriteLine( "\n" );
            }
        }

    } // akhir kelas Senarai

    // definisi kelas EksepsiSenaraiKosong
    public class EksepsiSenaraiKosong : ApplicationException
    {
        public EksepsiSenaraiKosong(string nama)
            : base("# " + nama + " kosong")
        {
        }

    } // akhir kelas EksepsiSenaraiKosong

 } // akhir namespace PustakaSenaraiBerantai


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// Kode 14.3: UjiSenarai.cs
// Menguji kelas Senarai.

using System;
using PustakaSenaraiBerantai;

namespace UjiSenarai
{
    // kelas untuk menguji fungsionalitas kelas Senarai
    class UjiSenarai
    {
        static void Main( string[] args )
        {
            Senarai senarai = new Senarai(); // menciptakan kontainer Senarai

            // menciptakan data untuk disimpan di dalam Senarai
            bool aBoolean = true;
            char aKarakter = '$';
            int aInteger = 34567;
            string aString = "hallo";

            // menggunakan metode-metode penyisipan Senarai
            senarai.SisipDiDepan( aBoolean );
            senarai.Tampil();
            senarai.SisipDiDepan( aKarakter );
            senarai.Tampil();
            senarai.SisipDiBelakang( aInteger );
            senarai.Tampil();
            senarai.SisipDiBelakang(aString);
            senarai.Tampil();

            // menggunakan metode-metode penghapusan Senarai
            object objekHapus;

            // menghapus data dari senarai dan menampilkannya (data yang terhapus)
            try
            {
                objekHapus = senarai.HapusDariDepan();
                Console.WriteLine( objekHapus + " dihapus" );
                senarai.Tampil();

                objekHapus = senarai.HapusDariDepan();
                Console.WriteLine(objekHapus + " dihapus");
                senarai.Tampil();

                objekHapus = senarai.HapusDariBelakang();
                Console.WriteLine(objekHapus + " dihapus");
                senarai.Tampil();

                objekHapus = senarai.HapusDariBelakang();
                Console.WriteLine(objekHapus + " dihapus");
                senarai.Tampil();
            }

            // melempar eksepsi jika senarai kosong ketika
            // percobaan penghapusan item dilakukan
            catch (EksepsiSenaraiKosong eksepsiSenaraiKosong)
            {
                Console.Error.WriteLine("\n" + eksepsiSenaraiKosong);
            }

        } // akhir metode Main

    } // akhir kelas UjiSenarai
}

# senarai adalah: True

# senarai adalah: $ True

# senarai adalah: $ True 34567

# senarai adalah: $ True 34567 hallo

$ dihapus
# senarai adalah: True 34567 hallo

True dihapus
# senarai adalah: 34567 hallo

hallo dihapus
# senarai adalah: 34567

34567 dihapus
senarai Kosong

Gambar 14.3 mengilustrasikan metode SisipDiDepan. Bagian a) menggambarkan senarai dan simpul baru selama operasi SisipDiDepan dan sebelum perantaian SimpulSenarai yang baru (memuat nilai 12) ke dalam senarai. Anak panah putus-putus pada bagian b) mengilustrasikan langkah 3 pada operasi SisipDiDepan, yang membuat SimpulSenarai menjadi bagian depan senarai yang baru.



Gambar 14.3 Representasi grafikal atas SisipDiDepan


Metode SisipDiBelakang (Kode 14.2, baris 92-104) menempatkan sebuah simpul baru di belakang senarai. Metode ini memuat tiga langkah:
1.       Memanggil ApaKosong untuk menentukan apakah senarai kosong (baris 96).

2.       Jika senarai kosong, kedua simpulPertama dan simpulAkhir ditetapkan untuk menunjuk ke SimpulSenarai yang baru yang diinisialisasi dengan objek itemSisip (baris 97-98). Konstruktor SimpulSenarai pada baris 9-11 (kode 14.2) memanggil konstruktor CSimpulSenarai  pada baris 16-19 (kode 14.2) untuk menetapkan variabel instans data untuk menunjuk ke object yang dilewatkan sebagai argumen pertama dan kemudian menetapkan berikutnya untuk menunjuk ke null.

3.       Jika senarai tidak kosong, maka simpul baru dirantaikan ke dalam senarai dengan menetapkan simpulAkhir dan simpulAkhir.berikutnya agar menunjuk ke objek SimpulSenarai yang baru, yang diinisialisasi dengan objek itemSisip (baris 101-102). Ketika konstruktor SimpulSenarai (baris 16-19 pada kode 14.2) dieksekusi, ia akan menetapkan variabel instans data agar menunjuk ke object yang dilewatkan sebagai argumen dan melakukan penyisipan dengan menetapkan referensi berikutnya agar menunjuk ke null.

Gambar 14.4 mengilustrasikan metode SisipDiBelakang. Bagian a) menggambarkan senarai dan SimpulSenarai yang baru (yang memuat nilai 5) selama operasi SisipDiBelakang dan sebelum perantaian simpul yang baru tersebut ke dalam senarai. Anak panah putus-putus pada bagian b) mengilustrasikan langkah-langkah pada operasi SisipDiBelakang, yang membuat SimpulSenarai menjadi bagian belakang senarai yang baru.


Gambar 14.4 Representasi grafikal atas SisipDiBelakang


Metode HapusDariDepan (kode 14.2, baris 107-127) menghapus simpul depan dari senarai dan menghasilkan (menjadikan nilai balik) sebuah referensi yang menunjuk ke data terhapus. Metode ini melemparkan EksepsiSenaraiKosong (baris 114) jika program mencoba menghapus sebuah simpul dari senarai kosong. Metode ini memuat empat langkah:

1.       Menugaskan simpulPertama.Data (data yang akan dihapus dari senarai) kepada referensi itemHapus (baris 116).

2.       Jika objek-objek yang ditunjuk oleh simpulPertama dan simpulAkhir adalah objek yang sama, maka ini mengindikasikan bahwa senarai hanya memuat satu elemen saja sebelum operasi penghapusan dilakukan. Pada kasus ini, metode HapusDariDepan menetapkan simpulPertama dan simpulAkhir menjadi null (baris 120) untuk menghapus simpul dari senarai (sehingga senarai menjadi kosong).

3.       Jika senarai memuat lebih dari satu simpul sebelum penghapusan, maka metode ini membiarkan simpulAkhir seperti adanya dan hanya menugaskan simpulPertama. Berikunya untuk menunjuk ke simpulPertama (baris 123). Jadi, simpulPertama mereferensi simpul kedua sebelum pemanggilan metode HapusDariDepan.

4.       Menghasilkan referensi itemHapus.

Gambar 14.5 mengilustrasikan metode HapusDariDepan. Bagian a) mengilustrasikan senarai sebelum operasi penghapusan. Bagian b) memotret manipulasi referensi yang terjadi.



Gambar 14.5 Representasi grafikal atas HapusDariDepan


Metode HapusDariBelakang (kode 14.2, baris 130-160) menghapus simpul akhir pada sebuah senarai dan menghasilkan sebuah referensi yang menunjuk ke data terhapus. Metode ini melemparkan EksepsiSenaraiKosong (baris 137) jika program mencoba menghapus sebuah simpul dari senarai kosong. Metode ini terdiri-dari tujuh langkah:
1.       Menugaskan simpulAkhir.Data (data yang akan dihapus dari senarai) kepada referensi itemHapus (baris 139).

2.       Jika objek-objek yang ditunjuk oleh simpulPertama dan simpulAkhir adalah objek yang sama (baris 142), maka ini mengindikasikan bahwa senarai hanya memuat satu elemen saja sebelum operasi penghapusan dilakukan. Pada kasus ini, metode HapusDariBelakang menetapkan simpulPertama dan simpulAkhir menjadi null (baris 143) untuk menghapus simpul dari senarai (sehingga senarai menjadi kosong).
3.       Jika senarai memuat lebih dari satu simpul sebelum penghapusan, maka diciptakan referensi SimpulSenarai, sekarang, dan menugasinya simpulPertama (baris 147).

4.       Menggunakan sekarang untuk menjelajahi senarai sampai sekarang mereferensi simpul yang secara langsung berada tepat sebelum simpul akhir. Loop while (baris 150-151) menugaskan sekarang.Berikutnya untuk mereferensi sekarang asalkan sekarang. Berikutnya tidak sama dengan simpulAkhir.

5.       Setelah mengetahui lokasi simpul kedua terakhir, dilakukan penugasan sekarang kepada simpulAkhir (baris 154) untuk menghapus simpul akhir dari senarai.

6.       Menetapkan sekarang.Berikutnya menjadi null (baris 155) pada simpul akhir yang baru.

7.       Menghasilkan referensi itemHapus (baris 113).


Gambar 14.6 Representasi grafikal atas HapusDariBelakang


Tumpukan
Tumpukan adalah versi terkekang dari sebuah senarai berantai, dimana simpul baru dapat ditambahkan pada dan dihapus dari tumpukan hanya dari atasnya. Karena alasan ini, tumpukan disebuah dengan struktur data LIFO (least-in, first-out). Anggota link pada simpul bawah tumpukan ditetapkan menjadi Nothing untuk mengindikasikan bagian bawah tumpukan.

Beberapa operasi utama yang digunakan untuk memanipulasi tumpukan adalah push dan pop. Operasi push menambahkan sebuah simpul baru di atas tumpukan. Operasi pop menghapus sebuah simpul dari atas tumpukan dan menjadikan data dari simpul yang terhapus sebagai nilai balik.

Tumpukan memiliki banyak aplikasi. Sebagai contoh, ketika program memanggil sebuah metode, metode terpanggil harus mengetahui bagaiman kembali kepada pemanggilnya, sehingga alamat kembali ditempatkan di atas tumpukan eksekusi program. Jika serangkaian pemanggilan metode terjadi, alamat-alamat kembali ditempatkan ke atas tumpukan deengan gaya LIFO sehingga setiap metode dapat kembali kepada pemanggilnya.

Relasi yang dekat antara senarai dan tumpukan akan dipakai untuk mengimplementasikan kelas tumpukan dengan mendaur-ulang kelas senarai. Dua bentuk pendaur-ulangan kode akan didemons-trasikan. Pertama, akan diimplementasikan kelas tumpukan dengan mewarisi kelas CSenarai pada kode 14.3. Kemudian, akan diimplementasikan kelas tumpukan yang identik melalui komposisi dengan menyertakan objek Senarai sebagai anggota private dari kelas tumpukan.

Program pada kode 14.4 dan kode 14.5 menciptakan sebuah kelas tumpukan dengan mewarisi kelas Senarai pada kode 14.2. Diinginkan bahwa tumpukan menyediakan metode Push, Pop, ApaKosong, dan Tampil. Secara esensial, semuanya adalah metode SisipDiDepan, HapusDariDepan, ApaKosong, dan Tampil dari kelas Senarai. Kelas Senarai memiliki beberapa metode lain, seperti SisipDiBelakang dan HapusDariBelakang, yang tidak bisa diakses melalui antarmuka public pada tumpukan. Ingat bahwa semua metode pada antarmuka public pada kelas Senarai adalah metode public pada kelas terderivasi PewarisanTumpukan (kode 14.4).

Ketika metode-metode tumpukan diimplementasikan, setiap metode PewarisanTumpukan memanggil metode Senarai yang sesuai, yaitu metode Push memanggil SisipDiDepan dan metode Pop memanggil HapusDariDepan. Kelas PewarisanTumpukan  tidak mendefinisikan metode ApaKosong dan Tampil, karena PewarisanTumpukan mewarisi kedua metode ini dari kelas Senarai. Semua metode pada kelas PewarisanTumpukan tidak menggunakan statemen lock. Setiap metode pada kelas ini memanggil metode dari kelas Senarai yang menggunakan lock.

Metode Main pada UjiPewarisanTumpukan (kode 14.5) menggunakan kelas PewarisanTumpukan untuk menginstansiasi sebuah tumpukan object, dinamai tumpukan. Baris 18-21 mendefinisikan empat objek yang akan ditempatkan ke atas tumpukan dan dihapus dari tumpukan. Program menempatkan sebuah bool dengan nilai true, sebuah char dengan nilai $, sebuah integer dengan nilai 34567, dan sebuah string dengan nilai “hallo” ke atas tumpukan (baris 24, 26, 28, dan 30). Loop while tak-hingga (baris 36-41) menghapus elemen-elemen tersebut dari tumpukan. Ketika tidak ada lagi objek yang akan dihapus, metode Pop melempar Eksepsi-SenaraiKosong, dan program menampilkan jejak tumpukan eksepsi, yang menggambarkan tumpukan eksekusi program ketika eksepsi terjadi. Program menggunakan metode Tampil (diwarisi dari kelas Senarai) untuk menampilkan isi tumpukan setelah tiap operasi dilakukan.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// Kode 14.4: PustakanPewarisanTumpukan.cs
// Mengimplementasikan sebuah tumpukan dengan mewarisi kelas Senarai.

using System;
using PustakaSenaraiBerantai;

namespace PustakaPewarisanTumpukan
{
    // kelas PewarisanTumpukan mewarisi kapabilitas kelas Senarai
    public class PewarisanTumpukan : Senarai
    {
        // melewatkan nama "tumpukan" kepada konstruktor Senarai
        public PewarisanTumpukan() : base( "tumpukan" )
        {
        }

        // menempatkan nilaiData di atas tumpukan dengan menyisipkan
        // nilaiData di depan senarai berantai
        public void Push( object nilaiData )
        {
            SisipDiDepan( nilaiData );
        }

        // menghapus item dari atas tumpukan dengan menghapus
        // item di depan senarai berantai
        public object Pop()
        {
            return HapusDariDepan();
        }

    } // akhir kelas PewarisanTumpukan
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// Kode 14.5: UjiPewarisanTumpukan.cs
// Menguji kelas PewarisanTumpukan.

using System;
using PustakaPewarisanTumpukan;
using PustakaSenaraiBerantai;

namespace UjiPewarisanTumpukan
{
    // demonstrasi fungsionalitas kelas PewarisanTumpukan
    class UjiPewarisanTumpukan
    {
        static void Main( string[] args )
        {
            PewarisanTumpukan tumpukan = new PewarisanTumpukan();

            // menciptakan objek-objek untuk disimpan di dalam tumpukan
            bool aBoolean = true;
            char aKarakter = '$';
            int aInteger = 34567;
            string aString = "hallo";

            // menggunakan metode Push untuk menambah item ke atas tumpukan
            tumpukan.Push( aBoolean );
            tumpukan.Tampil();
            tumpukan.Push( aKarakter );
            tumpukan.Tampil();
            tumpukan.Push( aInteger );
            tumpukan.Tampil();
            tumpukan.Push( aString );
            tumpukan.Tampil();

            // menggunakan metode Pop untuk menghapus item dari tumpukan
            try
            {
                while ( true )
                {
                    object objekHapus = tumpukan.Pop();
                    Console.WriteLine( objekHapus + " dihapus" );
                    tumpukan.Tampil();
                }
            }

            // jika eksepsi terjadi, tampilkan jejak tumpukan
            catch (EksepsiSenaraiKosong eksepsiSenaraiKosong)
            {
                Console.Error.WriteLine(
                eksepsiSenaraiKosong.StackTrace);
            }

      } // akhir metode Main

    } // akhir kelas UjiPewarisanTumpukan
}

# tumpukan adalah: 34567 $ True

# tumpukan adalah: hallo 34567 $ True

hallo dihapus
# tumpukan adalah: 34567 $ True

34567 dihapus
# tumpukan adalah: $ True

$ dihapus
# tumpukan adalah: True

True dihapus
tumpukan Kosong
   at PustakaSenaraiBerantai.Senarai.HapusDariDepan() in E:\PustakaSenaraiBerantai.cs:line 114
   at PustakaPewarisanTumpukan.PewarisanTumpukan.Pop() in E:\PustakaPewarisanTumpukan.cs:line 27
   at UjiPewarisanTumpukan.UjiPewarisanTumpukan.Main(String[] args) in E:\UjiPewarisanTumpukan.cs:line 37

Cara lain dalam mengimplementasikan sebuah kelas tumpukan adalah dengan mendaur-ulang kelas senarai melalui komposisi. Kelas pada 14.6 menggunakan sebuah objek private dari kelas Senarai (baris 12) di dalam definisi kelas KomposisiTumpukan. Komposisi memampukan Anda untuk menyembunyikan metode-metode kelas Senarai yang tidak perlu muncul di dalam antarmuka public tumpukan. Hal ini dilakukan dengan menyediakan antarmuka public bagi metode-metode yang diperlukan oleh metode-metode Senarai. Kelas KomposisiTumpukan mengimplemen-tasikan setiap metode tumpukan dengan mendelgasikan pekerjaanya kepada metode Senarai yang sesuai. Kelas KomposisiTumpukan memanggil metode-metode Senarai, seperti SisipDi-Depan, HapusDariDepan, ApaKosong, dan Tampil.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// Kode 14.6: PustakaKomposisiTumpukan.cs
// Definisi KomposisiTumpukan dengan objek Senarai terkomposisi.

using System;
using PustakaSenaraiBerantai;

namespace PustakaKomposisiTumpukan
{
    // kelas KomposisiTumpukan mengenkapsulasi kapabilitas Senarai
    public class KomposisiTumpukan
    {
        private Senarai tumpukan;

        // menciptakan tumpukan kosong
        public KomposisiTumpukan()
        {
            tumpukan = new Senarai( "tumpukan" );
        }

        // menambahkan objek ke atas tumpukan
        public void Push( object nilaiData )
        {
            tumpukan.SisipDiDepan( nilaiData );
        }

        // menghapus objek dari tumpukan
        public object Pop()
        {
            return tumpukan.HapusDariDepan();
        }

        // menentukan apakah tumpukan kosong
        public bool ApaKosong()
        {
            return tumpukan.ApaKosong();
        }

        // menampilkan isi tumpukan
        public void Tampil()
        {
            tumpukan.Tampil();
        }

    } // akhir kelas KomposisiTumpukan
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// Kode 14.7: UjiKomposisiTumpukan.cs
// Menguji kelas KomposisiTumpukan.

using System;
using PustakaKomposisiTumpukan;
using PustakaSenaraiBerantai;
namespace UjiKomposisiTumpukan
{
    // demonstrasi fungsionalitas kelas PewarisanTumpukan
    class UjiKomposisiTumpukan
    {
        static void Main( string[] args )
        {
            KomposisiTumpukan tumpukan = new KomposisiTumpukan();

            // menciptakan objek-objek untuk disimpan di dalam tumpukan
            bool aBoolean = true;
            char aKarakter = '$';
            int aInteger = 34567;
            string aString = "hallo";

            // menggunakan metode Push untuk menambahkan item ke atas tumpukan
            tumpukan.Push( aBoolean );
            tumpukan.Tampil();
            tumpukan.Push( aKarakter );
            tumpukan.Tampil();
            tumpukan.Push( aInteger );
            tumpukan.Tampil();
            tumpukan.Push( aString );
            tumpukan.Tampil();

            // menggunakan metode Pop untuk menghapus item dari tumpukan
            try
            {
                while ( true )
                {
                    object objekHapus = tumpukan.Pop();
                    Console.WriteLine( objekHapus + " dihapus" );
                    tumpukan.Tampil();
                }
            }

            // jika eksepsi terjadi, tampilkan jejak tumpukan
            catch (EksepsiSenaraiKosong eksepsiSenaraiKosong)
            {
                Console.Error.WriteLine(
                    eksepsiSenaraiKosong.StackTrace);
            }

      } // akhir metode Main

    } // akhir kelas UjiKomposisiTumpukan
}

# tumpukan adalah: 34567 $ True

# tumpukan adalah: hallo 34567 $ True

hallo dihapus
# tumpukan adalah: 34567 $ True

34567 dihapus
# tumpukan adalah: $ True

$ dihapus
# tumpukan adalah: True

True dihapus
Kosong tumpukan
   at CSenarai.HapusDariDepan() in E:\CSenarai.vb:line 65
   at CKomposisiTumpukan.Pop() in E:\CKomposisiTumpukan.vb:line 20
   at modUjiKomposisiTumpukan.Main() in E:\modUjiKomposisiTumpukan.vb:line 38


Antrian
Struktur data lain yang umum dijumpai adalah antrian. Antrian sama seperti antrian di pusat perbelanjaan, dimana orang pertama dalam antrian akan dilayani lebih dahulu, dan para pelanggan lainnya harus menunggu untuk dilayani. Simpul antrian dihapus hanya dari kepala antrian dan disisipkan hanya di ekor antrian. Karena alasan ini, antrian disebut dengan struktur data FIFO (first-in first-out). Operasi penyisipan dan operasi penghapusan dikenal sebagai enqueue dan dequeue.

Program pada kode 14.8 dan kode 14.9 menciptakan sebuah kelas antrian melalui pewarisan dari kelas senarai. Diinginkan bahwa kelas PewarisanAntrian (kode 14.8) untuk menyertakan metode-metoe Enqueue, Dequeue, ApaKosong, dan Tampil. Perhatikan bahwa secara esensial semua metode tersebut adalah SisipDiBelakang, HapusDariDepan, ApaKosong, dan Tampil dari kelas Senarai.

Ketika Anda mengimplementasikan metode-metode antrian, setiap pemanggilan metode PewarisanAntrian akan memanggil metode Senarai yang sesuai, dimana metode Enqueue memanggil SisipDiBelakang, dan metode Dequeue memangil HapusDariDepan, sedangkan ApaKosong dan Tampil memanggil versi kelas-basisnya.

Metode Main pada kelas UjiAntrian (kode 14.9) menggunakan kelas PewarisanAntrian untuk menginstansiasi sebuah antrian object, dinamai antrian. Baris 18-21 mendefinisikan empat objek yang akan ditempatkan ke dalam antrian dan dihapus dari antrian. Program menempatkan sebuah boolean dengan nilai true, sebuah char dengan nilai $, sebuah integer dengan nilai 34567, dan sebuah string dengan nilai “hallo” ke dalam antrian (baris 24, 26, 28, dan 30).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// Kode 14.8: PustakaPewarisanAntrian.cs
// Mengimplementasikan sebuah antrian dengan mewarisi kelas Senarai.

using System;
using PustakaSenaraiBerantai;

namespace PustakaPewarisanAntrian
{
    // PewarisanAntrian mewarisi kapabilitas Senarai
    public class PewarisanAntrian : Senarai
    {
        // melewatkan nama "antrian" kepada konstruktor Senarai
        public PewarisanAntrian() : base("antrian")
        {
        }

        // menempatkan nilaiData di akhir antrian dengan menyisipkan
        // nilaiData di akhir senarai berantai
        public void Enqueue( object nilaiData )
        {
            SisipDiBelakang( nilaiData );
        }

        // menghapus item dari depan antrian dengan menghapus
        // item di depan senarai berantai
        public object Dequeue( )
        {
            return HapusDariDepan();
        }

    } // akhir PewarisanAntrian
}

Loop while tak-hingga (baris 39-44) menghapus elemen-elemen tersebut dari antrian dengan urutan FIFO. Ketika tidak ada lagi objek yang akan dihapus, metode Dequeu akan melempar Eksepsi-SenaraiKosong, dan program menampilkan jejak tumpukan eksepsi, yang menggambarkan tumpukan eksekusi program ketika eksepsi terjadi. Program menggunakan metode Tampil (diwarisi dari kelas Senarai) untuk menampilkan isi tumpukan setelah tiap operasi dilakukan.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// Kode 14.9: UjiAntrian.cs
// Menguji kelas PewarisanAntrian.

using System;
using PustakaPewarisanAntrian;
using PustakaSenaraiBerantai;

namespace UjiAntrian
{
    // demonstrasi fungsionalitas kelas PewarisanAntrian
    class UjiAntrian
    {
        static void Main( string[] args )
        {
            PewarisanAntrian antrian = new PewarisanAntrian();

            // menciptakan objek-objek untuk disimpan di dalam antrian
            bool aBoolean = true;
            char aKarakter = '$';
            int aInteger = 34567;
            string aString = "hallo";

            // menggunakan metode Enqueue untuk menambahkan item pada antrian
            antrian.Enqueue( aBoolean );
            antrian.Tampil();
            antrian.Enqueue( aKarakter );
            antrian.Tampil();
            antrian.Enqueue( aInteger );
            antrian.Tampil();
            antrian.Enqueue( aString );
            antrian.Tampil();

            // menggunakan metode Dequeue untuk menghapus item dari antrian
            object objekHapus = null;

            // menghapus item dari antrian
            try
            {
                while ( true )
                {
                    objekHapus = antrian.Dequeue();
                    Console.WriteLine( objekHapus + " dihapus dari antrian" );
                    antrian.Tampil();
                }
            }

            // jika eksepsi terjadi, tampilkan jejak tumpukan pemanggilan
            catch (EksepsiSenaraiKosong eksepsiSenaraiKosong)
            {
                Console.Error.WriteLine(
                eksepsiSenaraiKosong.StackTrace);
            }

        } // akhir metode Main

    } // akhir kelas UjiAntrian
}



# tumpukan adalah: True

# tumpukan adalah: $ True

# tumpukan adalah: 34567 $ True

# tumpukan adalah: hallo 34567 $ True

hallo dihapus
# tumpukan adalah: 34567 $ True

34567 dihapus
# tumpukan adalah: $ True

$ dihapus
# tumpukan adalah: True

True dihapus
Kosong tumpukan
   at CSenarai.HapusDariDepan() in E:\CSenarai.vb:line 65
   at CKomposisiTumpukan.Pop() in E:\CKomposisiTumpukan.vb:line 20
   at modUjiKomposisiTumpukan.Main() in E:\modUjiKomposisiTumpukan.vb:line 38


Pohon
Senarai berantai, tumpukan, dan antrian adalah struktur data linier. Sebaliknya, pohon adalah struktur data tak-linier, dua dimensi, dengan beberapa sifat spesial. Setiap simpul pada pohon mempunyai dua atau lebih link atau rantai. Bagian ini akan mendiskusikan pohon biner (Gambar 14.7), atau pohon dengan setiap simpul memiliki dua link (tidak ada, satu atau keduanya bisa null). Simpul akar adalah simpul pertama pada pohon. Setiap link pada simpul akar disebut dengan anak. Anak kiri adalah simpul pertama pada subpohon kiri, dan anak kanan adalah simpul pertama pada subpohon kanan. Semua anak dari simpul tertentu disebut dengan sibling atau saudara. Sebuah simpul yang tidak memiliki anak disebut dengan simpul daun.

Contoh pohon-biner yang disajikan akan menciptakan sebuah pohon biner spesial, yang dikenal dengan pohon pencarian biner (binary search tree). Sebuah pohon pencarian biner (tanpa nilai simpul duplikat) memiliki karakteristik bahwa nilai-nilai pada sembarang subpohon kiri lebih rendah dari nilai simpul induk subpohon, dan bahwa nilai-nilai pada sembarang subpohon kanan lebih tinggi dari simpul induk subpohon. Gambar 14.8 mengilustrasikan sebuah pohon pencarian biner yang memuat 12 integer. Perhatikan bahwa bentuk sebuah pohon pencarian biner yang terkait dengan suatu himpunan data sangat bergantung pada urutan penyisipan nilai-nilai ke dalam pohon.


Gambar 14.7 Representasi grafikal atas pohon biner



Gambar 14.8 Pohon pencarian biner yang memuat 12 integer


Pohon Pencarian Biner dengan Nilai-Nilai Integer
Aplikasi pada kode 14.10 dan kode 14.11 menciptakan sebuah pohon pencarian biner dengan nilai-nilai integer dan kemudian menjelajahi pohon tersebut (berjalan melalui semua simpulnya) dalam tiga cara, yaitu menggunakan penjelajahan inorder, preorder, dan postorder rekursif. Program membangkitkan 10 angka acak dan menyisipkan setiap angka acak itu ke dalam pohon. Kode 14.10 mendefinisikan kelas Pohon. Kode 14.11 mendefinisikan UjiPohon, yang mendemonstrasikan fungsionalitas kelas Pohon. Metode Main pada UjiPohon menginstansiasi sebuah objek Pohon kosong, yang secara acak membangkitkan 10 integer dan menyisipkan setiap nilai ke dalam pohon menggunakan metode SisipSimpul. Program kemudian melakukan penjelajahan pohon secara preorder, inorder, dan postorder.

Kelas SimpulPohon (kode 14.10) merupakan sebuah kelas referensi-diri yang memuat tiga anggota data private, yaitu simpulKiri dan simpulKanan yang keduanya bertipe SimpulPohon dan data yang bertipe int. Awalnya, setiap SimpulPohon adalah simpul daun, jadi konstruktor (baris 16-20) menginisialisasi referensi simpulKiri dan simpulKanan dengan null. Properti SimpulKiri (baris 23-34), Data (baris 37-48), dan SimpulKanan (baris 51-62) menyediakan akses terhadap anggota-anggota private kelas SimpulPohon.

Kelas Pohon (baris 98-198, kode 14.10) memanipulasi objek-objek kelas SimpulPohon. Kelas Pohon memuat sebuah simpul private akar (baris 100), yaitu sebuah referensi yang menunjuk ke simpul akar pohon. Kelas ini juga memuat anggota public SisipSimpul (baris 111-121), yang menyisipkan sebuah simpul ke dalam pohon, dan metode-metode public PenjelajahanPreorder (baris 124-130), PenjelajahanInorder (baris 149-155), dan PenjelajahanPostorder (baris 174-180), yang memulai penjelajahan pohon. Setiap metode penjelajah memanggil metode utilitas rekursif secara terpisah untuk melakukan operasi penjelajahan pada pohon. Konstruktor Pohon (baris 103-106) menginisialisasi akar dengan null untuk mengindikasikan bahwa pohon awalnya kosong.

Metode SisipSimpul pada kelas Pohon pertama-tama mengunci objek Pohon dan kemudian menentukan apakah pohon kosong atau tidak. Jika kosong, baris 116 akan menginstansiasi sebuah objek SimpulPohon, menginisialisasi simpul dengan integer yang akan disisipkan, dan menugaskan simpul baru kepada akar. Jika pohon tidak kosong, maka metode SisipSimpul akan memanggil metode Sisip (baris 67-93) dari kelas SimpulPohon, yang secara rekursif menentukan lokasi untuk simpul baru di dalam pohon dan menyisipkan simpul pada lokasi itu.

Metode Sisip pada kelas SimpulPohon melakukan perbandingan atas nilai yang akan disisipkan dengan nilai data pada simpul akar. Jika nilai yang akan disisipkan kurang dari data simpul-akar, maka program menentukan apakah subpohon kiri kosong atau tidak (baris 73). Jika kosong, maka baris 74 akan menginstansiasi sebuah objek SimpulPohon, menginisialisasinya dengan integer yang akan disisipkan, dan menugaskan simpul baru pada referensi simpulKiri. Sebaliknya, jika subpohon kiri tidak kosong, maka baris 90 akan secara rekursif memanggil metode Sisip pada subpohon kiri untuk menyisipkan nilai ke dalam subpohon kiri.

Metode-metode PenjelajahanInorder, PenjelajahanPreorder, dan PenjelajahanPostorder memanggil metode-metode pembantu PembantuInorder (baris 158-171), PembantuPreorder (baris 133-146), dan PembantuPostorder (baris 183-196) untuk menjelajah pohon dan menampilkan nilai setiap simpul. Setiap metode pembantu pada kelas Pohon membuat programer dapat mengawali penjelajahan tanpa perlu terlebih dahulu mendapatkan sebuah referensi yang menunjuk ke simpul pertama akar dan kemudian memanggil metode rekursif dengan referensi itu. Metode-metode PenjelajahanInorder, PenjelajahanPreorder, dan PenjelajahanPostorder cukup mengambil referensi private akar dan melewatkannya kepada metode pembantu yang sesuai untuk mengawali penjelajahan pohon.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
// Kode 14.10: PustakaPohonBiner.cs
// Definisi kelas SimpulPohon dan kelas Pohon.

using System;

namespace PustakaPohonBiner
{
    // definisi kelas SimpulPohon
    class SimpulPohon
    {
        private SimpulPohon simpulKiri;
        private int data;
        private SimpulPohon simpulKanan;

        // inisialisasi data dan membuat simpul daun
        public SimpulPohon( int dataSimpul )
        {
            data = dataSimpul;
            simpulKiri = simpulKanan = null; // simpul tidak memiliki anak
        }

        // properti SimpulKiri property
        public SimpulPohon SimpulKiri
        {
            get
            {
                return simpulKiri;
            }

            set
            {
                simpulKiri = value;
            }
        }

        // properti Data
        public int Data
        {
            get
            {
                return data;
            }

            set
            {
                data = value;
            }
        }

        // properti SimpulKanan
        public SimpulPohon SimpulKanan
        {
            get
            {
                return simpulKanan;
            }

            set
            {
                simpulKanan = value;
            }
        }


        // menyisipkan SimpulPohon ke dalam Pohon yang memuat simpul-simpul;
        // mengabaikan nilai-nilai duplikat
        public void Sisip( int nilaiSisip )
        {
            // sisip di subpohon kiri
            if ( nilaiSisip < data )
            {
                // sisip SimpulPohon yang baru
                if ( simpulKiri == null )
                    simpulKiri = new SimpulPohon( nilaiSisip );

                // melanjutkan penjelajahan subpohon kiri
                else
                    simpulKiri.Sisip( nilaiSisip );
            }

            // sisip di subpohon kanan
            else if ( nilaiSisip > data )
            {
               // sisip SimpulPohon yang baru
               if ( simpulKanan == null )
                    simpulKanan = new SimpulPohon( nilaiSisip );

               // melanjutkan penjelajahan subpohon kanan
               else
                    simpulKanan.Sisip( nilaiSisip );
            }

        } // akhir metode Sisip

    } // akhir kelas SimpulPohon

    // definisi kelas Pohon
    public class Pohon
    {
        private SimpulPohon akar;

        // menciptakan sebuah Pohon kosong yang memuat integer-integer
        public Pohon()
        {
            akar = null;
        }
   
        // menyisipkan sebuah simpul baru di dalam pohon pencarian biner.
        // jika simpul akar kosong, ciptakan simpul akar di sini.
        // Sebaliknya, panggil metode sisip dari kelas SimpulPohon.
        public void SisipSimpul( int nilaiSisip )
        {
            lock ( this )
            {
                if ( akar == null )
                    akar = new SimpulPohon( nilaiSisip );

                else
                    akar.Sisip( nilaiSisip );
            }
        }

        // memulai penjelajahan preorder
        public void PenjelajahanPreorder()
        {
            lock ( this )
            {
                PembantuPreorder( akar );
            }
        }

        // metode rekursif untuk melakukan penjelajahan preorder
        private void PembantuPreorder(SimpulPohon simpul)
        {
            if ( simpul == null )
                return;

            // menampilkan data simpul
            Console.Write( simpul.Data + " " );

            // menjelajah subpohon kiri
            PembantuPreorder(simpul.SimpulKiri);

            // menjelajah subpohon kanan
            PembantuPreorder(simpul.SimpulKanan);
        }

        // memulai penjelajahan inorder
        public void PenjelajahanInorder()
        {
            lock ( this )
            {
                PembantuInorder( akar );
            }
        }

        // metode rekursif untuk melakukan penjelajahan inorder
        private void PembantuInorder(SimpulPohon simpul)
        {
            if ( simpul == null )
                return;

            // menjelajah subpohon kiri
            PembantuInorder(simpul.SimpulKiri);

            // menampilkan data simpul
            Console.Write( simpul.Data + " " );

            // menjelajah subpohon kanan
            PembantuInorder(simpul.SimpulKanan);
        }

        // memulai penjelajahan postorder
        public void PenjelajahanPostorder()
        {
            lock ( this )
            {
                PembantuPostorder( akar );
            }
        }

        // metode rekursif untuk melakukan penjelajahan postorder
        private void PembantuPostorder(SimpulPohon simpul)
        {
            if ( simpul == null )
                return;

            // menjelajah subpohon kiri
            PembantuPostorder(simpul.SimpulKiri);

            // menjelajah subpohon kanan
            PembantuPostorder(simpul.SimpulKanan);

            // menampilkan data simpul
            Console.Write( simpul.Data + " " );
        }

    } // akhir kelas Pohon
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// Kode 14.11: UjiPohon.cs
// Program ini menguji kelas Pohon.

using System;
using PustakaPohonBiner;

namespace UjiPohon
{
    // definisi kelas UjiPohon
    public class UjiPohon
    {
        // menguji kelas Pohon
        static void Main( string[] args )
        {
            Pohon pohon = new Pohon();
            int nilaiSisip;

            Console.WriteLine( "Menyisipkan nilai-nilai: " );
            Random acak = new Random();

            // menyisipkan 10 integer acak dari 0-99 ke dalam pohon
            for ( int i = 1; i <= 10; i++ )
            {
                nilaiSisip = acak.Next( 100 );
                Console.Write( nilaiSisip + " " );

                pohon.SisipSimpul( nilaiSisip );
            }

            // melakukan penjelajahan preorder pada pohon
            Console.WriteLine( "\n\nPenjelajahan Preorder" );
                pohon.PenjelajahanPreorder();

            // melakukan penjelajahan inorder pada pohon
            Console.WriteLine( "\n\nPenjelajahan Inorder" );
                pohon.PenjelajahanInorder();

            // melakukan penjelajahan postorder pada pohon
            Console.WriteLine( "\n\nPenjelajahan Postorder" );
                pohon.PenjelajahanPostorder();
            Console.WriteLine();
        }

    } // akhir kelas UjiPohon
}

Menyisipkan nilai-nilai:
2 64 74 52 32 57 99 46 10 55

Penjelajahan Preorder
2 64 52 32 10 46 57 55 74 99

Penjelajahan Inorder
2 10 32 46 52 55 57 64 74 99

Penjelajahan Postorder
10 46 32 55 57 52 99 74 64 2


Pohon Pencarian Biner dengan Objek-Objek IComparable
Contoh pohon-biner sebelumnya dapat bekerja dengan baik ketika semua data bertipa int. Namun, bila dimisalkan bahwa seorang programer ingin memanipulasi sebuah pohon pencarian biner yang memuat nilai-nilai double, maka ia harus menuliskan-ulang kelas SimpulPohon dan Pohon sehingga dapat dipakai untuk memanipulasi nilai-nilai double.

Pada contoh selanjutnya, akan digunakan kapabilitas polimorfik pada C#. Akan diimplementasikan kelas CSimpulPohon dan CPohon, yang memanipulasi objek-objek yang mengimplementasikan antarmuka IComparable (dari namespace System). Kelas yang mengimplementasikan antarmuka IComparable mendefinisikan metode CompareTo, yang membanding-kan objek yang memanggil metode dengan objek yang diterima metode tersebut sebagai argumen. Metode menghasilkan sebuah nilai int yang kurang dari nol jika objek pemanggil kurang dari objek argumen, nol jika kedua objek sama, atau sebuah Integer lebih besar dari nol jika objek pemanggil lebih besar dari objek argumen. Di samping itu, kedua objek pemanggil dan objek argumen harus bertipe data sama; jika tidak, metode akan melemparkan ArgumentException.

Program pada kode 14.12 dan kode 14.13 memperbaiki program sebelumnya untuk memanipulasi objek IComparable. Satu pembatasan pada versi baru dari kelas SimpulPohon dan Pohon adalah bahwa setiap objek Pohon dapat memuat objek dengan satu tipe data (misalnya, semuanya string atau semuanya double). Jika program mencoba untuk menyisipkan beberapa data berbeda pada objek Pohon yang sama, maka ArgumentException akan terjadi. Yang dimodifikasi hanyalah enam baris kode pada kelas SimpulPohon (baris 13, 17, 38, 67, 70, dan 82) dan satu baris kode pada kelas Pohon (baris 111) untuk memampukan pemrosesan objek IComparable. Dengan pengecualian pada baris 70 dan 82, semua modifikasi hanya mengganti tipe int dengan tipe IComparable. Baris 70 dan 82 sebelumnya menggunakan operator < dan > dalam membandingkan nilai yang disisipkan dengan nilai di dalam simpul tertentu. Kedua baris tersebut sekarang membandingkan objek-objek IComparable menggunakan metode CompareTo; Metode ini dipakai untuk menentukan nilai balik kurang dari nol (objek pemanggil kurang dari objek argumen), nol (objek pemanggil sama dengan objek argumen), atau lebih besar dari nol (objek pemanggil lebih besar dari objek argumen).

Kelas UjiPohon (kode 14.13) menciptakan tiga objek Pohon untuk menyimpan nilai-nilai int, double, dan string, yang semuanya didefinisikan C# sebagai tipe IComparable. Program mengisi pohon dari nilai-nilai pada array arrayInteger (baris 15), arrayDouble (baris 16-17), dan arrayString (baris 18-19), dan kemudian memanggil metode jelajahanPohon untuk menampilkan penjelajahan preorder, inorder, dan postorder atas pohon Pohon. Metode isiPohon (baris 38-48) menerima sebagai argumen sebuah Array yang memuat nilai-nilai penginisialisasi untuk Pohon, sebuah Pohon yang akan diisi oleh elemen-elemen array, dan sebuah string yang merepresentasikan nama Pohon.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
// Kode 14.12: PustakaPohonBiner2.cs
// Definisi atas kelas SimpulPohon dan kelas Pohon untuk objek-objek
// IComparable.

using System;

namespace PustakaPohonBiner2
{
    // definisi kelas SimpulPohon
    class SimpulPohon
    {
        private SimpulPohon simpulKiri;
        private IComparable data;
        private SimpulPohon simpulKanan;

        // inisialisasi data dan membuat simpul daun
        public SimpulPohon(IComparable dataSimpul)
        {
            data = dataSimpul;
            simpulKiri = simpulKanan = null; // simpul tidak memiliki anak
        }

        // properti SimpulKiri property
        public SimpulPohon SimpulKiri
        {
            get
            {
                return simpulKiri;
            }

            set
            {
                simpulKiri = value;
            }
        }

        // properti Data
        public IComparable Data
        {
            get
            {
                return data;
            }

            set
            {
                data = value;
            }
        }

        // properti SimpulKanan
        public SimpulPohon SimpulKanan
        {
            get
            {
                return simpulKanan;
            }

            set
            {
                simpulKanan = value;
            }
        }

        // menyisipkan SimpulPohon ke dalam Pohon yang memuat simpul-simpul;
        // mengabaikan nilai-nilai duplikat
        public void Sisip(IComparable nilaiSisip)
        {
            // sisip di subpohon kiri
            if (nilaiSisip.CompareTo(data) < 0)
            {
                // sisip SimpulPohon yang baru
                if (simpulKiri == null)
                    simpulKiri = new SimpulPohon(nilaiSisip);

                // melanjutkan penjelajahan subpohon kiri
                else
                    simpulKiri.Sisip(nilaiSisip);
            }

            // sisip di subpohon kanan
            else if (nilaiSisip.CompareTo(data) > 0)
            {
                // sisip SimpulPohon yang baru
                if (simpulKanan == null)
                    simpulKanan = new SimpulPohon(nilaiSisip);

                // melanjutkan penjelajahan subpohon kanan
                else
                    simpulKanan.Sisip(nilaiSisip);
            }

        } // akhir metode Sisip

    } // akhir kelas SimpulPohon

    // definisi kelas Pohon
    public class Pohon
    {
        private SimpulPohon akar;

        // menciptakan sebuah Pohon kosong yang memuat integer-integer
        public Pohon()
        {
            akar = null;
        }

        // menyisipkan sebuah simpul baru di dalam pohon pencarian biner.
        // jika simpul akar kosong, ciptakan simpul akar di sini.
        // Sebaliknya, panggil metode sisip dari kelas SimpulPohon.
        public void SisipSimpul(IComparable nilaiSisip)
        {
            lock (this)
            {
                if (akar == null)
                    akar = new SimpulPohon(nilaiSisip);

                else
                    akar.Sisip(nilaiSisip);
            }
        }

        // memulai penjelajahan preorder
        public void PenjelajahanPreorder()
        {
            lock (this)
            {
                PembantuPreorder(akar);
            }
        }

        // metode rekursif untuk melakukan penjelajahan preorder
        private void PembantuPreorder(SimpulPohon simpul)
        {
            if (simpul == null)
                return;

            // menampilkan data simpul
            Console.Write(simpul.Data + " ");

            // menjelajah subpohon kiri
            PembantuPreorder(simpul.SimpulKiri);

            // menjelajah subpohon kanan
            PembantuPreorder(simpul.SimpulKanan);
        }

        // memulai penjelajahan inorder
        public void PenjelajahanInorder()
        {
            lock (this)
            {
                PembantuInorder(akar);
            }
        }

        // metode rekursif untuk melakukan penjelajahan inorder
        private void PembantuInorder(SimpulPohon simpul)
        {
            if (simpul == null)
                return;

            // menjelajah subpohon kiri
            PembantuInorder(simpul.SimpulKiri);

            // menampilkan data simpul
            Console.Write(simpul.Data + " ");

            // menjelajah subpohon kanan
            PembantuInorder(simpul.SimpulKanan);
        }

        // memulai penjelajahan postorder
        public void PenjelajahanPostorder()
        {
            lock (this)
            {
                PembantuPostorder(akar);
            }
        }

        // metode rekursif untuk melakukan penjelajahan postorder
        private void PembantuPostorder(SimpulPohon simpul)
        {
            if (simpul == null)
                return;

            // menjelajah subpohon kiri
            PembantuPostorder(simpul.SimpulKiri);

            // menjelajah subpohon kanan
            PembantuPostorder(simpul.SimpulKanan);

            // menampilkan data simpul
            Console.Write(simpul.Data + " ");
        }

    } // akhir kelas Pohon
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// Kode 14.13: UjiPohon.cs
// Program ini menguji kelas Pohon.

using System;
using PustakaPohonBiner2;

namespace UjiPohon
{
    // definisi kelas UjiPohon
    public class UjiPohon
    {
        //   menguji kelas Pohon
        static void Main( string[] args )
        {
            int[] arrayInt = { 8, 2, 4, 3, 1, 7, 5, 6 };
            double[] arrayDouble =
                { 8.8, 2.2, 4.4, 3.3, 1.1, 7.7, 5.5, 6.6 };
            string[] arrayString = { "delapan", "dua", "empat",
                "tiga", "satu", "tujuh", "lima", "enam" };

            // menciptakan Pohon int
            Pohon pohonInt = new Pohon();
            isiPohon( arrayInt, pohonInt, "pohonInt" );
            jelajahPohon(pohonInt, "pohonInt");

            // menciptakan Pohon double
            Pohon pohonDouble = new Pohon();
            isiPohon(arrayDouble, pohonDouble, "pohonDouble");
            jelajahPohon(pohonDouble, "pohonDouble");

            // menciptakan Pohon string
            Pohon pohonString = new Pohon();
            isiPohon(arrayString, pohonString, "pohonString");
            jelajahPohon(pohonString, "pohonString");
        }

        // mengisi Pohon dengan elemen-elemen array
        static void isiPohon(
            Array array, Pohon pohon, string nama )
        {
            Console.WriteLine( "\nMenyisipkan ke dalam" + nama + ":" );

            foreach ( IComparable data in array )
            {
                Console.Write( data + " " );
                pohon.SisipSimpul( data );
            }
        }  

        // melakukan penjelajahan
        static void jelajahPohon(Pohon pohon, string tipePohon)
        {
            // melakukan penjelajahan preorder atas pohon
            Console.WriteLine(
                "\n\nPenjelajahan preorder atas " + tipePohon );
                pohon.PenjelajahanPreorder();

            // melakukan penjelajaha inorder atas pohon
            Console.WriteLine(
                "\n\nPenjelajahan inorder atas " + tipePohon );
                pohon.PenjelajahanInorder();

            // melakukan penjelajahan postorder atas pohon
            Console.WriteLine(
                "\n\nPenjelajahan postorder atas " + tipePohon );
            pohon.PenjelajahanPostorder();
            Console.WriteLine( "\n" );
        }
       
    } // akhir kelas UjiPohon
}

Menyisipkan ke dalam pohonInt:
8 2 4 3 1 7 5 6

Penjelajahan preorder atas pohonInt
8 2 1 4 3 7 5 6

Penjelajahan inorder atas pohonInt
1 2 3 4 5 6 7 8

Penjelajahan postorder atas pohonInt
1 3 6 5 7 4 2 8


Menyisipkan ke dalam pohonDouble:
8.8 2.2 4.4 3.3 1.1 7.7 5.5 6.6

Penjelajahan preorder atas pohonDouble
8.8 2.2 1.1 4.4 3.3 7.7 5.5 6.6

Penjelajahan inorder atas pohonDouble
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8

Penjelajahan postorder atas pohonDouble
1.1 3.3 6.6 5.5 7.7 4.4 2.2 8.8

Menyisipkan ke dalam pohonString:
delapan dua empat tiga satu tujuh lima enam

Penjelajahan preorder atas pohonString
delapan dua empat tiga satu lima enam tujuh

Penjelajahan inorder atas pohonString
delapan dua empat enam lima satu tiga tujuh

Penjelajahan postorder atas pohonString
enam lima satu tujuh tiga empat dua delapan


Kelas-Kelas Koleksi
Dengan kelas-kelas koleksi, daripada harus menciptakan struktur data sendiri, programer dapat menggunakan struktur data yang ada tanpa perlu khawatir tentang bagaimana struktur data diimplementasikan. Metodologi ini merepresentasikan beberapa contoh pendaur-ulangan kode. Programer dapat mengkode lebih cepat dan dengan kinerja yang lebih baik dalam hal kecepatan eksekusi dan konsumsi memori.

C# menyediakan beberapa koleksi. Akan didemonstrasikan empat kelas koleksi, yaitu Array, ArrayList, Stack, dan Hashtable. Namespace System.Collections juga menyediakan beberapa struktur data yang lain, termasuk BitArray, Queue, dan SortedList.


Kelas Array
Telah disebutkan bahwa semua array mewarisi kelas Array (namespace System), yang mende-finisikan properti Length yang menspesifikasi jumlah elemen di dalam array. Di samping itu, kelas Array juga menyediakan beberapa metode static yang mendefinisikan beberapa algoritma untuk memproses array. Semua metode kelas Array tersebut dioverload untuk memberikan opsi untuk merealisasikan algoritma. Sebagai contoh, metode Reverse dari kelas Array dapat membalikkan urutan elemen-elemen di dalam array secara keseluruhan atau dapat membalikkan elemen-elemen di dalam rentang tertentu pada array. Kode 14.14 mendemonstrasikan beberapa metode static dari kelas Array.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// Kode 14.14: MenggunakanArray.cs
// Menggunakan kelas Array untuk melakukan beberapa manipulasi array.

using System;
using System.Windows.Forms;
using System.Collections;

namespace MenggunakanArray
{
    // demonstrasi beberapa algoritma kelas Array
    class MenggunakanArray
    {
        private int[] nilaiInt = { 1, 2, 3, 4, 5, 6 };
        private double[] nilaiDouble =
            { 8.4, 9.3, 0.2, 7.9, 3.4 };
        private int[] salinNilaiInt;
        private string keluaran;

        // metode untuk membangun dan menampilkan keluaran program
        public void Start()
        {
            salinNilaiInt = new int[ nilaiInt.Length ];

            keluaran = "Nilai-nilai awal array:\n";
            TampilArray(); // menampilkan isi awal array

            // mengurutkan nilaiDouble
            Array.Sort( nilaiDouble );

            // menyalin nilaiInt ke salinNilaiInt
            Array.Copy( nilaiInt, salinNilaiInt,
                nilaiInt.Length );

            keluaran += "\nIsi array setelah Sort dan Copy:\n";
            TampilArray(); // menampilkan isi array
            keluaran += "\n";

            // mencari 5 di dalam nilaiInt
            int hasil = Array.BinarySearch( nilaiInt, 5 );
            keluaran +=
                ( hasil >= 0 ? "5 ditemukan pada elemen " + hasil :
                "5 tidak ditemukan" ) + " di dalam nilaiInt\n";

            // search for 8763 in intValues
            hasil = Array.BinarySearch( nilaiInt, 8763 );
            keluaran +=
                ( hasil >= 0 ? "8763 ditemukan pada elemen " + hasil :
                "8763 tidak ditemukan" ) + " di dalam nilaiInt";
   
            MessageBox.Show( keluaran, "Menggunakan Kelas Array",
            MessageBoxButtons.OK, MessageBoxIcon.Information );
        }

        // menampilkan isi array
        private void TampilArray()
        {
            keluaran += "nilaiDouble: ";

            foreach ( double elemen in nilaiDouble )
                keluaran += elemen + " ";

            keluaran += "\nnilaiInt: ";

            foreach (int elemen in nilaiInt)
                keluaran += elemen + " ";

            keluaran += "\nsalinNilaiInt: ";

            foreach ( int elemen in salinNilaiInt )
                keluaran += elemen + " ";

            keluaran += "\n";
        }

        // enti utama untuk aplikasi
        static void Main( string[] args )
        {
            MenggunakanArray aplikasi = new MenggunakanArray();

            aplikasi.Start();
        }

    } // akhir kelas MenggunakanArray
}


Gambar 14.9 Keluaran program pada kode 14.14


Baris 28 menggunakan metode static Array, Sort, untuk mengurutkan sebuah array yang memuat nilai-nilai double. Ketika metode ini selesai dieksekusi, array yang memuat elemen-elemen terurut secara menaik dijadikan nilai balik.

Baris 21-32 menggunakan metode static Array, Copy, untuk menyalin setiap elemen array arrayInteger ke dalam array salinArrayInteger. Argumen pertama adalah array yang akan disalin (nilaiInteger), argumen kedua adalah array tujuan penyalinan (salinNilaiInteger), dan argumen ketiga adalah sebuah integer yang merepresentasikan jumlah elemen yang akan disalin (pada kasus ini, properti nilaiInteger.Length menspesifikasi semua elemen akan disalin).

Baris 37 dan 45 memanggil metode static Array, BinarySearch, untuk melakukan pencarian biner terhadap array nilaiInteger. Metode BinarySearch menerima array terurut sebagai lokasi pencarian dan kunci untuk dicari. Metode ini menghasilkan indeks di dalam array, dimana di lokasi tersebut ia menemukan kunci yang dicari, atau jika kunci tidak ditemukan, maka metode menghasilkan nilai negatif.


Kelas ArrayList
Koleksi ArrayList pada C# (namespace System.Collections) menyerupai fungsionalitas array konvensional dan menyediakan kapabilitas pengubahan-ukuran dinamis. Sebuah ArrayList memuat sejumlah elemen, yang kurang dari atau sama dengan kapasitasnya. Jumlah elemen Program dapat memanipulasi kapasitas dengan properti Capacity pada ArrayList. Jika kapasitas  ArrayList perlu diperbesar, maka secara default ia akan menggandakan kapasitasnya.

Metode
Deskripsi
Add



Clear

Contains


IndexOf


Insert

Remove

RemoveAt

RemoveRange


Sort

TrimToSize

Menambahkan sebuah object ke dalam ArrayList. Menghasilkan sebuah int yang menspesifikasi indeks dimana object tersebut ditambahkan.

Menghapus semua elemen dari ArrayList.

Menghasilkan true jika object yang dispesifikasi berada di dalam ArrayList; sebaliknya, menghasilkan false.

Menghasilkan indeks dari kemunculan pertama object yang dispesifikasi di dalam ArrayList.

Menyisipkan sebuah object pada indeks yang dispesifikasi.

Menghapus kemunculan pertama dari object yang dispesifikasi.

Menghapus sebuah object pada indeks yang dispesifikasi.

Menghapus sejumlah elemen tertentu berawal dari indeks yang dispesifikasi di dalam ArrayList.

Mengurutkan ArrayList.

Menetapkan Capacity dari ArrayList menjadi jumlah elemen yang sekarang dimuat di dalam ArrayList.

Gambar 14.10 Beberapa metode ArrayList


ArrayList mereferensi object. Semua kelas diderivasi dari kelas object, jadi ArrayList dapat memuat objek-objek sembarang tipe. Gambar 14.10 mencantumkan beberapa metode penting dari kelas ArrayList. Kode 14.15 mendemonstrasikan kelas ArrayList dan beberapa metodenya. Pengguna dapat mengentrikan sebuah string ke dalam TextBox dan kemudian menekan sebuah tombol yang merepresentasikan suatu metode ArrayList untuk melihat fungsionalitas metode. TextBox menampilkan pesan yang mengindikasikan hasil tiap operasi.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// Kode 14.15: UjiArrayList.cs
// Menggunakan kelas ArrayList

using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace UjiArrayList
{
    public partial class UjiArrayList : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Button tombolTambahkan;
        private System.Windows.Forms.TextBox kotakTeksMasukan;
        private System.Windows.Forms.Label labelMasukan;
        private System.Windows.Forms.Button tombolHapus;
        private System.Windows.Forms.Button tombolPertama;
        private System.Windows.Forms.Button tombolAkhir;
        private System.Windows.Forms.Button tombolApaKosong;
        private System.Windows.Forms.Button tombolMemuat;
        private System.Windows.Forms.Button tombolLokasi;
        private System.Windows.Forms.Button tombolPotong;
        private System.Windows.Forms.Button tombolStatistik;
        private System.Windows.Forms.Button tombolTampil;

        // variabel designer yang diperlukan.
        private System.ComponentModel.Container komponen = null;
        private System.Windows.Forms.TextBox kotakTeksKonsol;

        // ArrayList untuk memanipulasi string
        private ArrayList arrayList = new ArrayList(1);

        public UjiArrayList()
        {
            InitializeComponent();
        }

        // kode yang dibangkitkan oleh Visual Studio.NET

        // entri poin untuk aplikasi
        [STAThread]
        static void Main()
        {
            Application.Run( new ArrayListTest() );
        }
       
        // menambah item di akhir arrayList
        private void tombolTambahkan_Click(
            object sender, EventArgs e)
        {
            arrayList.Add(kotakTeksMasukan.Text);
            kotakTeksKonsol.Text =
                "Ditambahkan ke akhir: " + kotakTeksMasukan.Text;
            kotakTeksMasukan.Clear();
        }

        // menghapus item yang diinginkan dari arrayList
        private void tombolHapus_Click(
            object sender, EventArgs e)
        {
            arrayList.Remove(kotakTeksMasukan.Text);
            kotakTeksKonsol.Text = "Dihapus: " + kotakTeksMasukan.Text;
            kotakTeksMasukan.Clear();
        }

        // menampilkan elemen pertama
        private void tombolPertama_Click(
            object sender, EventArgs e)
        {
            // mendapatkan elemen pertama
            try
            {
                kotakTeksKonsol.Text =
                    "Elemen pertama: " + arrayList[0];
            }

            // menampilkan eksepsi jika tidak ada elemen di dalam arrrayList
            catch (ArgumentOutOfRangeException diLuarRentang)
            {
                kotakTeksKonsol.Text = diLuarRentang.ToString();
            }
        }

        // menampilkan elemen akhir
        private void tombolAkhir_Click(
            object sender, EventArgs e)
        {
            // mendapatkan elemen akhir
            try
            {
                kotakTeksKonsol.Text = "Elemen akhir: " +
                arrayList[ arrayList.Count - 1 ];
            }

            // menampilkan eksepsi jika tidak ada elemen di dalam arrrayList
            catch ( ArgumentOutOfRangeException diLuarRentang )
            {
                kotakTeksKonsol.Text = diLuarRentang.ToString();
            }
        }

        // menentukan apakah arrayList kosong
        private void tombolApaKosong_Click(
            object sender, EventArgs e)
        {
            kotakTeksKonsol.Text = (arrayList.Count == 0 ?
            "arrayList kosong" : "arrayList tidak kosong" );
        }

        // menentukan apakah arrayList memuat objek yang dispesifikasi
        private void tombolMemuat_Click(
            object sender, EventArgs e)
        {
            if (arrayList.Contains(kotakTeksMasukan.Text))
                kotakTeksKonsol.Text = "arrayList memuat " +
                    kotakTeksMasukan.Text;
            else
                kotakTeksKonsol.Text = kotakTeksMasukan.Text +
                    " tidak ditemukan";
        }

        // menentukan lokasi dari objek yang dispesifikasi
        private void tombolLokasi_Click(
            object sender, EventArgs e)
        {
            kotakTeksKonsol.Text = "Elemen berada pada lokasi " +
                arrayList.IndexOf(kotakTeksMasukan.Text);
        }

        // memotong arrayList menjadi ukuran sekarang
        private void tombolPotong_Click(
            object sender, EventArgs e)
        {
            arrayList.TrimToSize();
            kotakTeksKonsol.Text = "Vektor dipotong menjadi ukuran sekarang";
        }

        // menampilkan ukuran dan kapasitas sekarang dari arrayList
        private void tombolStatistik_Click(
            object sender, EventArgs e)
        {
            kotakTeksKonsol.Text = "Ukuran = " + arrayList.Count +
                "; kapasitas = " + arrayList.Capacity;
        }

        // menampilkan isi dari arrayList
        private void tombolTampil_Click(
            object sender, EventArgs e)
        {
            IEnumerator enumerator = arrayList.GetEnumerator();
            StringBuilder buffer = new StringBuilder();

            while ( enumerator.MoveNext() )
                buffer.Append( enumerator.Current + " " );

            kotakTeksKonsol.Text = buffer.ToString();
        }
    }
}

  

Gambar 14.11  Keluaran program pada kode 14.15







No comments:

Post a Comment