图解-堆删除节点

本文详细阐述了在堆数据结构中删除特定节点的算法流程,包括如何通过替换删除节点来保持二叉树的完整性,并进一步调整以确保堆属性不被破坏。文章深入解析了向上过滤和向下过滤的具体步骤,提供了伪代码和Java实现示例。
摘要由CSDN通过智能技术生成

转自:http://www.mathcs.emory.edu/~cheung/Courses/171/Syllabus/9-BinTree/heap-delete.html

 

 

  • Deleting a specific node from a Heap

     

     





     

    • Problem description:

       

      • You are given a heap.

        For example:

         

         


         

      • You are also given a index k

        For example: k = 2

         


         

      • Problem:

         

        • Delete the value a[k] from the heap (so that the resulting tree is also a heap !!!)

         

       


       

    • Here is a Heap with the element a[2] = 5 deleted:

       

      Heap before deleting the value a[2] = 5
      Heap after the deletion...

      $64,000 question:

       

      • How did you do it ???        

       

  • The delete algorithm for a Heap

     

     





     

    • The heap deletion algorithm in pseudo code:

       

          1, Delete a node from the array 
             (this creates a "hole" and the tree is no longer "complete")
      
          2. Replace the deletion node
             with the "fartest right node" on the lowest level
             of the Binary Tree
             (This step makes the tree into a "complete binary tree")
      
          3. Heapify (fix the heap):
      
               if ( value in replacement node < its parent node )
                  Filter the replacement node UP the binary tree
               else
      	    Filter the replacement node DOWN the binary tree
       
      

       


       

    • Example:

       

      • Delete the node containing the value 5 from the following heap:

         

        After you delete the node, the tree is not a complete binary tree:

         

         



         

      • Step 1: replace the deleted node with the node in the "fartest right location" of the lowest level

         

        Result:

         

        However, it is not a heap:

         

        • We must fix the binary tree so that it becomes a heap again !!!

           

           

          • Depending on the value of the replacement node, we must filter the replacement node upwards ordownwards

           

           

        Since you have already seen the filter up algorithm --- in the heap insert algorithm --- I made the example to show you the filter down algorithm now

         


         

      • Step 2: because the replacement node 21 is greater than its parent node (1), we must filter the replacement node down the tree

         

         

        Filter the replacement node down the tree proceeds as follows:

         

        • Compare the values of the replacement node with all its children nodes in the tree:

           

          Some child node has a smaller value: the replacement node is not in its proper location

           


           

        • Swap the replacement node with the smallest of the children nodes:

           

           

        • After swapping:

           

           

          Repeat !

           



           

        • Compare the values of the replacement node (21) with all its children nodes in the tree:

           

           

          Some child node has a smaller value: the replacement node is not in its proper location

           


           

        • Swap the replacement node with the smallest of the children nodes:

           

          After swapping:

           

           

          Repeat !

           



           

        • The replacement node (21) does not have any children node:

           

          Done !!!

         

       







       

    • Warning:

       

      • Sometimes, you have to filter the replacement node up the Binary tree !!!!!      

      Example:

       

      • Delete the node with value = 33 from the following heap:

         

         



         

      • Step 1: replace the deleted node with the "last" node in the lowest level (to make a complete binary tree)

         

        Result:

         

         



         

      • In this case, the replacement node must be filtered up into the binary tree:

         

        Result:

         

         

       



       

    • Conclusion:

       

           if ( replacement node < its parent node )
              filter the replacement node up the tree
           else
              filter the replacement node down the tree      
      

       

       



       

    • Heap deletion algorithm in Java:

       

         public double remove( int k )
         {
            int parent;
            double r;             // Variable to hold deleted value
      
            r = a[k];             // Save return value
      
            a[k] = a[NNodes];     // Replace deleted node with the right most leaf
                                  // This fixes the "complete bin. tree" property
      
            NNodes--;             // One less node in heap....
      
            parent = k/2;
      
            /* =======================================================
      	 Filter a[k] up or down depending on the result of:
      		a[k] <==> a[k's parent]
               ======================================================= */
            if ( k == 1 /* k is root */ || a[parent] < a[k] ) 
               HeapFilterDown(k);  // Move the node a[k] DOWN the tree
            else
               HeapFilterUp(k);    // Move the node a[k] UP the tree
      
            return r;         // Return deleted value...
         }
      

      (We have already discussed the HeapFilterUp() algorithm .... )

       





       

    • Filter Down algorithm in pseudo code:

       

          HeapFilterDown( k )   // Filter node a[k] down to its proper place
          {
             while ( a[k] has at least 1 child node )
             {
                child1 = 2*k;        // left  child of a[k]
      	  child2 = 2*k + 1;    // right child of a[k]
      
                if ( a[k] has 2 childred nodes )
      	  {
      	     if ( a[k] has smallest value among {a[k], a[child1], a[child2]} )
      	        break;       // a[k] in proper place, done
      	     else
      	     {
      	        /* =========================================
      		   Replace a[k] with the smaller child node
      		   ========================================= */
      	        if ( a[child1] < a[child2] )
      		{
      		   swap ( a[k], a[child1] );
      		   k = child1;                 // Continue check....
      	        }
      		else
      		{
      		   swap ( a[k], a[child2] );
      		   k = child2;                 // Continue check...
      		}
      	     }
      	  }
      	  else  // a[k] must have only 1 child node
      	  {
      	     if ( a[k] has smallest value among {a[k], a[child1]} )
      	        break;       // a[k] in proper place, done
      	     else
      	     {
      		swap ( a[k], a[child1] );
      	        k = child1;                    // Continue check....
      	  }
             }
          }
      

       


       

    • The Filter down algorithm (describe above) is coded as a method:

       

         /* ========================================================
            HeapFilterDown(k): Filters the node a[k] down the heap
            ======================================================== */
         void HeapFilterDown( int k )
         {
            int child1, child2;          // Indices of the children nodes of k
            double help;
      
            while ( 2*k <= NNodes )       // Does k have any child node ? 
            {
               child1 = 2*k;              // Child1 = left  child of k
               child2 = 2*k+1;            // Child2 = right child of k
      
               if ( child2 <= NNodes )    // If true, then k has 2 children nodes !
               {
                  /* ========================================
                     Node k has 2 children nodes....
                     Find the min. of 3 nodes !!!
                     ======================================== */
                  if ( a[k] < a[child1] && a[k] < a[child2] )
                  {
                     /* -------------------------------------------------------
      	          Node k has the smallest value !
                        Node k is in correct location... It's a heap. Stop...
                        ------------------------------------------------------- */
                     break;    // STOP, it's a heap now
                  }
                  else
                  {
                     /* ===================================================
      	          Swap a[k] with the smaller of its 2 children nodes
      		  =================================================== */
                     if ( a[child1] < a[child2] )
         	       {
         		  /* -------------------------------------------------------
         		     Child1 is smaller: swap a[k] with a[child1]
         		     ------------------------------------------------------- */
         		  help = a[k];
         		  a[k] = a[child1];
         		  a[child1] = help;
         		
         		  k = child1;     // Replacement node is a[child1]
         				  // in next iteration
         	       }
         	       else
         	       {
         		  /* -------------------------------------------------------
         		     Child2 is smaller: swap a[k] with a[child2]
         		     ------------------------------------------------------- */
         		  help = a[k];
         		  a[k] = a[child2];
         		  a[child2] = help;
         		
         		  k = child2;     // Replacement node is a[child2]
         				  // in next iteration
         	       }
                  }
               }
               else
               {
                  /* ========================================
                     Node k only has a left child node
                     Find the min. of 2 nodes !!!
                     ======================================== */
                  if ( a[k] < a[child1] )
                  {
                     /* -------------------------------------------------------
                        Node k is in correct location... It's a heap. Stop...
                        ------------------------------------------------------- */
                     break;
                  }
                  else
                  {
                     /* -------------------------------------------------------
                        Child1 is smaller: swap a[k] with a[child1]
                        ------------------------------------------------------- */
                     help = a[k];
                     a[k] = a[child1];
                     a[child1] = help;
      
                     k = child1;     // Replacement node is a[child1]
                                     // in next iteration
                  }
               }
            }
         }
      

       


       

    • Example Program: (Demo above code)                                                 

       

      How to run the program:

       

      • Right click on link and save in a scratch directory

         

      • To compile:   javac testProg2.java
      • To run:          java testProg2

       

  • Running time analysis of the heap delete algorithm

     

     





     

    • Before we can perform a running time analysis, we must first understand how the algorithm works exactly...

       


       

    • Summary of the heap delete algorithm:

       

      • The deleted node is first replaced:

         

        We will always have a complete binary tree:

         

         


         

      • Then the HeapFilterUp() or the HeapFilterDown() algorithm will migrate the replacement node up or down into the binary tree:

         

        and:

         

         

       



       

    • Fact:

       

      • The number of times that the deleted node will migrate up or down into the binary tree is:

         

            # migrationsheight of the binary tree               
        

         

      Example:

       

      • The maximum number of times that replacement node can move down in a binary tree:

         

        is at most 3 times:

         

         

      The same argument can be apply to show that the maximum number of times that a nodes can move up the tree is at most the height of the tree.

       



       

    • Therefore:

       

         Running time( delete(n) ) = Running time heap delete in heap with n node     
      
                                   = height of a heap of n nodes   
      

       

  • The height of a heap when it contains n nodes

     

     





     

    • We have already determined this fact:

       

        Let:  n =  # nodes in heap of height h 
      
                2h - 1  <  n          ≤  2h+1 − 1       
         <===>  2h      <  n + 1      ≤   2h+1
         <===>  h       <  lg(n + 1)  ≤  h+1
      
      
         ===> height of heap ~= lg(n + 1)         
      

       

  • Running time of the heap delete algorithm

     

    • Summary:

       

      • Running time of delete into a heap of n nodes = height of the heap

         


         

      • height of the heap containing n nodes ~= lg(n + 1)

       


       

    • Conclusion:

       

      • Running time of delete into a heap of n nodes = O(lg(n))       
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值