sinau-c/content/binary_trees.md

205 lines
7.3 KiB
Markdown

---LESSON_INFO---
**Learning Objectives:**
- Memahami konsep pohon biner (binary tree) dalam bahasa C
- Belajar membuat dan mengelola struktur pohon biner
- Mengenal operasi dasar pada pohon biner
- Memahami traversal dalam pohon biner
**Prerequisites:**
- Pemahaman tentang pointer dan struktur
- Pemahaman dasar tentang rekursi
---END_LESSON_INFO---
# Pohon Biner dalam C
## Pengantar
Pohon Biner adalah jenis struktur data di mana setiap node memiliki paling banyak dua anak (anak kiri dan anak kanan). Pohon biner digunakan untuk mengimplementasikan pohon pencarian biner dan tumpukan biner, dan digunakan untuk pencarian dan pengurutan yang efisien. Pohon biner adalah kasus khusus dari pohon K-ary, di mana k adalah 2. Operasi umum untuk pohon biner termasuk penyisipan, penghapusan, dan penjelajahan. Kesulitan melakukan operasi ini bervariasi jika pohon seimbang dan juga apakah node adalah node daun atau node cabang. Untuk **pohon seimbang** kedalaman subtree kiri dan kanan dari setiap node berbeda 1 atau kurang. Ini memungkinkan **kedalaman** yang dapat diprediksi juga dikenal sebagai **tinggi**. Ini adalah ukuran dari node dari akar ke daun, di mana akar adalah 0 dan node selanjutnya adalah (1,2..n). Ini bisa dinyatakan oleh bagian integer dari log2(n) di mana n adalah jumlah node dalam pohon.
```
g
s 9
/ \ / \
/ \ / \
b m f u
5 13
/ \ / \
c d t y
11 15
```
Operasi yang dilakukan pada pohon memerlukan pencarian dengan salah satu dari dua cara utama: Pencarian Kedalaman Pertama dan Pencarian Lebar-terlebih dahulu. **Pencarian Kedalaman Pertama (DFS)** adalah algoritma untuk menelusuri atau mencari struktur data pohon atau graf. Seseorang mulai dari akar dan mengeksplorasi sejauh mungkin sepanjang setiap cabang sebelum kembali. Ada tiga jenis penjelajahan kedalaman pertama: **pre-order** kunjungi, kiri, kanan, **in-order** kiri, kunjungi, kanan, **post-order** kiri, kanan, kunjungi. **Pencarian Lebar-terlebih dahulu (BFS)** adalah algoritma untuk menelusuri atau mencari struktur data pohon atau graf. Dalam urutan tingkat, di mana kita mengunjungi setiap node dalam tingkat sebelum pergi ke tingkat yang lebih rendah.
---
## Tabel Jenis Traversal dalam Pohon Biner
| Jenis Traversal | Urutan Kunjungan | Contoh |
|-----------------|------------------|--------|
| Pre-order | Root, Kiri, Kanan | A, B, D, E, C, F |
| In-order | Kiri, Root, Kanan | D, B, E, A, F, C |
| Post-order | Kiri, Kanan, Root | D, E, B, F, C, A |
| Level-order | Berdasarkan tingkat | A, B, C, D, E, F |
---EXERCISE---
# Latihan: Traversal Pohon Biner
Berikut adalah implementasi dari pohon biner yang memiliki fungsi penyisipan dan pencetakan. Pohon ini diurutkan tetapi tidak seimbang. Contoh ini menjaga pengurutannya saat waktu penyisipan. Ubah rutin cetak menjadi pencarian kedalaman pertama **pre-order**.
**Requirements:**
- Ubah fungsi printDFS untuk traversal pre-order
- Cetak nilai node dalam urutan pre-order
- Pastikan traversal mengikuti urutan kunjungan: root, kiri, kanan
**Expected Output:**
```
5 4 3 8
```
Try writing your solution in the code editor below!
---EXPECTED_OUTPUT---
5 4 3 8
---END_EXPECTED_OUTPUT---
---INITIAL_CODE---
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int val;
struct node * left;
struct node * right;
} node_t;
void insert(node_t * tree,int val);
void print_tree(node_t * current);
void printDFS(node_t * current);
int main() {
node_t * test_list = (node_t *) malloc(sizeof(node_t));
/* atur nilai secara eksplisit, alternatifnya adalah calloc() */
test_list->val = 0;
test_list->left = NULL;
test_list->right = NULL;
insert(test_list,5);
insert(test_list,8);
insert(test_list,4);
insert(test_list,3);
printDFS(test_list);
printf("\\n");
}
void insert(node_t * tree, int val) {
if (tree->val == 0) {
/* sisipkan pada posisi saat ini (kosong) */
tree->val = val;
} else {
if (val < tree->val) {
/* sisipkan ke kiri */
if (tree->left != NULL) {
insert(tree->left, val);
} else {
tree->left = (node_t *) malloc(sizeof(node_t));
/* atur nilai secara eksplisit, alternatifnya adalah calloc() */
tree->left->val = val;
tree->left->left = NULL;
tree->left->right = NULL;
}
} else {
if (val >= tree->val) {
/* sisipkan ke kanan */
if (tree->right != NULL) {
insert(tree->right,val);
} else {
tree->right = (node_t *) malloc(sizeof(node_t));
/* atur nilai secara eksplisit, alternatifnya adalah calloc() */
tree->right->val = val;
tree->right->left = NULL;
tree->right->right = NULL;
}
}
}
}
}
/* pencarian kedalaman pertama */
void printDFS(node_t * current) {
/* ubah kode di sini */
if (current == NULL) return; /* tindakan keamanan */
if (current->left != NULL) printDFS(current->left);
if (current != NULL) printf("%d ", current->val);
if (current->right != NULL) printDFS(current->right);
}
---END_INITIAL_CODE---
---SOLUTION_CODE---
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int val;
struct node * left;
struct node * right;
} node_t;
void insert(node_t * tree,int val);
void print_tree(node_t * current);
void printDFS(node_t * current);
int main() {
node_t * test_list = (node_t *) malloc(sizeof(node_t));
/* atur nilai secara eksplisit, alternatifnya adalah calloc() */
test_list->val = 0;
test_list->left = NULL;
test_list->right = NULL;
insert(test_list,5);
insert(test_list,8);
insert(test_list,4);
insert(test_list,3);
printDFS(test_list);
printf("\\n");
}
void insert(node_t * tree, int val) {
if (tree->val == 0) {
/* sisipkan pada posisi saat ini (kosong) */
tree->val = val;
} else {
if (val < tree->val) {
/* sisipkan ke kiri */
if (tree->left != NULL) {
insert(tree->left, val);
} else {
tree->left = (node_t *) malloc(sizeof(node_t));
/* atur nilai secara eksplisit, alternatifnya adalah calloc() */
tree->left->val = val;
tree->left->left = NULL;
tree->left->right = NULL;
}
} else {
if (val >= tree->val) {
/* sisipkan ke kanan */
if (tree->right != NULL) {
insert(tree->right,val);
} else {
tree->right = (node_t *) malloc(sizeof(node_t));
/* atur nilai secara eksplisit, alternatifnya adalah calloc() */
tree->right->val = val;
tree->right->left = NULL;
tree->right->right = NULL;
}
}
}
}
}
/* pencarian kedalaman pertama */
void printDFS(node_t * current) {
/* ubah kode di sini */
if (current == NULL) return; /* tindakan keamanan */
if (current != NULL) printf("%d ", current->val);
if (current->left != NULL) printDFS(current->left);
if (current->right != NULL) printDFS(current->right);
}
---END_SOLUTION_CODE---