大顶堆第二弹----堆排序(递归实现)

  1 package com.datastruct;
  2 
  3 import java.util.ArrayList;
  4 import java.util.Arrays;
  5 
  6 public class BigHeap {
  7     
  8     
  9     
 10     /*
 11      *交换堆中的两个元素 
 12      */
 13     private void swap(ArrayList<Integer> heapList,int srcIndex,int dstIndex)
 14     {
 15         int tmp = heapList.get(srcIndex);
 16         
 17         heapList.set(srcIndex,heapList.get(dstIndex));
 18         heapList.set(dstIndex, tmp);
 19         
 20     }
 21     
 22     /*
 23      *将指定元素的位置进行上移操作 
 24      */
 25     private void HeapUp(ArrayList<Integer> heapList,int index)
 26     {
 27                 
 28         if(index > 1)
 29         {
 30             int parent = index / 2;
 31             int parentVal = heapList.get(parent).intValue();
 32             int indexVal =  heapList.get(index).intValue();
 33             
 34             if(indexVal > parentVal)
 35             {
 36                 swap(heapList,parent,index);
 37                 HeapUp(heapList,parent);
 38             }
 39             
 40         }
 41     }
 42     
 43     /*
 44      *将指定元素的位置进行下移操作 
 45      */
 46     private void HeapDown(ArrayList<Integer> heapList,int index)
 47     {
 48         int heapSize = heapList.size(); //这里进行了重复的计算,可以将作为形参传入,或者将该函数,写成非递归形式
 49         
 50         if(index > heapSize - 1)
 51         {//节点不存在
 52             return;
 53         }
 54         
 55         int child = index * 2; //左孩子节点
 56         
 57         if(child > (heapSize - 2))
 58         {//当前节点为叶子节点,不能进行下移操作,直接返回
 59          //-2是由于最后一个元素已经是要删除的节点,不在计算范围之内
 60             return;
 61         }
 62         else if(child < heapSize - 2) 
 63         {//有两个孩子节点
 64              if(heapList.get(child).intValue() < heapList.get(child + 1).intValue())
 65              {
 66                  child++; //右孩子结点值大,作为新的父节点
 67              }
 68         }
 69         
 70         if(heapList.get(child).intValue() > heapList.get(index).intValue())
 71         {//孩子节点的值大,进行下移
 72             swap(heapList,child, index);
 73             HeapDown(heapList,child);//继续进行下移操作
 74         }
 75         
 76     }
 77     
 78     /*
 79      *向大顶堆中插入一个元素
 80      */
 81     public void HeapInsert(ArrayList<Integer> heapList,int value)
 82     {
 83         int heapSize = heapList.size();
 84         
 85         if(heapSize == 0)
 86         {//第一个元素不为堆中的元素,跳过
 87             heapList.add(-100);
 88         }
 89         
 90         heapList.add(value);
 91         heapSize++; //添加新元素后,改变堆的大小
 92         
 93         HeapUp(heapList,heapSize - 1);
 94     }
 95     
 96     /*
 97      *从大顶堆中删除一个元素 
 98      */
 99     public void HeapDelete(ArrayList<Integer> heapList,int value)
100     {
101         int index = 1,heapSize = heapList.size();
102         for(; index < heapSize; index++)
103         {
104             if(heapList.get(index).intValue() == value)
105             {
106                 break;
107             }
108         }
109         
110         if (index >= heapSize)
111         {//元素不存在
112             return;
113         }
114         
115         heapList.set(index, heapList.get(heapSize-1)); //将最后一个叶子节点值赋值到当前节点
116         HeapDown(heapList,index); 
117         
118         int parent = index / 2;
119         
120         if(parent > 0 && ( heapList.get(index).intValue() > (Integer)heapList.get(parent).intValue() ))
121         {//如果下移操作后该元素大于父节点还要进行上移
122             HeapUp(heapList,index);
123         }
124         
125         heapList.remove(heapSize - 1);
126     }
127     
128     /*
129      *调整堆结构    
130      */
131     public void heapAdjust(ArrayList<Integer>heapList,int index,int end)
132     {
133         int child = -1,heapSize = heapList.size();
134         
135         end = end > heapSize - 1 ? heapSize - 1 : end; //确保结束正确
136         
137         while(index <= end / 2)
138         {//只需调整非叶子节点
139             child = index * 2; //左孩子节点
140             if(child + 1 <= end && (heapList.get(child+1).intValue() > heapList.get(child).intValue()) )
141             {
142                 child += 1; //右孩子节点值大右孩子节点上移
143             }
144             
145             if(heapList.get(child).intValue() > heapList.get(index).intValue())
146             {
147                 swap(heapList, child, index);
148                 index = child;
149             }
150             else
151             {
152                 break;
153             }
154         }
155     }
156     
157     
158     /*
159      * 初始化时调整堆结构
160      * 由于堆是完全二叉树结构,所以只有前一半节点是非叶子节点
161      */
162     public void heapInitAdjust(ArrayList<Integer> heapList)
163     {
164         int heapSize = heapList.size();
165         
166         for(int i = heapSize / 2; i > 0; i--)
167         {
168             heapAdjust(heapList, i, heapSize - 1);
169         }    
170         
171     }
172     
173     /*
174      * 堆排序
175      * 将大顶堆堆顶元素和最后一个元素交换,调整剩下元素的对结构
176      * 直到调整到最后一个元素就排好序
177      */
178     public void heapSort(ArrayList<Integer>heapList)
179     {
180         int heapSize = heapList.size();
181         
182         for(int i = heapSize - 1; i > 0; i--)
183         {
184             swap(heapList, 1, i); //交换堆顶和最后一个元素
185             heapAdjust(heapList, 1, i - 1);
186         }
187     }
188     
189     /*
190      *  打印堆元素
191      */
192     public void PrintHeap(ArrayList<Integer> heapList)
193     {
194         for(int i = 1; i < heapList.size(); i++)
195         {
196             System.out.print(heapList.get(i) + " ");
197         }
198         
199         System.out.println();
200     }
201     
202     
203     
204     public static void main(String args[])
205     {
206         ArrayList<Integer> heapList = new ArrayList<>(Arrays.asList(null,1,3,4,5,8,2,7));
207         
208         BigHeap bigHeap = new BigHeap();
209         
210         bigHeap.heapInitAdjust(heapList);
211         bigHeap.PrintHeap(heapList);
212         
213         bigHeap.HeapInsert(heapList, 6);
214         bigHeap.PrintHeap(heapList);
215         
216         bigHeap.heapSort(heapList);
217         bigHeap.PrintHeap(heapList);
218     }
219 }
原文地址:https://www.cnblogs.com/daimadebanyungong/p/4971896.html