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

  1 package tooffer;
  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 }
时间: 2024-08-03 02:03:30

大顶堆第二弹----堆排序(递归实现)的相关文章

堆排序——大根堆(大顶堆)

1.小根堆 若根节点存在左子女则根节点的值小于左子女的值:若根节点存在右子女则根节点的值小于右子女的值. 2.大根堆 若根节点存在左子女则根节点的值大于左子女的值:若根节点存在右子女则根节点的值大于右子女的值. 3.结论 (1)堆是一棵完全二叉树(如果公有h层,那么1~h-1层均满,在h层连续缺失若干个右叶子). (2)小根堆的根节点的值是最小值,大根堆的根节点的值是最大值. (3)堆适合于采用顺序存储. 4.堆的插入算法 将一个数据元素插入到堆中,使之依然成为一个堆. 算法描述:先将结点插入到

heap c++ 操作 大顶堆、小顶堆

在C++中,虽然堆不像 vector, set 之类的有已经实现的数据结构,但是在 algorithm.h 中实现了一些相关的模板函数.下面是一些示例应用 http://www.cplusplus.com/reference/algorithm/pop_heap/ #include <iostream> #include <algorithm> // make_heap(), pop_heap(), push_heap() #include <vector> using

wikioi 2573 大顶堆与小顶堆并用

题目描述 Description 我们使用黑匣子的一个简单模型.它能存放一个整数序列和一个特别的变量i.在初始时刻,黑匣子为空且i等于0.这个黑匣子能执行一系列的命令.有两类命令: ADD(x):把元素x放入黑匣子:GET:把i加1的同时,输出黑匣子内所有整数中第i小的数.牢记第i小的数是当黑匣子中的元素已非降序排序后位于第i位的元素. 下面的表6_4是一个11个命令的例子: 表6_4 编号 命令 i 黑匣子内容 输出 1 ADD(3) 0 3 2 GET 1 3 3 3 ADD(1) 1 1,

wikioi 1052 大顶堆

题目描述 Description 王钢是一名学习成绩优异的学生,在平时的学习中,他总能利用一切时间认真高效地学习,他不但学习刻苦,而且善于经常总结.完善自己的学习方法,所以他总能在每次考试中得到优异的分数,这一切很大程度上是由于他是一个追求效率的人. 但王钢也是一个喜欢玩的人,平时在学校学习他努力克制自己玩,可在星期天他却会抽一定的时间让自己玩一下,他的爸爸妈妈也比较信任他的学习能力和学习习惯,所以在星期天也不会象其他家长一样对他抓紧,而是允许他在星期天上午可以自由支配时间. 地鼠游戏是一项需要

寻找最小的k个数(大顶堆方法)

题目描述:查找最小的k个元素,输入n个整数,输出其中最小的k个. 一般的排序方法,如快排,时间复杂度为O(n*logn+k); 大顶堆方法,时间复杂度为O(k+(n-k)*logk); 如果建立k个元素的最小堆的话,那么其空间复杂度势为O(N),而建立k个元素的最大堆的空间复杂度为O(k); 当面对海量数据处理的时候,大顶堆的方法是较为靠谱的,并且可以在面试时短时间内完成代码. 1 class Solution { 2 public: 3 void Swap(int &a,int &b)

大顶堆(c++实现)

[大顶堆的性质] 大顶堆是一棵完全二叉树,且树中的每个节点的值都不小于它的孩子节点的值.我们可以用一个heap数组来表示它. [大顶堆的插入.删除] 大顶堆的插入:首先初始化插入位置为最后,然后从下往上调整堆(调整插入元素的位置).在调整过程中,若当前节点的父亲节点小于插入元素,则将其父亲节点的值赋给当前节点,父亲节点作为当前节点,依此继续:否则当前节点即为插入位置. 大顶堆的删除:删除根,初始化最后一个元素为新根的值,然后从上往下进行调整堆(调整最后一个元素的位置).在调整的过程中,若最后一个

poj 2010 Moo University - Financial Aid 大顶堆维护最小和

题意: 有c有牛,从中选(n-1)/2头,使他们的得分中位数最大且需要的资金援助和不超过f. 分析: 堆的运用大顶堆维护最小和. 代码: //poj 2010 //sep9 #include <iostream> #include <queue> #include <algorithm> using namespace std; const int maxN=100024; int dpl[maxN],dpr[maxN]; priority_queue<int&g

剑指offer:数据流中的中位数(小顶堆+大顶堆)

1. 题目描述 /** 如何得到一个数据流中的中位数? 如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值. 如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值. 我们使用 Insert()方法读取数据流,使用 GetMedian()方法获取当前读取数据的中位数. */ 2. 思路 /** 最大堆和最小堆 * 每次插入小顶堆的是当前大顶堆中最大的数 * 每次插入大顶堆的是当前小顶堆中最小的数 * 这样保证小顶堆中的数永远大于等于大顶堆中的数(值

python 大顶堆 小顶堆

http://www.coder4.com/archives/3844 需1求:给出N长的序列,求出TopK大的元素,使用小顶堆,heapq模块实现. import heapq import random class TopkHeap(object): def __init__(self, k): self.k = k self.data = [] def Push(self, elem): if len(self.data) < self.k: heapq.heappush(self.data