左式堆的合并

左式堆合并的时间复杂度为O(N) , 由于n个节点的左式堆的右子树最多含有log(N+1)个节点, 而且每次合并都是与较小值堆的右子树进行比较, 所以为O(N).
  1 package heap;
  2 
  3 import java.util.LinkedList;
  4 import java.util.Queue;
  5 import java.util.Stack;
  6 
  7 public class LeftHeap
  8 {
  9     int num ;
 10     LeftHeap left ;
 11     LeftHeap right ;
 12     int npl ;
 13 
 14     public LeftHeap() {}
 15 
 16     public LeftHeap(int num, int npl) {
 17         this.npl = npl;
 18         this.num = num;
 19     }
 20 
 21     public static LeftHeap create1(int[] num)
 22     {
 23         if(num == null || num.length < 1)
 24             return null ;
 25         Queue<LeftHeap> queue = new LinkedList<>() ;
 26         for(int i=0 ; i<num.length ; i++)
 27         {
 28             queue.add(new LeftHeap(num[i] , 0)) ;
 29         }
 30 
 31         while (queue.size()>=2)
 32         {
 33             LeftHeap h1 = queue.poll() ;
 34             LeftHeap h2 = queue.poll() ;
 35 
 36             LeftHeap heap = merge(h1 , h2) ;
 37             queue.add(heap) ;
 38         }
 39 
 40         return queue.poll() ;
 41     }
 42 
 43     public static LeftHeap create2(int[] num)
 44     {
 45         if(num == null || num.length < 1)
 46             return null ;
 47         int N = num.length ;
 48         LeftHeap[] arr = new LeftHeap[N+1] ;
 49         for(int i=0 ; i<N ; i++)
 50         {
 51             arr[i+1] = new LeftHeap(num[i] , 0) ;
 52         }
 53 
 54         for(int k=N/2 ; k>=1 ; k--)
 55             sink(arr , k , N) ;
 56         return arr[1] ;
 57     }
 58 
 59     private static void sink(LeftHeap[] heap , int k , int N)
 60     {
 61         while (k*2 <= N)
 62         {
 63             int min = k*2 ;
 64             heap[k].left = heap[min] ;
 65             if(min+1 <= N)
 66             {
 67                 heap[k].right = heap[min+1] ;
 68                 heap[k].npl = heap[min+1].npl+1 ;
 69                 if(heap[min].num > heap[min+1].num)
 70                     min++ ;
 71             }
 72 
 73             if(heap[k].num > heap[min].num)
 74             {
 75                 int temp = heap[k].num ;
 76                 heap[k].num = heap[min].num ;
 77                 heap[min].num = temp ;
 78                 k=min ;
 79             }
 80             else
 81                 break ;
 82         }
 83     }
 84 
 85     public static LeftHeap insert(int num , LeftHeap h1)
 86     {
 87         LeftHeap h = new LeftHeap(num , 0) ;
 88         return merge_unrec(h1 , h) ;
 89     }
 90 
 91     public static LeftHeap deleteMin(LeftHeap h)
 92     {
 93         if(h == null)
 94             return null ;
 95         return merge_unrec(h.left , h.right) ;
 96     }
 97 
 98     /**
 99      * 左式堆合并的非递归实现
100      */
101     public static LeftHeap merge_unrec(LeftHeap h1 , LeftHeap h2)
102     {
103         if(h1 == null || h2 == null)
104             return h1 == null ? h2 : h1 ;
105 
106         Stack<LeftHeap> stack = new Stack<>() ; //用于保存每一级的父节点
107 
108         while (h2 != null || !stack.isEmpty())
109         {
110             if(h1 != null && h2 != null)
111             {
112                 if(h1.num > h2.num) //确保h1为小值的堆,h2为大值的堆
113                 {
114                     LeftHeap temp = h1 ;
115                     h1 = h2 ;
116                     h2 = temp ;
117                 }
118 
119                 if(h1.left == null) //当小堆的左子树为空时, 直接将h2作为他的左子树即可, 由于仍不存在右子树, 所以npl无需更新
120                 {
121                     h1.left = h2 ;
122                     h2 = null ;
123                 }
124                 else
125                 {
126                     stack.push(h1) ;    //说明左右子树都存在, 此时应将h1保存, 让h1的右子树和h2进行合并
127                     h1 = h1.right ;
128                 }
129             }
130             else  //各级的父节点连接右子树
131             {
132                 if(h1 == null)
133                 {
134                     h1 = h2 ;
135                     h2 = null ;
136                 }
137                 while (!stack.isEmpty())
138                 {
139                     LeftHeap heap = stack.pop() ;
140                     heap.right = h1 ;
141                     if(heap.left.npl < heap.right.npl)
142                         swapLR(heap) ;
143                     heap.npl = heap.right.npl+1 ;
144                     h1 = heap ;
145                 }
146             }
147         }
148         return h1 ;
149     }
150 
151     public static LeftHeap merge(LeftHeap h1 , LeftHeap h2)
152     {
153         if(h1 == null || h2 == null)
154             return h1 == null ? h2 : h1 ;
155         if(h1.num > h2.num)
156             return merge1(h2 , h1) ;
157         else
158             return merge1(h1 , h2) ;
159     }
160 
161     private static LeftHeap merge1(LeftHeap h1 , LeftHeap h2)
162     {
163         if(h1.left == null)
164             h1.left = h2 ;
165         else
166         {
167             h1.right = merge(h1.right , h2) ;
168             if(h1.left.npl < h1.right.npl)
169                 swapLR(h1) ;
170             h1.npl = h1.right.npl+1 ;
171         }
172 
173         return h1 ;
174     }
175 
176     private static void swapLR(LeftHeap h)
177     {
178         LeftHeap temp = h.left ;
179         h.left = h.right ;
180         h.right = temp ;
181     }
182 
183     public static void inOrder(LeftHeap heap)
184     {
185         if(heap == null)
186             return ;
187         inOrder(heap.left);
188         System.out.print(heap.num + " ");
189         inOrder(heap.right);
190     }
191     public static void main(String[] args)
192     {
193         int[] arr = new int[]{
194                 6,2,8,11,22,3
195         } ;
196         LeftHeap heap = create1(arr) ;
197         inOrder(heap);
198         /*LeftHeap h1 = new LeftHeap(3, 1) ;
199         LeftHeap h2 = new LeftHeap(10, 1) ;
200         LeftHeap h3 = new LeftHeap(8, 0) ;
201         LeftHeap h4 = new LeftHeap(21, 0) ;
202         LeftHeap h5 = new LeftHeap(14, 0) ;
203         LeftHeap h6 = new LeftHeap(17, 0) ;
204         LeftHeap h7 = new LeftHeap(23, 0) ;
205         LeftHeap h8 = new LeftHeap(26, 0) ;
206 
207         h1.left = h2 ;
208         h1.right = h3 ;
209         h2.left = h4 ;
210         h2.right = h5 ;
211         h3.left = h6 ;
212         h5.left = h7 ;
213         h6.left = h8 ;
214 
215         LeftHeap a = h1 ;
216 
217         h1 = new LeftHeap(6,2) ;
218         h2 = new LeftHeap(12,1) ;
219         h3 = new LeftHeap(7,1) ;
220         h4 = new LeftHeap(18,0) ;
221         h5 = new LeftHeap(24,0) ;
222         h6 = new LeftHeap(37,0) ;
223         h7 = new LeftHeap(18,0) ;
224         h8 = new LeftHeap(33,0) ;
225 
226         h1.left = h2 ;
227         h1.right = h3 ;
228         h2.left = h4 ;
229         h2.right = h5 ;
230         h3.left = h6 ;
231         h3.right = h7 ;
232         h5.left = h8 ;
233 
234         LeftHeap b = h1 ;
235 
236         LeftHeap heap = merge_unrec(a , b) ;
237 
238         inOrder(heap) ;*/
239 
240     }
241 }
原文地址:https://www.cnblogs.com/iamzhoug37/p/5559298.html