您的位置:首页 > 理论基础 > 数据结构算法

09-排序3 Insertion or Heap Sort (25分)

2016-10-29 01:55 253 查看
这道题跟上一道很相似,不同的地方在于Heap Sort的处理。

1. 找到下一个要和根节点交换(堆排序)的元素的下标。

2. 利用“下滤”,做一次堆排序。

#include <iostream>
#include <algorithm>
using namespace std;

bool isHeapSort(int *init, int *arr, int n);
int getNextHeapSortIndex(int *arr, int n);
void heapSortOnce(int *arr, int index);

int main(void) {
int n;
cin >> n;
int *init = new int
;
int *arr = new int
;
for(int i = 0; i < n; ++i)
cin >> init[i];
for(int i = 0; i < n; ++i)
cin >> arr[i];

if(isHeapSort(init, arr, n)) {
cout << "Heap Sort" << endl;
heapSortOnce(arr, getNextHeapSortIndex(arr, n));
} else
cout << "Insertion Sort" << endl;

cout << arr[0];
for(int i = 1; i < n; ++i)
cout << " " << arr[i];

delete[] init;
delete[] arr;
return 0;
}

/*
* 1. 从前面找第一个反序的元素索引 -> 有序子列元素个数。
* 2. 判断从该索引开始,是否与原始数列一致。若一致,是插入排序。
*/
bool isHeapSort(int *init, int *arr, int n) {
int len = 1; //记录插入排序中,有序子列的个数。
for(int i = 0; i < n - 1; ++i) {
if(arr[i] > arr[i + 1]) {
len = i + 1;
break;
}
}

for(int i = len; i < n; ++i)
if(arr[i] != init[i]) return true;

sort(arr, arr + len + 1); //若是插入排序,直接在这里完成下一趟插入。
return false;
}

//返回下一次进行堆排序操作的元素的下标。
int getNextHeapSortIndex(int *arr, int n) {
int heap = arr[0];
for(int i = 1; i < n; ++i) {
if(arr[i] > heap) return i - 1;
}
return n - 1; //最大堆,未排序。
}

void heapSortOnce(int *arr, int index) {
swap(arr[0], arr[index]);
int size = index - 1;
//下滤。
int tmp = arr[0];
int parent = 0;
int child;
for(; parent*2 + 1 <= size; parent = child) {
child = parent * 2 + 1;
if(child < size && arr[child] < arr[child + 1]) ++child;

if(tmp > arr[child]) break;
else arr[parent] = arr[child];
}
arr[parent] = tmp;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息