堆排序(heap sort)
2016-09-28 17:43
351 查看
堆排序
概述
对简单排序的一种改进堆是具有下列性质的完全二叉树:
每个节点的值都大于或等于其左右孩子结点的值,称为大顶堆;
每个节点的值都小于或等于其左右孩子结点的值,称为小顶堆。
堆排序算法思想:
将待排序的列表,构造成一个大顶堆。最大值就是堆顶的根结点,将其移去(其实就是将第一个元素与最后一个元素对调,最后一个元素就是最大值),然后再对剩下的n-1个元素组成的序列从新排序成大顶堆。如此重复,就能得到一个有序序列。循环方式实现代码
/*堆调整函数,注意我们对于顺序表sqlist默认是第一个元素不用 * 调整顺序表sqList在s与其左右子树的 序列,m是堆的长度 * */ public void heapAdjust(int sqList[],int s,int m){ int temp = sqList[s]; for (int i = 2*s ; i <= m; i*=2) {//沿着关键字大的向下筛选 if (sqList[i]<sqList[i+1] && i<m) { i++;//j为记录关键字较大的下标 } if (sqList[i] <= temp) { break ;//已经满足堆排序条件,直接跳出 } sqList[s] = sqList[i]; s = i ; } sqList[s] = temp; } /*对顺序表sqlsit进行多排序*/ public void heapSort(int sqList[]){ //首先对顺序表改成一个大堆顶 for (int i = sqList.length/2; i > 0; i--) { heapAdjust(sqList, i,sqList.length); } for (int i = sqList.length; i > 1 ; i--) { swap(sqList,1,i);//将最大的一个换到后边 heapAdjust(sqList, 1,i-1);//对除了已经排好序的记录进行堆调整 } }
递归方式实现代码
/************************ * 大顶堆排序,堆为A[1...length],不用A[0] **************************/ public int parent(int i) { return i / 2; } public int leftChild(int i) { return 2 * i; } public int rightChild(int i) { return 2 * i + 1; } /* * 用递归的思想实现堆调整 * * @param sqList 是待调整的顺序表 * * @param i 是需要调整元素的索引 * * @param length 堆的长度 */ public void heapAdjust(int[] sqList, int i, int length) { int l = leftChild(i); int r = rightChild(i); int largest = i;// 最大值的索引 // 通过两次比较,从根和他的左右孩子之间找出最大值的索引 if (l <= length && sqList[i] < sqList[l]) { largest = l; } if ( r <= length && sqList[largest] < sqList[r] ) { largest = r; } // 将sqlist[largest]和sqlist[i]交换 if (largest != i) { swap(sqList, i, largest); // 由于sqlist[largest]和sqlist[i]交换, // 可能造成sqlist不在满足大顶堆性质,所以要调整 heapAdjust(sqList, largest, length); } //如果largest==i则已经满足大顶堆条件,就不需要做任何操作。 } // 建堆 // 由于我们不用sqlist[0],所以堆长度为length-1 public void buildHeap(int[] sqList) { for (int i = (sqList.length-1) / 2; i > 0; i--) { heapAdjust(sqList, i, (sqList.length-1)); } } // 堆排序 // 堆的长度为length-1 public void heapSort(int[] sqList) { buildHeap(sqList); for (int i = (sqList.length-1); i >= 2; i--) { swap(sqList, 1, i);// 将根结点换到后边 heapAdjust(sqList, 1, i - 1);// 堆调整 } } public void swap(int array[], int i, int j) { int temp = array[i]; array[i] = array[j]; array[j] = temp; }
堆排序时间复杂度
堆调整的时间复杂度为O(logi)构建堆需要n-1次堆调整,所以构建堆时间复杂度为O(nlogn)
堆排序需要一次堆构,n-1次交换和n-1次堆调整。所以堆排序的时间复杂度为O(nlogn)
相关文章推荐
- C++、C#、java算法学习日记06----堆排序思想(HeapSort)
- 堆排序 (Heap sort)
- 堆排序 heapsort(大根堆) c++
- 选择排序(2)——堆排序(heap sort)
- 堆排序 Heap Sort
- heapsort堆排序(3种语言实现 c/java/python)
- 堆排序 HeapSort
- 堆排序(Heap Sort)原理及Java实现
- 堆排序(Heapsort)
- 第六章 堆排序(heapsort)
- 堆排序 HeapSort
- Java排序算法--堆排序(HeapSort)
- 排序——堆排序(HeapSort)
- 堆排序 Heap Sort
- [Java--常见排序算法]--堆排序 (Heap Sort)
- 堆排序(1)HeapSort
- 堆排序(HeapSort)
- 算法导论------堆排序heapsort
- 堆排序 HeapSort
- Atitit 算法之道 attilax著 1. 第二部分(Part II) 排序与顺序统计(Sorting and Order Statistics) 1 2. 第六章 堆排序(Heapsort)