הוספה
שיעור 9 מתוך 16 בקורס עץ AVL – סדרת מבני נתונים מס' 10 של Coddy.
insert מתחילה כהכנסה רגילה לעץ חיפוש בינארי: מתקדמים למטה תוך השוואת ערכים, פונים שמאלה או ימינה וממקמים את הצומת החדש במקום שבו נמצא מקום ריק (מתעלמים מכפילויות). החלק של AVL מתרחש בדרך חזרה למעלה: לאחר מיקום הצומת, כל צומת קדמון לאורך המסלול מחשב מחדש את height שלו ובודק את מקדם האיזון שלו.
אם צומת יוצא מאיזון, הצד הכבד והמיקום שאליו הגיע הערך החדש קובעים יחד איזה מארבעת המקרים חל: left-left ו-right-right דורשים סיבוב יחיד, ואילו left-right ו-right-left דורשים שניים — סיבוב פנימי ליישור הזיגזג, ולאחריו הסיבוב החיצוני.
אתגר
בינוניכתבו שיטה insert(value) ב־AVLTree (דרך נקייה לעשות זאת היא בעזרת פונקציית עזר רקורסיבית). הוסיפו את value כמו בעץ חיפוש בינארי רגיל, והתעלמו ממנו אם הוא כבר קיים. בדרך חזרה למעלה, חשבו מחדש את הגובה ואת גורם האיזון של כל צומת, ואם צומת אינו מאוזן, בצעו את הסיבוב המתאים (או זוג סיבובים) לפני החזרה במעלה מחסנית הקריאות.
נסו בעצמכם
#include <stdio.h>
#include <string.h>
#include "avltree.h"
static void preorderValues(Node* node, int* vals, int* count) {
if (node == NULL) {
return;
}
vals[(*count)++] = node->value;
preorderValues(node->left, vals, count);
preorderValues(node->right, vals, count);
}
int main(void) {
AVLTree* tree = AVLTree_create();
char line[256];
while (fgets(line, sizeof(line), stdin) != NULL) {
line[strcspn(line, "\r\n")] = '\0';
char cmd[32];
int arg;
int parsed = sscanf(line, "%31s %d", cmd, &arg);
if (parsed >= 1 && strcmp(cmd, "insert") == 0) {
AVLTree_insert(tree, arg);
}
if (parsed >= 1 && strcmp(cmd, "preorder") == 0) {
int vals[10000];
int count = 0;
preorderValues(tree->root, vals, &count);
for (int i = 0; i < count; i++) {
if (i > 0) {
printf(" ");
}
printf("%d", vals[i]);
}
printf("\n");
}
if (parsed >= 1 && strcmp(cmd, "height") == 0) {
printf("%d\n", AVLTree_getHeight(tree, tree->root));
}
}
return 0;
}
כל השיעורים ביחידה עץ AVL – סדרת מבני נתונים מס' 10
תרגלו בעצמכם: קומפיילר C אונליין