簡體   English   中英

插入 AVL 樹

[英]Insertion into AVL tree

我目前正在嘗試在 c 中構建一個 AVL 樹,其中每個節點都包含一個名稱和一個值。 樹應該按值排序。 目前,輸入:

6 Franklin
4 David
1 Anna 
2 Bob
3 Cora
5 Ella
7 Griffin

樹最終看起來像

         David
     /           \
   Anna        Franklin
      \        /    \
      Bob    Ella  Griffin
        \ 
       Cora

當它看起來像

          David
      /          \
    Bob       Franklin
  /    \      /      \
Anna  Cora  Ella  Griffin

這似乎是它打破的閾值大小,輸入由較少的節點組成。 相關代碼:

#define MAX(X, Y) ((X) < (Y) ? (Y) : (X))

int height(struct Tree_Node *n) {

    if (n->right && n->left) return MAX(n->right->height, n->left->height) + 1;
    if (n->left && !n->right) return n->left->height + 1;
    if (n->right && !n->left) return n->right->height + 1;

    return 0;
}

int balance(struct Tree_Node *n) {

    if (n->left && n->right) return n->left->height - n->right->height;
    if (n->left && !n->right) return n->left->height;
    if (!n->left && n->right) return n->right->height;
    return 0;
}

struct Tree_Node *rotate_left(struct Tree_Node *n){

    struct Tree_Node *p;
    struct Tree_Node *tp;
    p = n;
    tp = p->left;

    p->left = tp->right;
    tp->right = p;

    return tp; 
}


struct Tree_Node *rotate_right(struct Tree_Node *n){

    struct Tree_Node *p;
    struct Tree_Node *tp;
    p = n;
    tp = p->right;

    p->right = tp->left;
    tp->left = p;

    return tp; 
}

struct Tree_Node *rotate_right_left(struct Tree_Node *n) {

    struct Tree_Node *p;
    struct Tree_Node *tp;
    struct Tree_Node *tp2;
    p = n;
    tp = p->right;
    tp2 =p->right->left;

    p -> right = tp2->left;
    tp ->left = tp2->right;
    tp2 ->left = p;
    tp2->right = tp; 
     
    return tp2; 
}

struct Tree_Node *rotate_left_right(struct Tree_Node *n) {

    struct Tree_Node *p;
    struct Tree_Node *tp;
    struct Tree_Node *tp2;
    p = n;
    tp = p->left;
    tp2 =p->left->right;

    p -> left = tp2->right;
    tp ->right = tp2->left;
    tp2 ->right = p;
    tp2->left = tp; 
     
    return tp2; 
}

struct Tree_Node *insert_leaf(struct Tree_Node *root, struct Tree_Node *new) {

    if (!root) {
        root = new;
        root->left = NULL;
        root->right = NULL;
        root->height = 0;
        return root;
    }
    else {
        if (new->value < root->value) root->left = insert_leaf(root->left, new);
        else root->right = insert_leaf(root->right, new);
    }
    root->height = height(root);
    
    if (balance(root) > 1 && new->value < root->left->value) root = rotate_left(root);
    else if (balance(root) < -1 && new->value > root->right->value) root = rotate_right(root);
    else if (balance(root) < -1 && new->value < root->right->value) root = rotate_right_left(root);
    else if (balance(root) > 1 && new->value > root->left->value) root = rotate_left_right(root);

    return root;
}

有以下問題:

  • 葉節點的高度是 1,而不是 0。所以height function 中的最后一個return應該是:

     return 1;

    insert_leaf function 中,從if塊中刪除這兩行:

     root->height = 0; return root;

    這樣,執行將繼續調用height以將此值正確設置為 1。

  • 旋轉函數將更改返回節點的后代節點的高度,因此您必須更新它們的高度。 因此,在單旋轉函數中,添加以下行:

     p->height = height(p);

    並在雙旋轉功能中,添加:

     p->height = height(p); tp->height = height(tp);
  • 您使用n->left->height - n->right->height將右重樹的平衡定義為,但是當n->leftNULLn->right不是時將其設為正。 在這種情況下它應該是負面的。 所以像這樣添加否定運算符:

     if (;n->left && n->right) return -n->right->height;

通過這些更改,將為您的測試用例構建預期的樹。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM