Step 2: Delete

本文详细介绍了在AVL树中删除节点的具体步骤,并针对三种不同情况提供了代码实现。此外,还探讨了删除操作后的平衡调整及特殊情况处理。

5.5.2 Step 2: Delete

At this point, we've identified p as the node to delete. The node on the top of the stack, da[k - 1], is p's parent node. There are the same three cases we saw in deletion from an ordinary BST (see Deleting from a BST), with the addition of code to copy balance factors and update the stack.

The code for selecting cases is the same as for BSTs:

166. <Step 2: Delete item from AVL tree 166> =
if (p->avl_link[1] == NULL)
  { <Case 1 in AVL deletion 168> }
else 
  { struct avl_node *r = p->avl_link[1]; if (r->avl_link[0] == NULL) {
        <Case 2 in AVL deletion 169>
      } else
      {
        <Case 3 in AVL deletion 170>
      } }

See also 167.

This code is included in 164.

Regardless of the case, we are in the same situation after the deletion: node p has been removed from the tree and the stack contains k nodes at which rebalancing may be necessary. Later code may change p to point elsewhere, so we free the node immediately. A pointer to the item data has already been saved in item (see avldelsaveitem):

167. <Step 2: Delete item from AVL tree 166> +=
tree->avl_alloc->libavl_free (tree->avl_alloc, p);
Case 1: p has no right child

If p has no right child, then we can replace it with its left child, the same as for BSTs (see bstdelcase1).

168. <Case 1 in AVL deletion 168> =
pa[k - 1]->avl_link[da[k - 1]] = p->avl_link[0];

This code is included in 166.

Case 2: p's right child has no left child

If p has a right child r, which in turn has no left child, then we replace p by r, attaching p's left child to r, as we would in an unbalanced BST (see bstdelcase2). In addition, r acquires p's balance factor, and r must be added to the stack of nodes above the deleted node.

169. <Case 2 in AVL deletion 169> =
r->avl_link[0] = p->avl_link[0];
r->avl_balance = p->avl_balance;
pa[k - 1]->avl_link[da[k - 1]] = r;
da[k] = 1;
pa[k++] = r;

This code is included in 166.

Case 3: p's right child has a left child

If p's right child has a left child, then this is the third and most complicated case. On the other hand, as a modification from the third case in an ordinary BST deletion (see bstdelcase3), it is rather simple. We're deleting the inorder successor of p, so we push the nodes above it onto the stack. The only trickery is that we do not know in advance the node that will replace p, so we reserve a spot on the stack for it (da[j]) and fill it in later:

170. <Case 3 in AVL deletion 170> =
struct avl_node *s;
int j = k++;

for (;;) 
  { da[k] = 0; pa[k++] = r; s = r->avl_link[0]; if (s->avl_link[0] == NULL) break; r = s; } s->avl_link[0] = p->avl_link[0]; r->avl_link[0] = s->avl_link[1]; s->avl_link[1] = p->avl_link[1]; s->avl_balance = p->avl_balance; pa[j - 1]->avl_link[da[j - 1]] = s; da[j] = 1; pa[j] = s;

This code is included in 166.

Exercises:

1. Write an alternate version of <Case 3 in AVL deletion 170> that moves data instead of pointers, as in Exercise 4.8-2.
[answer]

1. This approach cannot be used in libavl (see Exercise 4.8-3).

651. <Case 3 in AVL deletion, alternate version 651> =
struct avl_node *s;

da[k] = 1;
pa[k++] = p;
for (;;) 
  { da[k] = 0; pa[k++] = r; s = r->avl_link[0]; if (s->avl_link[0] == NULL) break; r = s; } p->avl_data = s->avl_data; r->avl_link[0] = s->avl_link[1]; p = s;


2. Why is it important that the item data was saved earlier? (Why couldn't we save it just before freeing the node?)
[answer]
2. We could, if we use the standard libavl code for deletion case 3. The alternate version in Exercise 1 modifies item data, which would cause the wrong value to be returned later.

转载于:https://www.cnblogs.com/sohu2000000/archive/2010/10/06/1844823.html

#include <stdio.h> #include <conio.h> #include <malloc.h> struct node { struct node *next; int data; struct node *prev; }; struct node *start = NULL; struct node *create_ll(struct node *); struct node *display(struct node *); struct node *insert_beg(struct node *); struct node *insert_end(struct node *); struct node *delete_beg(struct node *); struct node *delete_end(struct node *); struct node *delete_node(struct node *); struct node *delete_list(struct node *); int main() { int option; clrscr(); do { printf("\n\n *****MAIN MENU *****"); printf("\n 1: Create a list"); printf("\n 2: Display the list"); printf("\n 3: Add a node at the beginning"); printf("\n 4: Add a node at the end"); printf("\n 5: Delete a node from the beginning"); printf("\n 6: Delete a node from the end"); printf("\n 7: Delete a given node"); printf("\n 8: Delete the entire list"); printf("\n 9: EXIT"); printf("\n\n Enter your option : "); Step 1: IF START = NULL Write UNDERFLOW Go to Step 8 [END OF IF] Step 2: SET PTR = START [END OF LOOP] Step 7: FREE PTR Step 8: EXIT Step 3: Repeat Step 4 while PTR NEXT != START Step 4: SET PTR = PTR NEXT Step 5: SET PTR PREV NEXT = START Step 6: SET START PREV = PTR PREV -> -> -> -> -> -> Figure 6.64 Algorithm to delete the last node 204 Data Structures Using C scanf("%d", &option); switch(option) { case 1: start = create_ll(start); printf("\n CIRCULAR DOUBLY LINKED LIST CREATED"); break; case 2: start = display(start); break; case 3: start = insert_beg(start); break; case 4: start = insert_end(start); break; case 5: start = delete_beg(start); break; case 6: start = delete_end(start); break; case 7: start = delete_node(start); break; case 8: start = delete_list(start); printf("\n CIRCULAR DOUBLY LINKED LIST DELETED"); break; } }while(option != 9); getch(); return 0; } struct node *create_ll(struct node *start) { struct node *new_node, *ptr; int num; printf("\n Enter –1 to end"); printf("\n Enter the data : "); scanf("%d", &nu
03-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值