1. 程式人生 > >PAT-ADVANCED1098——Insertion or Heap Sort

PAT-ADVANCED1098——Insertion or Heap Sort

題目描述:

題目翻譯:

1098 插入排序與堆排序

根據維基百科的定義如下:

插入排序迭代,每次重複消耗一個輸入元素,並生成排序的輸出列表。 每次迭代,插入排序都會從輸入資料中刪除一個元素,在排序列表中找到它所屬的位置,然後將其插入到那裡。 它重複直到沒有輸入元素。

堆排序將其輸入劃分為排序和未排序區域,並通過提取最大元素並將其移動到排序區域來迭代縮小未排序區域。 它涉及使用堆資料結構而不是線性時間搜尋來找到最大值。

現在給出初始的整數序列,以及一些序列,這是一些排序方法的幾次迭代的結果,你能告訴我們正在使用哪種排序方法嗎?

輸入格式:

每個輸入檔案包含一個測試用例。在每個測試用例中,第一行給出一個正整數N(<= 100)。接下來的一行給出N個整數,作為初始序列。最後一行給出N個整數,代表某排序演算法的中間序列。假設目標序列是升序。 一行中的所有數字都由一個空格分隔。

輸出格式:

對每個測試用例,在第一行輸出“Insertion Sort”或“Heap Sort”來說明產生該中間序列所使用的排序演算法。然後再執行此演算法一次迭代,並在第二行輸出結果序列。 保證每個測試用例的答案都是唯一的。 一行中的所有數字必須用空格分隔,並且行尾必須沒有多餘的空格。

輸入樣例1:

10
3 1 2 8 7 5 9 4 6 0
1 2 3 7 8 5 9 4 6 0

輸出樣例1:

Insertion Sort
1 2 3 5 7 8 9 4 6 0

輸入樣例2:

10
3 1 2 8 7 5 9 4 6 0
6 4 5 1 0 3 2 7 8 9

輸出樣例2:

Heap Sort
5 4 3 1 0 2 6 7 8 9

知識點:插入排序、堆排序

思路:先判斷是否是插入排序,再分別進行下一步操作

(1)如果是插入排序,尋找到已經排好序的前k - 1個元素,對第k個元素進行插入排序。

(2)如果是堆排序,尋找到位置k,使得k + 1之後的元素已經排好序。對[0, k]範圍內的元素,先交換0和k位置的值,再對[0, k - 1]範圍內的堆頂元素,即0位置的元素進下沉操作。

如果是插入排序,時間複雜度是O(N)。而如果是堆排序,由於我們需要一個雙重迴圈來尋找位置k,因此時間複雜度是O(N ^ 2)。空間複雜度均是O(1)。

C++程式碼:

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

int N;
vector<int> input1;
vector<int> input2;

bool isInsertionSort();
void nextInsertionSort();
void nextHeapSort();
void print();

int main() {
	cin >> N;
	int num;
	for(int i = 0; i < N; i++) {
		cin >> num;
		input1.push_back(num);
	}
	for(int i = 0; i < N; i++) {
		cin >> num;
		input2.push_back(num);
	}
	if(isInsertionSort()) {
		cout << "Insertion Sort" << endl;
		nextInsertionSort();
	} else {
		cout << "Heap Sort" << endl;
		nextHeapSort();
	}
	print();
	return 0;
}

bool isInsertionSort() {
	int k = 0;
	for(int i = 0; i < N - 1; i++) {
		if(input2[i] > input2[i + 1]) {
			k = i + 1;
			break;
		}
	}
	for(int i = k; i < N; i++) {
		if(input1[i] != input2[i]) {
			return false;
		}
	}
	return true;
}

void nextInsertionSort() {
	int k = 0;
	for(int i = 0; i < N - 1; i++) {
		if(input2[i] > input2[i + 1]) {
			k = i + 1;
			break;
		}
	}
	int j = k - 1;
	int temp = input2[k];
	for(; input2[j] > temp; j--) {
		input2[j + 1] = input2[j];
	}
	input2[j + 1] = temp;
}

void nextHeapSort() {
	int k;
	for(int i = N - 1; i >= 0; i--) {
		bool flag = true;
		for(int j = 0; j < i; j++) {
			if(input2[j] > input2[i]) {
				flag = false;
			}
		}
		if(!flag) {
			k = i;
			break;
		}
	}
	swap(input2[0], input2[k]);
	int i = 0;
	int j = 2 * i + 1;
	while(j <= k - 1) {
		if(j + 1 <= k - 1 && input2[j + 1] > input2[j]) {
			j = j + 1;
		}
		if(input2[j] > input2[i]) {
			swap(input2[i], input2[j]);
			i = j;
			j = 2 * i + 1;
		}else{
			break;
		}
	}
}

void print() {
	for(int i = 0; i < input2.size(); i++) {
		cout << input2[i];
		if(i != input2.size() - 1) {
			cout << " ";
		}
	}
	cout << endl;
}

C++解題報告: