堆和优先级队列

来源:互联网 发布:opencv读取caffe 编辑:程序博客网 时间:2024/05/17 23:58

堆的概念:

如果将序列{k1 , k2 , … , kn}对应为一维数组,且序列中元素的下标与数组中下标一致,即数组中下标为 0 的位置不存放数据元素,此时该序列可看成是一颗完全二叉树,则堆的定义说明,在对应的完全二叉树中非终端结点的值均不大于(或不小于)其左右孩子结点的值。


堆排序:

其实感觉画图可以把问题说明,不过我就不画图了。简单的几句话觉得更能说明问题。


第一步,建立堆结构(完全二叉树可以存储到数组中);

第二步,不断的输出堆顶元素,输出后并调整堆的结构,使其重新成为一个堆。


public void heapAdjust(int[] array,int low,int high) {int parentNode = array[low];for (int j=2*low; j<=high; j=j*2){//沿关键之较大的元素向下进行筛选//j 指向关键之较大的元素if (j<high && (array[j] < array[j+1])) //j < high防止没有右子树的情况j++;//若 parentNode 比其孩子都大,那么退出循环if (parentNode >= array[j]) {break;} else {//否则沿着交换的路径继续向下比较array[low] = array[j]; low = j; }}array[low] = parentNode;}public void heapSort() {int[] array = {0,28,26,17,36,20,42,11,53};int n = array.length - 1;//这里为小技巧,i=n/2为一个完全二叉树的最后一个叶子节点的父节点,然后沿逆时针方向倒叙//遍历每一个父节点for (int i=n/2; i>=1; i--) {//4 3 2 1heapAdjust(array,i,n);}for (int i=n; i>1; i--) {//不断输出堆顶元素并调整 array[1..i-1]为新堆int temp = array[1];//交换堆顶与堆底元素array[1] = array[i];array[i] = temp;heapAdjust(array,1,i-1);}for(int i = 0;i<=n;i++)System.out.println(array[i]);}
</pre><pre name="code" class="java">
2,优先级队列,其实堆就是一种特殊的优先级队列。每次取数据的时间复杂度为1(把优先级最高的元素取出),插入元素的过程为把一个元素插入到有序的队列之中(按优先级排序)时间复杂度为log2N。
下面给出了一种插入算法和一种二分查找算法,只要把二分查找变为二分查找后插入就可以了。
</pre><pre name="code" class="java"><pre name="code" class="java">public static void main(String args[]) {int[] array = {1,2,3,4,5,6,7};System.out.println(erfinsert(array,1,0,6));}public void insert(int[] array, int insertData, int reallength) {int i, j;if (insertData < array[0]) {for (i = reallength; i > 0; i--) {array[i] = array[i - 1];}array[i] = insertData;} else if (insertData > array[reallength - 1]) {array[reallength] = insertData;} else {for (i = 0; i < reallength; i++) {if (insertData > array[i] && insertData <= array[i + 1]) {for (j = reallength; j > i; j--) {array[j] = array[j - 1];}array[j] = insertData;break;}}}}public static int erfinsert(int[] arr, int data, int low,int high) {int mid = 0;while(low <= high) {mid = (low + high)/2;if(arr[mid] == data)return mid;else if(arr[mid] > data) {high = mid -1;continue;} else if(arr[mid] < data) {low = mid +1;continue;}}return -1;}

下面补充一个折半插入排序吧:


public void binInsertSort(int[] array, int low, int high) {for (int i = low + 1; i <= high; i++) {int temp = array[i];// 保存待插入元素int hi = i - 1;int lo = low;// 设置初始区间while (lo <= hi) {// 折半确定插入位置int mid = (lo + hi) / 2;if (temp < array[mid])hi = mid - 1;elselo = mid + 1;}for (int j = i - 1; j > hi; j--)array[j + 1] = array[j]; // 移动元素array[hi + 1] = temp;// 插入元素}// for}




0 0
原创粉丝点击