首页 > 代码库 > 堆排序
堆排序
堆排序
// 测试堆排序 // @start:调整的起点 // @end:调整的终点,在堆排序的过程中,不断地减小调整区间,end参数起作用 void SiftDown(int arr[], int start, int end) { int i = start; int j = 2*i + 1; // j记录的是i结点的左孩子 int temp = arr[i]; while (j <= end) { // (j<end)很巧妙的判断i结点是否有右孩子 if (j < end && arr[j] < arr[j+1]) { ++j; // 如果i结点存在右孩子,并且右孩子大于左孩子 } // 到目前为止,j指向的是i结点中较大的孩子结点 if (temp >= arr[j]) // 如果i结点大于等于孩子结点中较大的,则不需要再调整下去,直接跳出循环 { break; }else { arr[i] = arr[j]; // 否则做调整,把i和j整体下移一层 i = j; j = 2*j +1; } } arr[i] = temp; // 最后i所指向的位置,就是空缺出来的arr[0]该放的位置 } void BuildHeap(int arr[], int n) { // 因为数组是从0开始索引,所以堆的最后一个有孩子的结点位于(n-2)/2处 for (int i = (n-2)/2; i >= 0; --i) { SiftDown(arr, i, n-1); // 在建堆的过程中,调整的右边界始终是数组的最后一个索引值 } } void HeapSort(int arr[], int n) { BuildHeap(arr, n); int temp; for (int i = n-1; i > 0; --i) // 从数组的最后一个索引值开始,到索引为1(数组中的第二个元素) { temp = arr[0]; // 堆顶和i位置交换 arr[0] = arr[i]; arr[i] = temp; // 在这个过程中的调整左边界始终为0,而右边界一直在缩小,因为右边界右面的都是排好序的 SiftDown(arr, 0, i-1); } }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。