Pelajaran 16 - Rekursi
Rekursi didefinisikan sebagai fungsi yang menamakan dirinya. Hal ini dalam beberapa hal mirip dengan loop karena mengulangi kode yang sama, tetapi membutuhkan lewat di variabel perulangan dan menjadi lebih berhati-hati. Banyak bahasa pemrograman memungkinkan karena dapat menyederhanakan beberapa tugas, dan sering lebih elegan dari lingkaran.
Sebuah contoh sederhana dari rekursi akan menjadi:
batal recurse ()
{
recurse (); / / Fungsi menyebut dirinya
}
int main ()
{
recurse (); / / Set off rekursi
}
Program ini tidak akan berlanjut selamanya, namun. Komputer terus pemanggilan fungsi pada stack dan sekali terlalu banyak yang dipanggil tanpa berakhir, program akan crash. Mengapa tidak menulis sebuah program untuk melihat berapa kali fungsi ini dipanggil sebelum program berakhir?
Kode: [Pilih]
# Include
menggunakan namespace std;
recurse void (int count) / / panggil Masing-masing mendapat hitungan sendiri
{
cout << count << "\ n";
/ / Hal ini tidak perlu untuk kenaikan jumlah sinceeach fungsi ini
/ / Variabel terpisah (sehingga setiap hitungan akan diinisialisasi satu lebih besar)
recurse (count + 1);
}
int main ()
{
recurse (1); pemanggilan fungsi / / Pertama, sehingga mulai pada satu
}
Ini program yang sederhana akan menunjukkan berapa kali fungsi recurse telah dipanggil oleh menginisialisasi variabel jumlah setiap panggilan fungsi individu yang lebih besar dari itu sebelumnya dengan lewat di count + 1. Perlu diingat, itu bukan fungsi restart sendiri, itu adalah ratusan fungsi yang masing-masing belum selesai dengan yang terakhir memanggil fungsi recurse baru.
Hal ini dapat dianggap seperti boneka Rusia yang selalu memiliki di dalam boneka yang lebih kecil. Setiap boneka boneka panggilan lain, dan Anda dapat memikirkan ukuran menjadi variabel counter yang sedang decremented oleh satu.
Pikirkan sebuah boneka yang benar-benar kecil, ukuran beberapa atom. Anda tidak bisa lebih kecil dari itu, jadi ada boneka lagi. Biasanya, fungsi rekursif akan memiliki variabel yang melakukan tindakan serupa, yang mengontrol ketika fungsi akhirnya akan keluar. Kondisi di mana functin tidak akan menyebut dirinya disebut kasus dasar dari fungsi. Pada dasarnya, itu adalah jika-pernyataan yang memeriksa beberapa variabel untuk kondisi (seperti angka yang kurang dari nol, atau lebih besar dari beberapa nomor lain) dan jika kondisi itu benar, itu tidak akan memungkinkan fungsi untuk menyebut dirinya lagi. (Atau, bisa memeriksa apakah kondisi tertentu adalah benar dan hanya kemudian memungkinkan fungsi untuk menyebut dirinya).
Contoh cepat:
kekosongan boneka (int size)
{
if (size == 0) / / boneka ada bisa lebih kecil dari 1 atom (10 ^ 0 == 1) sehingga tidak menyebut dirinya
return; / / Kembali tidak harus kembali sesuatu, dapat digunakan
/ / Untuk keluar fungsi
boneka (size - 1); / / decrements variabel ukuran sehingga boneka berikutnya akan lebih kecil.
}
int main ()
{
boneka (10), / / Dimulai dengan boneka besar (skala logaritmik nya)
}
Program ini berakhir ketika ukuran sama dengan satu. Ini adalah kasus dasar yang baik, tetapi jika tidak diatur dengan benar, adalah mungkin untuk memiliki kasus dasar yang selalu benar (atau selalu salah).
Setelah fungsi telah menyebut dirinya, maka akan siap untuk pergi ke baris berikutnya setelah panggilan. Hal ini masih bisa melakukan operasi. Salah satu fungsi yang Anda bisa menulis bisa mencetak angka 123456789987654321. Bagaimana Anda bisa menggunakan rekursi untuk menulis fungsi untuk melakukan hal ini? Cukup memilikinya terus incrementing variabel berlalu dalam, dan kemudian output variabel ... dua kali, sekali sebelum recurses fungsi, dan sekali setelah ...
batal printnum (int mulai)
{
cout << mulai;
if (mulai> 9) / / Kasus dasar adalah ketika begin lebih besar dari 9
printnum (mulai + 1); / / untuk itu tidak akan recurse setelah pernyataan jika-
cout << mulai; / / Output kedua dimulai, setelah program memiliki
/ / Pergi melalui dan output
}
Fungsi ini bekerja karena akan pergi melalui dan mencetak angka mulai 9, dan kemudian karena setiap fungsi printnum berakhir akan terus mencetak nilai dimulai di setiap fungsi dari 9 untuk memulai.
Ini hanyalah awal dari kegunaan rekursi. Heres tantangan kecil, gunakan rekursi untuk menulis sebuah program yang mengembalikan faktorial dari sejumlah besar dari 0. (Faktorial adalah nomor * nomor 1 * Nomor-2 ... * 1).
Petunjuk: Secara rekursif menemukan faktorial dari angka-angka yang lebih kecil pertama, yakni, dibutuhkan angka, menemukan faktorial dari jumlah sebelumnya, dan mengalikan jumlah waktu yang faktorial.
Pelajaran 17 - Func Var Arg
Mungkin Anda ingin memiliki fungsi yang akan menerima sejumlah nilai dan kemudian kembali rata-rata. Anda tidak tahu berapa banyak argumen akan dilewatkan ke fungsi. Salah satu cara Anda bisa membuat fungsi akan menerima pointer ke array. Cara lain adalah dengan menulis fungsi yang dapat mengambil sejumlah argumen. Jadi Anda bisa menulis avg (4, 12,2, 23,3, 33,3, 12,1), atau Anda bisa menulis avg (2, 2,3, 34,4); Beberapa fungsi perpustakaan dapat menerima daftar variabel argumen (seperti printf terhormat).
Untuk menggunakan fungsi dengan jumlah variabel argumen, atau lebih tepatnya, fungsi tanpa nomor set argumen, Anda akan menggunakan file header cstdarg. Ada empat bagian yang dibutuhkan: va_list, yang menyimpan daftar argumen, va_start, yang menginisialisasi daftar, va_arg, yang mengembalikan argumen berikutnya dalam daftar, dan va_end, yang membersihkan daftar argumen variabel. Setiap kali fungsi dinyatakan memiliki jumlah tak tentu argumen, di tempat argumen terakhir Anda harus menempatkan elipsis (yang terlihat seperti '...'), sehingga, int a_function (int x, ...); akan memberitahu compiler fungsi harus menerima argumen namun banyak bahwa programmer menggunakan, asalkan sama dengan setidaknya satu, yang menjadi, pertama x.
va_list adalah seperti variabel lainnya. Misalnya,
va_list a_list;
va_start adalah makro yang menerima dua argumen, sebuah va_list dan nama variabel yang secara langsung mendahului elipsis (...). Jadi, dalam a_function fungsi, untuk menginisialisasi a_list dengan va_start, Anda akan menulis va_start (a_list, x);
va_arg mengambil va_list dan jenis variabel, dan mengembalikan argumen berikutnya dalam daftar dalam bentuk apa pun jenis variabel itu mengatakan. Kemudian bergerak ke bawah daftar untuk argumen berikutnya. Misalnya, va_arg (a_list, ganda) akan mengembalikan argumen berikutnya, dengan asumsi itu ada, dalam bentuk ganda. Lain kali itu disebut, itu akan kembali argumen mengikuti jumlah yang dikembalikan terakhir, jika ada.
Untuk menunjukkan bagaimana setiap bagian bekerja, mengambil fungsi contoh:
# Include <cstdarg>
# Include
menggunakan namespace std;
ganda rata (int num, ...)
{
argumen va_list; / / Tempat untuk menyimpan daftar argumen
ganda sum = 0;
va_start (argumen, num); / / Inisialisasi argumen untuk menyimpan semua nilai setelah num
for (int x = 0; x <num, x + +) / / Loop sampai semua nomor yang ditambahkan
jumlah + = va_arg (argumen, ganda); / / Menambahkan nilai berikutnya dalam daftar argumen untuk sum.
va_end (argumen); / / Membersihkan daftar
return sum / num; / / Returns beberapa nomor (typecast mencegah pemotongan)
}
int main ()
{
cout << rata (3, 12,2, 22,3, 4,5) << endl;
cout << rata (5, 3,3, 2,2, 1,1, 5,5, 3,3) << endl;
}
Hal ini tidak selalu merupakan ide yang baik untuk menggunakan daftar argumen variabel setiap saat, karena potensi ada untuk asumsi nilai adalah dari satu jenis, sementara itu sebenarnya lain, seperti pointer nol yang dianggap integer. Akibatnya, daftar argumen variabel harus digunakan hemat.
Pelajaran 18 - Binary Pohon Part 1
Pohon biner adalah struktur data dasar yang digunakan dalam ilmu komputer. Pohon biner adalah struktur data yang berguna untuk data yang diurutkan dengan cepat menyimpan dan mengambil data yang disimpan dengan cepat. Sebuah pohon biner terdiri dari node induk, atau daun, yang masing-masing menyimpan data dan juga link ke hingga dua node anak lainnya (daun) yang dapat divisualisasikan spasial seperti di bawah node pertama dengan satu ditempatkan ke kiri dan dengan satu ditempatkan ke kanan. Ini adalah hubungan antara daun terkait dan daun menghubungkan, juga dikenal sebagai node induk, yang membuat pohon biner seperti struktur data yang efisien. Ini adalah daun di sebelah kiri yang memiliki nilai kunci yang lebih rendah (yaitu, nilai yang digunakan untuk mencari daun di pohon), dan itu adalah daun di sebelah kanan yang memiliki nilai kunci yang sama atau lebih besar. Akibatnya, daun di terjauh kiri pohon memiliki nilai terendah, sedangkan daun di sebelah kanan pohon memiliki nilai terbesar. Lebih penting lagi, seperti setiap daun menghubungkan ke dua daun lain, itu adalah awal dari sebuah pohon, baru yang lebih kecil, biner. Karena sifat ini, adalah mungkin untuk dengan mudah mengakses dan memasukkan data dalam sebuah pohon biner dengan menggunakan fungsi pencarian dan masukkan rekursif meminta daun berturut-turut.Representasi grafis khas pohon biner pada dasarnya adalah bahwa dari sebuah pohon terbalik. Ini dimulai dengan simpul akar, yang berisi nilai kunci asli. Simpul akar memiliki dua node anak, setiap node anak mungkin memiliki node anak sendiri. Idealnya, pohon akan terstruktur sehingga pohon seimbang sempurna, dengan setiap node memiliki jumlah yang sama node anak ke kiri dan ke kanan. Sebuah pohon seimbang sempurna memungkinkan untuk penyisipan tercepat rata-rata dari data atau pengambilan data. Skenario kasus terburuk adalah pohon di mana setiap node hanya memiliki satu simpul anak, sehingga menjadi seolah-olah itu sebuah linked list dalam hal kecepatan. Representasi khas dari pohon biner terlihat seperti berikut:
10
/ \
6 14
/ \ / \
5 8 11 18
Simpul menyimpan 10, diwakili di sini hanya sebagai 10, adalah simpul akar, menghubungkan ke node anak kiri dan kanan, dengan simpul kiri menyimpan nilai yang lebih rendah dari node induk, dan simpul di sebelah kanan menyimpan nilai yang lebih besar dari node induk. Perhatikan bahwa jika seseorang dihapus simpul akar dan node anak kanan, bahwa node menyimpan nilai 6 akan menjadi setara baru, lebih kecil, pohon biner.Struktur pohon biner membuat penyisipan dan fungsi pencarian sederhana untuk mengimplementasikan menggunakan rekursi. Bahkan, dua penyisipan dan pencarian, juga keduanya sangat mirip. Untuk menyisipkan data ke dalam sebuah pohon biner melibatkan fungsi mencari sebuah simpul yang tidak terpakai dalam posisi yang tepat di pohon di mana untuk memasukkan nilai kunci. Fungsi insert umumnya fungsi rekursif yang terus bergerak turun tingkat pohon biner sampai ada daun yang tidak terpakai dalam posisi yang mengikuti aturan node menempatkan. Aturan-aturan adalah bahwa nilai yang lebih rendah harus di sebelah kiri dari node, dan nilai yang lebih besar atau sama harus ke kanan. Mengikuti aturan, fungsi insert harus memeriksa setiap node untuk melihat apakah itu kosong, jika demikian, itu akan memasukkan data yang akan disimpan bersama dengan nilai kunci (dalam sebagian besar implementasi, node kosong hanya akan menjadi pointer NULL dari node induk, sehingga fungsi juga harus membuat node). Jika node sudah diisi, fungsi insert harus memeriksa untuk melihat apakah nilai kunci untuk dimasukkan kurang dari nilai kunci dari node saat ini, dan jika demikian, fungsi insert harus rekursif disebut pada node anak kiri, atau jika nilai kunci untuk dimasukkan lebih besar dari atau sama dengan nilai kunci dari node saat ini fungsi insert harus rekursif disebut pada node anak kanan. Fungsi pencarian bekerja sepanjang cara yang sama. Ini harus memeriksa untuk melihat apakah nilai kunci dari node saat ini adalah nilai yang akan dicari. Jika tidak, maka harus memeriksa untuk melihat apakah nilai yang akan dicari adalah kurang dari nilai node, dalam hal ini harus secara rekursif disebut pada node anak kiri, atau jika lebih besar dari nilai node, itu harus disebut rekursif pada node anak kanan. Tentu saja, hal ini juga diperlukan untuk memeriksa untuk memastikan bahwa simpul anak kiri atau kanan benar-benar ada sebelum memanggil fungsi pada node.Karena pohon biner memiliki log (basis 2) n lapisan, waktu pencarian rata-rata untuk sebuah pohon biner adalah log (basis 2) n. Untuk mengisi sebuah pohon biner keseluruhan, diurutkan, dibutuhkan kira-kira log (basis 2) n * n. Mari kita lihat kode yang diperlukan untuk implementasi sederhana dari sebuah pohon biner. Pertama, perlu untuk memiliki struct, atau kelas, didefinisikan sebagai node.
struct simpul
{
int key_value;
simpul * kiri;
simpul * benar;
};
Struct memiliki kemampuan untuk menyimpan key_value dan berisi node anak kedua yang menentukan node sebagai bagian dari pohon. Bahkan, node itu sendiri sangat mirip dengan node dalam linked list. Sebuah pengetahuan dasar kode untuk linked list akan sangat membantu dalam memahami teknik pohon biner. Pada dasarnya, pointer diperlukan untuk memungkinkan penciptaan sewenang-wenang node baru dalam pohon.Hal ini paling logis untuk membuat kelas pohon biner untuk merangkum kerja pohon ke daerah tunggal, dan juga membuatnya dapat digunakan kembali. Kelas akan berisi fungsi untuk memasukkan data ke dalam pohon dan untuk mencari data. Karena penggunaan pointer, maka akan diperlukan untuk menyertakan fungsi untuk menghapus pohon dalam rangka untuk menghemat memori setelah program selesai.
Kelas btree
{
simpul akar *;
btree ();
~ Btree ();
batal destroy_tree (node * daun);
kekosongan insert (int key, simpul daun *);
simpul * cari (int key, simpul daun *);
publik:
kekosongan insert (int key);
simpul * cari (int key);
batal destroy_tree ();
};
Insert dan fungsi pencarian yang adalah anggota masyarakat dari kelas dirancang untuk memungkinkan pengguna kelas menggunakan kelas tanpa berurusan dengan desain yang mendasarinya. Insert dan fungsi pencarian yang akan dipanggil secara rekursif adalah orang-orang yang berisi dua parameter, yang memungkinkan mereka untuk melakukan perjalanan ke pohon. Fungsi destroy_tree tanpa argumen adalah sebuah front untuk fungsi destroy_tree yang rekursif akan menghancurkan pohon, node demi node, dari bawah ke atas.Kode untuk kelas akan terlihat mirip dengan berikut ini:
btree :: btree ()
{
root = NULL;
}
Hal ini diperlukan untuk menginisialisasi akar ke NULL untuk fungsi kemudian untuk dapat mengenali bahwa itu tidak ada.
btree :: ~ btree ()
{
destroy_tree ();
}
Fungsi destroy_tree akan berangkat destroy_tree fungsi rekursif ditunjukkan di bawah ini yang benar-benar akan menghapus semua node dari pohon.
batal destroy_tree (node * daun)
{
if (leaf! = NULL)
{
destroy_tree (daun-> kiri);
destroy_tree (daun-> kanan);
menghapus daun;
}
}
The destroy_tree Fungsi pergi ke bagian bawah setiap bagian dari pohon, yaitu, pencarian sementara ada simpul non-null, menghapus bahwa daun, dan kemudian bekerja dengan cara kembali. Menghapus fungsi node paling kiri, maka simpul anak kanan dari node induk node paling kiri, maka akan menghapus node induk, kemudian bekerja jalan kembali untuk menghapus node anak lain dari orang tua dari node itu hanya dihapus, dan terus penghapusan ini bekerja dengan cara sampai ke node dari pohon yang di atasnya delete_tree awalnya disebut. Dalam contoh di atas pohon, urutan penghapusan node akan 5 8 6 11 18 14 10. Perhatikan bahwa perlu untuk menghapus semua node anak untuk menghindari pemborosan memori.
batal btree :: insert (int key, simpul daun *)
{
jika (key <daun-> key_value)
{
if (daun-> kiri = NULL!)
masukkan (kunci, daun-> kiri);
lain
{
daun-> kiri = node baru;
daun-> kiri-> key_value = kunci;
daun-> kiri-> kiri = NULL; / / Mengatur anak kiri dari simpul anak ke null
daun-> kiri-> kanan = NULL; / / Mengatur anak kanan dari simpul anak ke null
}
}
lain jika (key> = daun-> key_value)
{
if (daun-> kanan = NULL!)
masukkan (kunci, daun-> kanan);
lain
{
daun-> kanan = node baru;
daun-> kanan> key_value = kunci;
daun-> kanan> kiri = NULL; / / Mengatur anak kiri dari simpul anak ke null
daun-> kanan> kanan = NULL; / / Mengatur anak kanan dari simpul anak ke null
}
}
}
Kasus dimana akar masih NULL akan diurus oleh fungsi insert yang nonrecursive dan tersedia untuk non-anggota kelas. Pencarian menyisipkan fungsi, bergerak turun pohon node anak, mengikuti peraturan yang telah ditetapkan, berangkat nilai yang lebih rendah untuk dimasukkan dan tepat untuk nilai yang lebih besar, sampai menemukan sebuah simpul kosong yang menciptakan menggunakan 'baru' kata kunci dan menginisialisasi dengan nilai kunci ketika mengatur anak node baru pointer simpul ke NULL. Setelah membuat node baru, fungsi insert tidak akan lagi menyebut dirinya.
simpul * btree :: cari (int key, simpul daun *)
{
if (leaf! = NULL)
{
jika (key == daun-> key_value)
kembali daun;
jika (key <leaf-> key_value)
kembali pencarian (key, daun-> kiri);
lain
kembali pencarian (key, daun-> kanan);
}
lain kembali NULL;
}
Fungsi pencarian yang ditampilkan di atas rekursif bergerak ke bawah pohon sampai baik mencapai node dengan nilai kunci sama dengan nilai yang fungsinya adalah mencari atau sampai fungsi mencapai node diinisiasi, yang berarti bahwa nilai sedang dicari tidak disimpan dalam pohon biner. Ia mengembalikan pointer ke node ke instance sebelumnya fungsi yang menyebutnya, menyerahkan pointer kembali ke fungsi pencarian diakses di luar kelas.
batal btree :: insert (int key)
{
if (root! = NULL)
insert (key, root);
lain
{
akar simpul = baru;
akar-> key_value = kunci;
akar-> kiri = NULL;
akar-> kanan = NULL;
}
}
Versi publik fungsi insert mengurus kasus di mana akar belum diinisialisasi dengan mengalokasikan memori untuk itu dan menetapkan kedua node anak ke NULL dan pengaturan key_value untuk nilai yang akan dimasukkan. Jika simpul akar sudah ada, insert disebut dengan simpul akar sebagai simpul awal fungsi, dan fungsi insert rekursif mengambil alih.
simpul * btree :: cari (int key)
{
kembali pencarian (key, root);
}
Versi publik fungsi pencarian digunakan untuk menonaktifkan rekursi pencarian di simpul akar, menjaga dari yang diperlukan bagi pengguna untuk memiliki akses ke simpul akar.
batal btree :: destroy_tree ()
{
destroy_tree (root);
}
Versi publik fungsi pohon menghancurkan hanya digunakan untuk menginisialisasi fungsi destroy_tree rekursif yang kemudian menghapus semua node dari pohon.
Pelajaran 19 - Inheratence
Kemampuan untuk menggunakan pemrograman berorientasi obyek adalah fitur penting dari C + +. Pelajaran 12 memperkenalkan gagasan kelas, jika Anda belum membaca dan tidak tahu rincian dasar kelas, Anda harus membacanya sebelum melanjutkan tutorial ini. Tutorial ini adalah n Warisan adalah fitur penting dari kelas, bahkan, itu merupakan bagian integral dari gagasan pemrograman berorientasi obyek. Warisan memungkinkan Anda untuk membuat hirarki kelas, dengan berbagai kelas sifat yang lebih spesifik mewarisi aspek umum kelas yang lebih umum. Dengan cara ini, adalah mungkin untuk struktur program dimulai dengan ide-ide abstrak yang kemudian diimplementasikan oleh kelas tertentu. Sebagai contoh, Anda mungkin memiliki Animal kelas dari yang kelas anjing dan kucing melekat sifat-sifat yang umum untuk semua hewan, pada saat yang sama, masing-masing kelas akan memiliki atribut khusus untuk anjing atau kucing hewan.
Warisan menawarkan banyak fitur yang berguna untuk programmer. Kemampuan, misalnya, dari variabel dari kelas yang lebih umum berfungsi sebagai salah satu kelas yang lebih spesifik yang mewarisi dari itu, disebut polimorfisme, berguna. Untuk saat ini, kami akan berkonsentrasi pada sintaks dasar warisan. Polimorfisme akan dibahas dalam tutorial sendiri.
Setiap kelas dapat mewarisi dari kelas lain, tetapi belum tentu praktek yang baik untuk menggunakan warisan (menaruhnya di bank daripada pergi berlibur). Warisan harus digunakan bila Anda memiliki kelas yang lebih umum obyek yang menggambarkan satu set objek. Fitur dari setiap elemen yang mengatur (dari setiap objek yang juga dari jenis yang lebih umum) harus tercermin dalam kelas yang lebih umum. Kelas ini disebut kelas dasar. kelas dasar biasanya mengandung fungsi bahwa semua kelas mewarisi dari itu, yang dikenal sebagai kelas turunan, akan membutuhkan. kelas dasar juga harus memiliki semua variabel bahwa setiap kelas turunan lain akan berisi.
Mari kita lihat sebuah contoh bagaimana struktur program dengan beberapa kelas. Ambil sebuah program yang digunakan untuk mensimulasikan interaksi antara jenis organisme, pohon, burung, beruang, dan makhluk lainnya coinhabiting hutan. Ada kemungkinan akan beberapa kelas dasar yang kemudian akan memiliki kelas turunan spesifik untuk jenis hewan individual. Bahkan, jika Anda tahu apa-apa tentang biologi, Anda mungkin ingin untuk struktur kelas Anda untuk mengambil keuntungan dari klasifikasi biologis dari Raya ke spesies, meskipun mungkin akan terlalu rumit. Sebaliknya, Anda mungkin memiliki kelas dasar untuk hewan dan tumbuhan. Jika Anda ingin menggunakan kelas dasar yang lebih (kelas dapat berasal baik dari satu kelas dan dasar yang lain), Anda mungkin memiliki kelas untuk terbang hewan dan hewan darat, dan mungkin pohon dan semak-semak. Kemudian Anda ingin kelas untuk tipe tertentu dari hewan: merpati dan burung bangkai, beruang dan singa, dan tipe tertentu dari tanaman: oak dan pinus, rumput dan bunga. Ini tidak mungkin untuk hidup bersama di wilayah yang sama, tetapi ide dasarnya ada: kelas yang lebih spesifik harus mewarisi dari kelas yang kurang spesifik.
Kelas, tentu saja, data saham. Sebuah kelas turunan memiliki akses ke sebagian besar fungsi dan variabel dari kelas dasar. Namun demikian, cara-cara untuk menjaga derivedren dari mengakses beberapa atribut dari kelas dasar. Masyarakat kata kunci, dilindungi, dan swasta yang digunakan untuk mengontrol akses ke informasi dalam kelas. Penting untuk diingat bahwa informasi kontrol publik, dilindungi, dan swasta baik untuk kasus tertentu dari kelas dan untuk kelas sebagai tipe data umum. Variabel dan fungsi yang ditetapkan publik keduanya diwariskan oleh kelas turunan dan dapat diakses oleh fungsi luar dan kode ketika mereka adalah elemen dari contoh spesifik dari sebuah kelas. Variabel yang dilindungi tidak dapat diakses oleh fungsi dan kode luar kelas, tetapi kelas turunan mewarisi fungsi-fungsi dan variabel sebagai bagian dari kelas mereka sendiri. Variabel swasta tidak dapat diakses di luar kelas ketika kelas tertentu atau tersedia untuk kelas turunan. Variabel pribadi berguna bila Anda memiliki variabel yang masuk akal dalam konteks ide besar.
Pelajaran 20 - Sintaks Inheratence
Sebelum memulai pelajaran ini, Anda harus memiliki pemahaman tentang ide warisan. Jika Anda tidak, silahkan baca pelajaran 19. Pelajaran ini akan terdiri dari gambaran dari sintaks warisan, penggunaan kata kunci publik, swasta, dan dilindungi, dan kemudian contoh program berikut untuk menunjukkan masing-masing. Sintaks untuk menunjukkan satu kelas sebagai mewarisi dari yang lain sederhana. Ini terlihat seperti berikut: Bear class: Hewan publik, di tempat hanya kelas kata kunci dan kemudian nama kelas. The ": base_class_name publik" adalah sintaks penting dari warisan, fungsi dari sintaks ini adalah bahwa kelas akan berisi semua variabel publik dan dilindungi dari kelas dasar. Jangan bingung gagasan akses kelas turunan harus anggota data dari kelas dasar dan contoh-contoh spesifik dari data kelas turunan memiliki. Data anggota - variabel dan fungsi - yang dimiliki oleh kelas turunan yang khusus untuk jenis kelas, bukan untuk setiap objek individu tipe tersebut. Jadi, dua benda yang berbeda Beruang, sementara memiliki variabel anggota dan fungsi yang sama, mungkin memiliki informasi yang berbeda disimpan dalam variabel mereka, lebih jauh lagi, jika ada hewan kelas dengan obyek, katakanlah BigAnimal objek, jenis itu, dan bukan dari yang lebih jenis tertentu diwariskan dari kelas itu, dua beruang tidak akan memiliki akses ke data dalam BigAnimal. Mereka hanya akan memiliki variabel dan fungsi dengan nama yang sama dan dari jenis yang sama. Contoh cepat warisan:
kelas Hewan
{
publik:
kaki int;
lengan int;
int usia;
Hewan ();
~ Animal ();
membatalkan makan ();
membatalkan tidur ();
membatalkan minuman ();
};
/ / The Animal kelas berisi informasi dan fungsi
/ / Yang berhubungan dengan semua hewan (setidaknya, semua hewan pelajaran ini menggunakan)
Kelas Cat: Animal publik
{
publik:
int fur_color;
membatalkan Purr ();
kekosongan ikan ();
membatalkan Mark_territory ();
};
/ / Bagi Anda akrab dengan kucing
/ / Makan dari operasi diatas adalah unik
/ / Ke teman Anda ramah berbulu
/ / (Atau musuh, sebagai kasus mungkin)
Sebuah diskusi tentang kata kunci publik, swasta, dan dilindungi berguna ketika membahas warisan. Tiga kata kunci yang digunakan untuk mengontrol akses ke fungsi dan variabel yang disimpan dalam kelas.publik:Tingkat yang paling terbuka menyembunyikan data, segala sesuatu yang umum tersedia untuk semua kelas turunan dari kelas dasar, dan variabel publik dan data untuk masing-masing obyek baik dasar dan kelas turunan dapat diakses oleh kode di luar kelas. Fungsi ditandai masyarakat umumnya yang kelas digunakan untuk memberikan informasi kepada dan mengambil informasi dari dunia luar, mereka biasanya antarmuka dengan kelas. Sisa kelas harus disembunyikan dari pengguna (ini sifat tersembunyi dan sifat yang sangat terfokus kelas yang dikenal secara kolektif sebagai enkapsulasi). Sintaks untuk umum adalah:
publik:
Berikut Semuanya publik sampai akhir kelas atau kata kunci lain menyembunyikan data yang digunakan.dilindungi:Variabel dan fungsi ditandai dilindungi diwariskan oleh kelas turunan, namun, kelas-kelas yang berasal menyembunyikan data dari kode luar dari setiap instance dari objek. Perlu diingat, bahkan jika Anda memiliki objek lain dari jenis yang sama sebagai objek pertama Anda, objek kedua tidak dapat mengakses sebuah variabel lindung di objek pertama. Sebaliknya, obyek kedua akan memiliki variabel sendiri dengan nama yang sama - namun belum tentu data yang sama. Dilindungi adalah tingkat yang berguna perlindungan bagi aspek penting untuk kelas yang harus dilalui tanpa memungkinkan untuk diakses. Sintaksnya adalah sama dengan masyarakat. khusus,
dilindungi:
swasta:Swasta adalah tingkat tertinggi dari data-bersembunyi. Tidak hanya fungsi dan variabel ditandai pribadi tidak dapat diakses oleh kode di luar objek tertentu di mana data yang muncul, namun variabel pribadi dan fungsi tidak diwariskan. Tingkat perlindungan data yang diberikan oleh dilindungi umumnya lebih fleksibel daripada tingkat pribadi. Tentu saja, ada sukacita tertentu dalam melindungi data Anda dengan kata kunci pribadi. Sintaks tetap sama.
swasta:
Ok guys ... Yah aku berharap seseorang menemukan tutorial ini bermanfaat.
Rekursi didefinisikan sebagai fungsi yang menamakan dirinya. Hal ini dalam beberapa hal mirip dengan loop karena mengulangi kode yang sama, tetapi membutuhkan lewat di variabel perulangan dan menjadi lebih berhati-hati. Banyak bahasa pemrograman memungkinkan karena dapat menyederhanakan beberapa tugas, dan sering lebih elegan dari lingkaran.
Sebuah contoh sederhana dari rekursi akan menjadi:
batal recurse ()
{
recurse (); / / Fungsi menyebut dirinya
}
int main ()
{
recurse (); / / Set off rekursi
}
Program ini tidak akan berlanjut selamanya, namun. Komputer terus pemanggilan fungsi pada stack dan sekali terlalu banyak yang dipanggil tanpa berakhir, program akan crash. Mengapa tidak menulis sebuah program untuk melihat berapa kali fungsi ini dipanggil sebelum program berakhir?
Kode: [Pilih]
# Include
menggunakan namespace std;
recurse void (int count) / / panggil Masing-masing mendapat hitungan sendiri
{
cout << count << "\ n";
/ / Hal ini tidak perlu untuk kenaikan jumlah sinceeach fungsi ini
/ / Variabel terpisah (sehingga setiap hitungan akan diinisialisasi satu lebih besar)
recurse (count + 1);
}
int main ()
{
recurse (1); pemanggilan fungsi / / Pertama, sehingga mulai pada satu
}
Ini program yang sederhana akan menunjukkan berapa kali fungsi recurse telah dipanggil oleh menginisialisasi variabel jumlah setiap panggilan fungsi individu yang lebih besar dari itu sebelumnya dengan lewat di count + 1. Perlu diingat, itu bukan fungsi restart sendiri, itu adalah ratusan fungsi yang masing-masing belum selesai dengan yang terakhir memanggil fungsi recurse baru.
Hal ini dapat dianggap seperti boneka Rusia yang selalu memiliki di dalam boneka yang lebih kecil. Setiap boneka boneka panggilan lain, dan Anda dapat memikirkan ukuran menjadi variabel counter yang sedang decremented oleh satu.
Pikirkan sebuah boneka yang benar-benar kecil, ukuran beberapa atom. Anda tidak bisa lebih kecil dari itu, jadi ada boneka lagi. Biasanya, fungsi rekursif akan memiliki variabel yang melakukan tindakan serupa, yang mengontrol ketika fungsi akhirnya akan keluar. Kondisi di mana functin tidak akan menyebut dirinya disebut kasus dasar dari fungsi. Pada dasarnya, itu adalah jika-pernyataan yang memeriksa beberapa variabel untuk kondisi (seperti angka yang kurang dari nol, atau lebih besar dari beberapa nomor lain) dan jika kondisi itu benar, itu tidak akan memungkinkan fungsi untuk menyebut dirinya lagi. (Atau, bisa memeriksa apakah kondisi tertentu adalah benar dan hanya kemudian memungkinkan fungsi untuk menyebut dirinya).
Contoh cepat:
kekosongan boneka (int size)
{
if (size == 0) / / boneka ada bisa lebih kecil dari 1 atom (10 ^ 0 == 1) sehingga tidak menyebut dirinya
return; / / Kembali tidak harus kembali sesuatu, dapat digunakan
/ / Untuk keluar fungsi
boneka (size - 1); / / decrements variabel ukuran sehingga boneka berikutnya akan lebih kecil.
}
int main ()
{
boneka (10), / / Dimulai dengan boneka besar (skala logaritmik nya)
}
Program ini berakhir ketika ukuran sama dengan satu. Ini adalah kasus dasar yang baik, tetapi jika tidak diatur dengan benar, adalah mungkin untuk memiliki kasus dasar yang selalu benar (atau selalu salah).
Setelah fungsi telah menyebut dirinya, maka akan siap untuk pergi ke baris berikutnya setelah panggilan. Hal ini masih bisa melakukan operasi. Salah satu fungsi yang Anda bisa menulis bisa mencetak angka 123456789987654321. Bagaimana Anda bisa menggunakan rekursi untuk menulis fungsi untuk melakukan hal ini? Cukup memilikinya terus incrementing variabel berlalu dalam, dan kemudian output variabel ... dua kali, sekali sebelum recurses fungsi, dan sekali setelah ...
batal printnum (int mulai)
{
cout << mulai;
if (mulai> 9) / / Kasus dasar adalah ketika begin lebih besar dari 9
printnum (mulai + 1); / / untuk itu tidak akan recurse setelah pernyataan jika-
cout << mulai; / / Output kedua dimulai, setelah program memiliki
/ / Pergi melalui dan output
}
Fungsi ini bekerja karena akan pergi melalui dan mencetak angka mulai 9, dan kemudian karena setiap fungsi printnum berakhir akan terus mencetak nilai dimulai di setiap fungsi dari 9 untuk memulai.
Ini hanyalah awal dari kegunaan rekursi. Heres tantangan kecil, gunakan rekursi untuk menulis sebuah program yang mengembalikan faktorial dari sejumlah besar dari 0. (Faktorial adalah nomor * nomor 1 * Nomor-2 ... * 1).
Petunjuk: Secara rekursif menemukan faktorial dari angka-angka yang lebih kecil pertama, yakni, dibutuhkan angka, menemukan faktorial dari jumlah sebelumnya, dan mengalikan jumlah waktu yang faktorial.
Pelajaran 17 - Func Var Arg
Mungkin Anda ingin memiliki fungsi yang akan menerima sejumlah nilai dan kemudian kembali rata-rata. Anda tidak tahu berapa banyak argumen akan dilewatkan ke fungsi. Salah satu cara Anda bisa membuat fungsi akan menerima pointer ke array. Cara lain adalah dengan menulis fungsi yang dapat mengambil sejumlah argumen. Jadi Anda bisa menulis avg (4, 12,2, 23,3, 33,3, 12,1), atau Anda bisa menulis avg (2, 2,3, 34,4); Beberapa fungsi perpustakaan dapat menerima daftar variabel argumen (seperti printf terhormat).
Untuk menggunakan fungsi dengan jumlah variabel argumen, atau lebih tepatnya, fungsi tanpa nomor set argumen, Anda akan menggunakan file header cstdarg. Ada empat bagian yang dibutuhkan: va_list, yang menyimpan daftar argumen, va_start, yang menginisialisasi daftar, va_arg, yang mengembalikan argumen berikutnya dalam daftar, dan va_end, yang membersihkan daftar argumen variabel. Setiap kali fungsi dinyatakan memiliki jumlah tak tentu argumen, di tempat argumen terakhir Anda harus menempatkan elipsis (yang terlihat seperti '...'), sehingga, int a_function (int x, ...); akan memberitahu compiler fungsi harus menerima argumen namun banyak bahwa programmer menggunakan, asalkan sama dengan setidaknya satu, yang menjadi, pertama x.
va_list adalah seperti variabel lainnya. Misalnya,
va_list a_list;
va_start adalah makro yang menerima dua argumen, sebuah va_list dan nama variabel yang secara langsung mendahului elipsis (...). Jadi, dalam a_function fungsi, untuk menginisialisasi a_list dengan va_start, Anda akan menulis va_start (a_list, x);
va_arg mengambil va_list dan jenis variabel, dan mengembalikan argumen berikutnya dalam daftar dalam bentuk apa pun jenis variabel itu mengatakan. Kemudian bergerak ke bawah daftar untuk argumen berikutnya. Misalnya, va_arg (a_list, ganda) akan mengembalikan argumen berikutnya, dengan asumsi itu ada, dalam bentuk ganda. Lain kali itu disebut, itu akan kembali argumen mengikuti jumlah yang dikembalikan terakhir, jika ada.
Untuk menunjukkan bagaimana setiap bagian bekerja, mengambil fungsi contoh:
# Include <cstdarg>
# Include
menggunakan namespace std;
ganda rata (int num, ...)
{
argumen va_list; / / Tempat untuk menyimpan daftar argumen
ganda sum = 0;
va_start (argumen, num); / / Inisialisasi argumen untuk menyimpan semua nilai setelah num
for (int x = 0; x <num, x + +) / / Loop sampai semua nomor yang ditambahkan
jumlah + = va_arg (argumen, ganda); / / Menambahkan nilai berikutnya dalam daftar argumen untuk sum.
va_end (argumen); / / Membersihkan daftar
return sum / num; / / Returns beberapa nomor (typecast mencegah pemotongan)
}
int main ()
{
cout << rata (3, 12,2, 22,3, 4,5) << endl;
cout << rata (5, 3,3, 2,2, 1,1, 5,5, 3,3) << endl;
}
Hal ini tidak selalu merupakan ide yang baik untuk menggunakan daftar argumen variabel setiap saat, karena potensi ada untuk asumsi nilai adalah dari satu jenis, sementara itu sebenarnya lain, seperti pointer nol yang dianggap integer. Akibatnya, daftar argumen variabel harus digunakan hemat.
Pelajaran 18 - Binary Pohon Part 1
Pohon biner adalah struktur data dasar yang digunakan dalam ilmu komputer. Pohon biner adalah struktur data yang berguna untuk data yang diurutkan dengan cepat menyimpan dan mengambil data yang disimpan dengan cepat. Sebuah pohon biner terdiri dari node induk, atau daun, yang masing-masing menyimpan data dan juga link ke hingga dua node anak lainnya (daun) yang dapat divisualisasikan spasial seperti di bawah node pertama dengan satu ditempatkan ke kiri dan dengan satu ditempatkan ke kanan. Ini adalah hubungan antara daun terkait dan daun menghubungkan, juga dikenal sebagai node induk, yang membuat pohon biner seperti struktur data yang efisien. Ini adalah daun di sebelah kiri yang memiliki nilai kunci yang lebih rendah (yaitu, nilai yang digunakan untuk mencari daun di pohon), dan itu adalah daun di sebelah kanan yang memiliki nilai kunci yang sama atau lebih besar. Akibatnya, daun di terjauh kiri pohon memiliki nilai terendah, sedangkan daun di sebelah kanan pohon memiliki nilai terbesar. Lebih penting lagi, seperti setiap daun menghubungkan ke dua daun lain, itu adalah awal dari sebuah pohon, baru yang lebih kecil, biner. Karena sifat ini, adalah mungkin untuk dengan mudah mengakses dan memasukkan data dalam sebuah pohon biner dengan menggunakan fungsi pencarian dan masukkan rekursif meminta daun berturut-turut.Representasi grafis khas pohon biner pada dasarnya adalah bahwa dari sebuah pohon terbalik. Ini dimulai dengan simpul akar, yang berisi nilai kunci asli. Simpul akar memiliki dua node anak, setiap node anak mungkin memiliki node anak sendiri. Idealnya, pohon akan terstruktur sehingga pohon seimbang sempurna, dengan setiap node memiliki jumlah yang sama node anak ke kiri dan ke kanan. Sebuah pohon seimbang sempurna memungkinkan untuk penyisipan tercepat rata-rata dari data atau pengambilan data. Skenario kasus terburuk adalah pohon di mana setiap node hanya memiliki satu simpul anak, sehingga menjadi seolah-olah itu sebuah linked list dalam hal kecepatan. Representasi khas dari pohon biner terlihat seperti berikut:
10
/ \
6 14
/ \ / \
5 8 11 18
Simpul menyimpan 10, diwakili di sini hanya sebagai 10, adalah simpul akar, menghubungkan ke node anak kiri dan kanan, dengan simpul kiri menyimpan nilai yang lebih rendah dari node induk, dan simpul di sebelah kanan menyimpan nilai yang lebih besar dari node induk. Perhatikan bahwa jika seseorang dihapus simpul akar dan node anak kanan, bahwa node menyimpan nilai 6 akan menjadi setara baru, lebih kecil, pohon biner.Struktur pohon biner membuat penyisipan dan fungsi pencarian sederhana untuk mengimplementasikan menggunakan rekursi. Bahkan, dua penyisipan dan pencarian, juga keduanya sangat mirip. Untuk menyisipkan data ke dalam sebuah pohon biner melibatkan fungsi mencari sebuah simpul yang tidak terpakai dalam posisi yang tepat di pohon di mana untuk memasukkan nilai kunci. Fungsi insert umumnya fungsi rekursif yang terus bergerak turun tingkat pohon biner sampai ada daun yang tidak terpakai dalam posisi yang mengikuti aturan node menempatkan. Aturan-aturan adalah bahwa nilai yang lebih rendah harus di sebelah kiri dari node, dan nilai yang lebih besar atau sama harus ke kanan. Mengikuti aturan, fungsi insert harus memeriksa setiap node untuk melihat apakah itu kosong, jika demikian, itu akan memasukkan data yang akan disimpan bersama dengan nilai kunci (dalam sebagian besar implementasi, node kosong hanya akan menjadi pointer NULL dari node induk, sehingga fungsi juga harus membuat node). Jika node sudah diisi, fungsi insert harus memeriksa untuk melihat apakah nilai kunci untuk dimasukkan kurang dari nilai kunci dari node saat ini, dan jika demikian, fungsi insert harus rekursif disebut pada node anak kiri, atau jika nilai kunci untuk dimasukkan lebih besar dari atau sama dengan nilai kunci dari node saat ini fungsi insert harus rekursif disebut pada node anak kanan. Fungsi pencarian bekerja sepanjang cara yang sama. Ini harus memeriksa untuk melihat apakah nilai kunci dari node saat ini adalah nilai yang akan dicari. Jika tidak, maka harus memeriksa untuk melihat apakah nilai yang akan dicari adalah kurang dari nilai node, dalam hal ini harus secara rekursif disebut pada node anak kiri, atau jika lebih besar dari nilai node, itu harus disebut rekursif pada node anak kanan. Tentu saja, hal ini juga diperlukan untuk memeriksa untuk memastikan bahwa simpul anak kiri atau kanan benar-benar ada sebelum memanggil fungsi pada node.Karena pohon biner memiliki log (basis 2) n lapisan, waktu pencarian rata-rata untuk sebuah pohon biner adalah log (basis 2) n. Untuk mengisi sebuah pohon biner keseluruhan, diurutkan, dibutuhkan kira-kira log (basis 2) n * n. Mari kita lihat kode yang diperlukan untuk implementasi sederhana dari sebuah pohon biner. Pertama, perlu untuk memiliki struct, atau kelas, didefinisikan sebagai node.
struct simpul
{
int key_value;
simpul * kiri;
simpul * benar;
};
Struct memiliki kemampuan untuk menyimpan key_value dan berisi node anak kedua yang menentukan node sebagai bagian dari pohon. Bahkan, node itu sendiri sangat mirip dengan node dalam linked list. Sebuah pengetahuan dasar kode untuk linked list akan sangat membantu dalam memahami teknik pohon biner. Pada dasarnya, pointer diperlukan untuk memungkinkan penciptaan sewenang-wenang node baru dalam pohon.Hal ini paling logis untuk membuat kelas pohon biner untuk merangkum kerja pohon ke daerah tunggal, dan juga membuatnya dapat digunakan kembali. Kelas akan berisi fungsi untuk memasukkan data ke dalam pohon dan untuk mencari data. Karena penggunaan pointer, maka akan diperlukan untuk menyertakan fungsi untuk menghapus pohon dalam rangka untuk menghemat memori setelah program selesai.
Kelas btree
{
simpul akar *;
btree ();
~ Btree ();
batal destroy_tree (node * daun);
kekosongan insert (int key, simpul daun *);
simpul * cari (int key, simpul daun *);
publik:
kekosongan insert (int key);
simpul * cari (int key);
batal destroy_tree ();
};
Insert dan fungsi pencarian yang adalah anggota masyarakat dari kelas dirancang untuk memungkinkan pengguna kelas menggunakan kelas tanpa berurusan dengan desain yang mendasarinya. Insert dan fungsi pencarian yang akan dipanggil secara rekursif adalah orang-orang yang berisi dua parameter, yang memungkinkan mereka untuk melakukan perjalanan ke pohon. Fungsi destroy_tree tanpa argumen adalah sebuah front untuk fungsi destroy_tree yang rekursif akan menghancurkan pohon, node demi node, dari bawah ke atas.Kode untuk kelas akan terlihat mirip dengan berikut ini:
btree :: btree ()
{
root = NULL;
}
Hal ini diperlukan untuk menginisialisasi akar ke NULL untuk fungsi kemudian untuk dapat mengenali bahwa itu tidak ada.
btree :: ~ btree ()
{
destroy_tree ();
}
Fungsi destroy_tree akan berangkat destroy_tree fungsi rekursif ditunjukkan di bawah ini yang benar-benar akan menghapus semua node dari pohon.
batal destroy_tree (node * daun)
{
if (leaf! = NULL)
{
destroy_tree (daun-> kiri);
destroy_tree (daun-> kanan);
menghapus daun;
}
}
The destroy_tree Fungsi pergi ke bagian bawah setiap bagian dari pohon, yaitu, pencarian sementara ada simpul non-null, menghapus bahwa daun, dan kemudian bekerja dengan cara kembali. Menghapus fungsi node paling kiri, maka simpul anak kanan dari node induk node paling kiri, maka akan menghapus node induk, kemudian bekerja jalan kembali untuk menghapus node anak lain dari orang tua dari node itu hanya dihapus, dan terus penghapusan ini bekerja dengan cara sampai ke node dari pohon yang di atasnya delete_tree awalnya disebut. Dalam contoh di atas pohon, urutan penghapusan node akan 5 8 6 11 18 14 10. Perhatikan bahwa perlu untuk menghapus semua node anak untuk menghindari pemborosan memori.
batal btree :: insert (int key, simpul daun *)
{
jika (key <daun-> key_value)
{
if (daun-> kiri = NULL!)
masukkan (kunci, daun-> kiri);
lain
{
daun-> kiri = node baru;
daun-> kiri-> key_value = kunci;
daun-> kiri-> kiri = NULL; / / Mengatur anak kiri dari simpul anak ke null
daun-> kiri-> kanan = NULL; / / Mengatur anak kanan dari simpul anak ke null
}
}
lain jika (key> = daun-> key_value)
{
if (daun-> kanan = NULL!)
masukkan (kunci, daun-> kanan);
lain
{
daun-> kanan = node baru;
daun-> kanan> key_value = kunci;
daun-> kanan> kiri = NULL; / / Mengatur anak kiri dari simpul anak ke null
daun-> kanan> kanan = NULL; / / Mengatur anak kanan dari simpul anak ke null
}
}
}
Kasus dimana akar masih NULL akan diurus oleh fungsi insert yang nonrecursive dan tersedia untuk non-anggota kelas. Pencarian menyisipkan fungsi, bergerak turun pohon node anak, mengikuti peraturan yang telah ditetapkan, berangkat nilai yang lebih rendah untuk dimasukkan dan tepat untuk nilai yang lebih besar, sampai menemukan sebuah simpul kosong yang menciptakan menggunakan 'baru' kata kunci dan menginisialisasi dengan nilai kunci ketika mengatur anak node baru pointer simpul ke NULL. Setelah membuat node baru, fungsi insert tidak akan lagi menyebut dirinya.
simpul * btree :: cari (int key, simpul daun *)
{
if (leaf! = NULL)
{
jika (key == daun-> key_value)
kembali daun;
jika (key <leaf-> key_value)
kembali pencarian (key, daun-> kiri);
lain
kembali pencarian (key, daun-> kanan);
}
lain kembali NULL;
}
Fungsi pencarian yang ditampilkan di atas rekursif bergerak ke bawah pohon sampai baik mencapai node dengan nilai kunci sama dengan nilai yang fungsinya adalah mencari atau sampai fungsi mencapai node diinisiasi, yang berarti bahwa nilai sedang dicari tidak disimpan dalam pohon biner. Ia mengembalikan pointer ke node ke instance sebelumnya fungsi yang menyebutnya, menyerahkan pointer kembali ke fungsi pencarian diakses di luar kelas.
batal btree :: insert (int key)
{
if (root! = NULL)
insert (key, root);
lain
{
akar simpul = baru;
akar-> key_value = kunci;
akar-> kiri = NULL;
akar-> kanan = NULL;
}
}
Versi publik fungsi insert mengurus kasus di mana akar belum diinisialisasi dengan mengalokasikan memori untuk itu dan menetapkan kedua node anak ke NULL dan pengaturan key_value untuk nilai yang akan dimasukkan. Jika simpul akar sudah ada, insert disebut dengan simpul akar sebagai simpul awal fungsi, dan fungsi insert rekursif mengambil alih.
simpul * btree :: cari (int key)
{
kembali pencarian (key, root);
}
Versi publik fungsi pencarian digunakan untuk menonaktifkan rekursi pencarian di simpul akar, menjaga dari yang diperlukan bagi pengguna untuk memiliki akses ke simpul akar.
batal btree :: destroy_tree ()
{
destroy_tree (root);
}
Versi publik fungsi pohon menghancurkan hanya digunakan untuk menginisialisasi fungsi destroy_tree rekursif yang kemudian menghapus semua node dari pohon.
Pelajaran 19 - Inheratence
Kemampuan untuk menggunakan pemrograman berorientasi obyek adalah fitur penting dari C + +. Pelajaran 12 memperkenalkan gagasan kelas, jika Anda belum membaca dan tidak tahu rincian dasar kelas, Anda harus membacanya sebelum melanjutkan tutorial ini. Tutorial ini adalah n Warisan adalah fitur penting dari kelas, bahkan, itu merupakan bagian integral dari gagasan pemrograman berorientasi obyek. Warisan memungkinkan Anda untuk membuat hirarki kelas, dengan berbagai kelas sifat yang lebih spesifik mewarisi aspek umum kelas yang lebih umum. Dengan cara ini, adalah mungkin untuk struktur program dimulai dengan ide-ide abstrak yang kemudian diimplementasikan oleh kelas tertentu. Sebagai contoh, Anda mungkin memiliki Animal kelas dari yang kelas anjing dan kucing melekat sifat-sifat yang umum untuk semua hewan, pada saat yang sama, masing-masing kelas akan memiliki atribut khusus untuk anjing atau kucing hewan.
Warisan menawarkan banyak fitur yang berguna untuk programmer. Kemampuan, misalnya, dari variabel dari kelas yang lebih umum berfungsi sebagai salah satu kelas yang lebih spesifik yang mewarisi dari itu, disebut polimorfisme, berguna. Untuk saat ini, kami akan berkonsentrasi pada sintaks dasar warisan. Polimorfisme akan dibahas dalam tutorial sendiri.
Setiap kelas dapat mewarisi dari kelas lain, tetapi belum tentu praktek yang baik untuk menggunakan warisan (menaruhnya di bank daripada pergi berlibur). Warisan harus digunakan bila Anda memiliki kelas yang lebih umum obyek yang menggambarkan satu set objek. Fitur dari setiap elemen yang mengatur (dari setiap objek yang juga dari jenis yang lebih umum) harus tercermin dalam kelas yang lebih umum. Kelas ini disebut kelas dasar. kelas dasar biasanya mengandung fungsi bahwa semua kelas mewarisi dari itu, yang dikenal sebagai kelas turunan, akan membutuhkan. kelas dasar juga harus memiliki semua variabel bahwa setiap kelas turunan lain akan berisi.
Mari kita lihat sebuah contoh bagaimana struktur program dengan beberapa kelas. Ambil sebuah program yang digunakan untuk mensimulasikan interaksi antara jenis organisme, pohon, burung, beruang, dan makhluk lainnya coinhabiting hutan. Ada kemungkinan akan beberapa kelas dasar yang kemudian akan memiliki kelas turunan spesifik untuk jenis hewan individual. Bahkan, jika Anda tahu apa-apa tentang biologi, Anda mungkin ingin untuk struktur kelas Anda untuk mengambil keuntungan dari klasifikasi biologis dari Raya ke spesies, meskipun mungkin akan terlalu rumit. Sebaliknya, Anda mungkin memiliki kelas dasar untuk hewan dan tumbuhan. Jika Anda ingin menggunakan kelas dasar yang lebih (kelas dapat berasal baik dari satu kelas dan dasar yang lain), Anda mungkin memiliki kelas untuk terbang hewan dan hewan darat, dan mungkin pohon dan semak-semak. Kemudian Anda ingin kelas untuk tipe tertentu dari hewan: merpati dan burung bangkai, beruang dan singa, dan tipe tertentu dari tanaman: oak dan pinus, rumput dan bunga. Ini tidak mungkin untuk hidup bersama di wilayah yang sama, tetapi ide dasarnya ada: kelas yang lebih spesifik harus mewarisi dari kelas yang kurang spesifik.
Kelas, tentu saja, data saham. Sebuah kelas turunan memiliki akses ke sebagian besar fungsi dan variabel dari kelas dasar. Namun demikian, cara-cara untuk menjaga derivedren dari mengakses beberapa atribut dari kelas dasar. Masyarakat kata kunci, dilindungi, dan swasta yang digunakan untuk mengontrol akses ke informasi dalam kelas. Penting untuk diingat bahwa informasi kontrol publik, dilindungi, dan swasta baik untuk kasus tertentu dari kelas dan untuk kelas sebagai tipe data umum. Variabel dan fungsi yang ditetapkan publik keduanya diwariskan oleh kelas turunan dan dapat diakses oleh fungsi luar dan kode ketika mereka adalah elemen dari contoh spesifik dari sebuah kelas. Variabel yang dilindungi tidak dapat diakses oleh fungsi dan kode luar kelas, tetapi kelas turunan mewarisi fungsi-fungsi dan variabel sebagai bagian dari kelas mereka sendiri. Variabel swasta tidak dapat diakses di luar kelas ketika kelas tertentu atau tersedia untuk kelas turunan. Variabel pribadi berguna bila Anda memiliki variabel yang masuk akal dalam konteks ide besar.
Pelajaran 20 - Sintaks Inheratence
Sebelum memulai pelajaran ini, Anda harus memiliki pemahaman tentang ide warisan. Jika Anda tidak, silahkan baca pelajaran 19. Pelajaran ini akan terdiri dari gambaran dari sintaks warisan, penggunaan kata kunci publik, swasta, dan dilindungi, dan kemudian contoh program berikut untuk menunjukkan masing-masing. Sintaks untuk menunjukkan satu kelas sebagai mewarisi dari yang lain sederhana. Ini terlihat seperti berikut: Bear class: Hewan publik, di tempat hanya kelas kata kunci dan kemudian nama kelas. The ": base_class_name publik" adalah sintaks penting dari warisan, fungsi dari sintaks ini adalah bahwa kelas akan berisi semua variabel publik dan dilindungi dari kelas dasar. Jangan bingung gagasan akses kelas turunan harus anggota data dari kelas dasar dan contoh-contoh spesifik dari data kelas turunan memiliki. Data anggota - variabel dan fungsi - yang dimiliki oleh kelas turunan yang khusus untuk jenis kelas, bukan untuk setiap objek individu tipe tersebut. Jadi, dua benda yang berbeda Beruang, sementara memiliki variabel anggota dan fungsi yang sama, mungkin memiliki informasi yang berbeda disimpan dalam variabel mereka, lebih jauh lagi, jika ada hewan kelas dengan obyek, katakanlah BigAnimal objek, jenis itu, dan bukan dari yang lebih jenis tertentu diwariskan dari kelas itu, dua beruang tidak akan memiliki akses ke data dalam BigAnimal. Mereka hanya akan memiliki variabel dan fungsi dengan nama yang sama dan dari jenis yang sama. Contoh cepat warisan:
kelas Hewan
{
publik:
kaki int;
lengan int;
int usia;
Hewan ();
~ Animal ();
membatalkan makan ();
membatalkan tidur ();
membatalkan minuman ();
};
/ / The Animal kelas berisi informasi dan fungsi
/ / Yang berhubungan dengan semua hewan (setidaknya, semua hewan pelajaran ini menggunakan)
Kelas Cat: Animal publik
{
publik:
int fur_color;
membatalkan Purr ();
kekosongan ikan ();
membatalkan Mark_territory ();
};
/ / Bagi Anda akrab dengan kucing
/ / Makan dari operasi diatas adalah unik
/ / Ke teman Anda ramah berbulu
/ / (Atau musuh, sebagai kasus mungkin)
Sebuah diskusi tentang kata kunci publik, swasta, dan dilindungi berguna ketika membahas warisan. Tiga kata kunci yang digunakan untuk mengontrol akses ke fungsi dan variabel yang disimpan dalam kelas.publik:Tingkat yang paling terbuka menyembunyikan data, segala sesuatu yang umum tersedia untuk semua kelas turunan dari kelas dasar, dan variabel publik dan data untuk masing-masing obyek baik dasar dan kelas turunan dapat diakses oleh kode di luar kelas. Fungsi ditandai masyarakat umumnya yang kelas digunakan untuk memberikan informasi kepada dan mengambil informasi dari dunia luar, mereka biasanya antarmuka dengan kelas. Sisa kelas harus disembunyikan dari pengguna (ini sifat tersembunyi dan sifat yang sangat terfokus kelas yang dikenal secara kolektif sebagai enkapsulasi). Sintaks untuk umum adalah:
publik:
Berikut Semuanya publik sampai akhir kelas atau kata kunci lain menyembunyikan data yang digunakan.dilindungi:Variabel dan fungsi ditandai dilindungi diwariskan oleh kelas turunan, namun, kelas-kelas yang berasal menyembunyikan data dari kode luar dari setiap instance dari objek. Perlu diingat, bahkan jika Anda memiliki objek lain dari jenis yang sama sebagai objek pertama Anda, objek kedua tidak dapat mengakses sebuah variabel lindung di objek pertama. Sebaliknya, obyek kedua akan memiliki variabel sendiri dengan nama yang sama - namun belum tentu data yang sama. Dilindungi adalah tingkat yang berguna perlindungan bagi aspek penting untuk kelas yang harus dilalui tanpa memungkinkan untuk diakses. Sintaksnya adalah sama dengan masyarakat. khusus,
dilindungi:
swasta:Swasta adalah tingkat tertinggi dari data-bersembunyi. Tidak hanya fungsi dan variabel ditandai pribadi tidak dapat diakses oleh kode di luar objek tertentu di mana data yang muncul, namun variabel pribadi dan fungsi tidak diwariskan. Tingkat perlindungan data yang diberikan oleh dilindungi umumnya lebih fleksibel daripada tingkat pribadi. Tentu saja, ada sukacita tertentu dalam melindungi data Anda dengan kata kunci pribadi. Sintaks tetap sama.
swasta:
Ok guys ... Yah aku berharap seseorang menemukan tutorial ini bermanfaat.

0 komentar:
Posting Komentar