PAT A1098 Insertion or Heap Sort (思路3:make_heap()等函数用法)

PAT A1098 Insertion or Heap Sort

在这里插入图片描述

Sample Input 1:

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

Sample Output 1:

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

Sample Input 2:

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

Sample Output 2:

Heap Sort
5 4 3 1 0 2 6 7 8 9
wordmeaning
ascendingadj.上升的
  1. 写出模拟插入排序和堆排序1次的函数
  2. 先模拟插入排序,每轮和sorted[]比较,若相等输出
  3. 模拟完插入排序还是没有相等,说明是堆排序,再开始模拟堆排序
  • code 1:
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
const int maxn = 110;
int n, in;
int input[maxn], sorted[maxn], imitate[maxn], heap[maxn];
//Insert: 
void insertSort(int idex){
	insert(1, idex, imitate[idex]);
}
void insert(int left, int right, int x){
	int pos = findPos(left, right, x);
	for(int i = right; i > pos; --i){
		imitate[i] = imitate[i-1];
	}
	imitate[pos] = x;
}
int findPos(int left, int right, int x){
	int mid;
	while(left < right){
		mid = (left + right) / 2;
		if(imitate[mid] < x) left = mid + 1;
		else right = mid;
	}
	return left; 
}
//Heap: 
void downAdjust(int now, int high){
	int v = now, lc = 2*v;
	while(lc <= high){
		if(lc + 1 <= high && heap[lc] < heap[lc+1])
			lc = lc+1; 
		if(heap[v] < heap[lc]){
			swap(heap[v], heap[lc]);
			v = lc;
			lc = 2*v;
		}
		else break;
	}
}
void createHeap(){
	for(int i = n/2; i > 0; --i){
		downAdjust(i, n);
	}
}
void heapSort(int idex){
	swap(heap[1], heap[idex]);
	downAdjust(1, idex-1);
}

bool isEqual();
bool isEqualHeap();
void output();
void outputHeap();

int main(){
	scanf("%d", &n);
	for(int i = 1 ; i <= n; ++i){
		scanf("%d", &input[i]);
		imitate[i] = input[i];
		heap[i] = input[i];
	}
	for(int i = 1 ; i <= n; ++i){
		scanf("%d", &sorted[i]);
	}
	//Insert:
	bool flag = false;
	for(int i = 2; i <= n; ++i){
		insertSort(i);
		if(isEqual()){
			printf("Insertion Sort\n");
			insertSort(i+1);
			output();
		}else{
			flag = true;
		}
	}
	//Heap:
	if(flag){
		createHeap();
		for(int i = n; i > 0; --i){
			heapSort(i);
			if(isEqualHeap()){
				printf("Heap Sort\n");
				heapSort(i-1);
				outputHeap();
				break;
			}
		}
	}
	return 0;
} 
//判断和输出 
bool isEqual(){
	for(int i = 1; i <= n; ++i){
		if(imitate[i] != sorted[i]) return false;
	}
	return true;
} 
bool isEqualHeap(){
	for(int i = 1; i <= n; ++i){
		if(heap[i] != sorted[i]) return false;
	}
	return true;
} 
void output(){
	printf("%d", imitate[1]);
	for(int i = 2; i <= n; ++i) 	printf(" %d", imitate[i]);
}
void outputHeap(){
	printf("%d", heap[1]);
	for(int i = 2; i <= n; ++i) 	printf(" %d", heap[i]);
}
  • 思路 2:
    插入排序部分可以用sort(a, a+i+1)代替

  • code 2:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 110;
int n, in;
bool flag = false;
int input[maxn], sorted[maxn], imitate[maxn];
void downAdjust(int, int);
void createHeap();
void heapSort(int);
bool isEqual();
void output();
void isInsert();
void isHeap();
int main(){
	scanf("%d", &n);
	for(int i = 1 ; i <= n; ++i){
		scanf("%d", &input[i]);
		imitate[i] = input[i];
	}
	for(int i = 1 ; i <= n; ++i){
		scanf("%d", &sorted[i]);
	}
	isInsert();
	isHeap();
	return 0;
} 
void downAdjust(int now, int high){
	int v = now, lc = 2*v;
	while(lc <= high){
		if(lc + 1 <= high && imitate[lc] < imitate[lc+1])
			lc = lc+1; 
		if(imitate[v] < imitate[lc]){
			swap(imitate[v], imitate[lc]);
			v = lc;
			lc = 2*v;
		}
		else break;
	}
}
void createHeap(){
	for(int i = n/2; i > 0; --i){
		downAdjust(i, n);
	}
}
void heapSort(int idex){
	swap(imitate[1], imitate[idex]);
	downAdjust(1, idex-1);
}
void isInsert(){
	for(int i = 2; i <= n; ++i){
		sort(imitate+1, imitate+i+1);
		if(isEqual()){
			printf("Insertion Sort\n");
			sort(imitate+1, imitate+i+2);
			output();
		}else{
			flag = true;
		}
	}
}
void isHeap(){
	if(flag){
		for(int i = 1 ; i <= n; ++i){
			imitate[i] = input[i];
		}
		createHeap();
		for(int i = n; i > 0; --i){
			heapSort(i);
			if(isEqual()){
				printf("Heap Sort\n");
				heapSort(i-1);
				output();
				break;
			}
		}
	}
}
//判断和输出 
bool isEqual(){
	for(int i = 1; i <= n; ++i){
		if(imitate[i] != sorted[i]) return false;
	}
	return true;
} 
void output(){
	printf("%d", imitate[1]);
	for(int i = 2; i <= n; ++i) 	printf(" %d", imitate[i]);
}
  • T2 code:
#include <bits/stdc++.h>
using namespace std;

//void UpAdjust(vector<int> & test, int id){	//建好堆以后,Insert才用UpAdjust() 
//	while(id != 1 && test[id] > test[id / 2]){
//		swap(test[id], test[id / 2]);
//		id /= 2;
//	}
//}
void DownAdjust(vector<int> & test, int id, int right){
	int i = id, j = 2 * id;
	while(j <= right){
		if(j + 1 <= right && test[j + 1] > test[j]) j++;
		if(test[i] < test[j]){
			swap(test[i], test[j]);
			i = j;
			j = 2 * i;
		}else break;
	}
}
void BuildHeap(vector<int> & test, int right){
	for(int i = right / 2; i > 0; --i){
		DownAdjust(test, i, right);
	} 
}
void Print(vector<int> & ans){
	for(int i = 1; i < ans.size(); ++i){
		printf("%d", ans[i]);
		if(i < ans.size()-1) printf(" ");
	}
}
bool IsHeap(vector<int> test, vector<int> & aim){
	BuildHeap(test, test.size()-1);
	for(int i = 1; i < test.size(); ++i){
		int right = test.size() - i;
		swap(test[1], test[right]);
		DownAdjust(test, 1, right-1);
		if(test == aim){
			swap(aim[1], aim[right - 1]);
			DownAdjust(aim, 1, right - 2);
			return true;
		}
	}
	return false;	//Wrong 1: 不写return false就会出错 
}
void Insert(vector<int> & test, int id){
	test[0] = test[id];	//哨兵
	while(test[id-1] > test[0]){
		test[id] = test[id-1];
		id--;
	}
	test[id] = test[0];
	test[0] = 0;	//否则 test == aim 会出错,aim[0] == 0 
}
void InsertSort(vector<int> test, vector<int> & aim){
	for(int i = 2; i < test.size() - 1; ++i){
		Insert(test, i);		
		if(test == aim){
			Insert(test, i + 1);
			printf("Insertion Sort\n");
			Print(test);
			return;
		}
	}
}
int main(){
	int n;
	scanf("%d", &n);
	vector<int> initial(n+1), ans(n+1);
	for(int i = 1; i <= n; ++i){
		scanf("%d", &initial[i]);
	}
	for(int i = 1; i <= n; ++i){
		scanf("%d", &ans[i]);
	}
	if(IsHeap(initial, ans)){
		printf("Heap Sort\n");
		Print(ans);
	}else{
		InsertSort(initial, ans); 
	}
	return 0;
}
  • 思路3:用 heap的库函数 is_heap(), make_heap(), pop_heap(), push_heap(), sort_heap();

  • Algorithm中的heap函数

函数函数原型作用
is_heap()bool is_heap( RandomIt first, RandomIt last, Compare comp);判断区间是否为heap
is_heap_until()RandomIt is_heap_until( RandomIt first, RandomIt last, Compare comp );找出区间中第一个不满足heap条件的位置.
make_heap()make_heap( RandomIt first, RandomIt last, Compare comp);在指定区间建堆
push_haep()void push_heap( RandomIt first, RandomIt last, Compare comp );把指定区间的最后一个元素插入到heap中
pop_heap()void pop_heap( RandomIt first, RandomIt last, Compare comp );弹出heap顶元素, 将其放置于区间末尾.
sort_heap()void sort_heap( RandomIt first, RandomIt last, Compare comp );堆排序,make_heap后反复调用pop_heap来实现

【注】cmp:less<int>()是默认的大顶堆(Max Heap), greater<>() 小顶堆

  • T2 code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 110;
bool IsHeap(vector<int> t, vector<int> & aim){
	make_heap(t.begin(), t.end(), less<int>());
	for( int i = 0; i < t.size() - 1; ++i){
		pop_heap(t.begin(), t.end() - i, less<int>());
		if(t == aim){
			pop_heap(aim.begin(), aim.end() - i - 1, less<int>());
			return true;
		}
	}
	return false;
}
void Insert(vector<int> t, vector<int> & aim){
	for(int i = 2; i < t.size() - 1; ++i){	//Wrong 1: 样例2: i要从2开始,因为不包括初始序列  
		sort(t.begin(), t.begin() + i);
		if(t == aim){
			sort(aim.begin(), aim.begin() + i + 1);
			return;
		}
	}
}
void Print(vector<int> ans){
	for(int i = 0; i < ans.size(); ++i){
			printf("%d", ans[i]);
			if(i < ans.size() - 1) printf(" ");
	}
}
int main(){
	int n;
	scanf("%d", &n);
	vector<int> initial(n), ans(n);
	for(int i = 0; i < n; ++i){
		scanf("%d", &initial[i]);
	}
	for(int i = 0; i < n; ++i){
		scanf("%d", &ans[i]);
	}
	if(IsHeap(initial, ans)){
		printf("Heap Sort\n");
		Print(ans);
	}else{
		Insert(initial, ans);
		printf("Insertion Sort\n");
		Print(ans);
	}
	return 0;
}

  • Wrong 1: 样例2: i要从2开始,因为不包括初始序列

  • T3 code:

#include <bits/stdc++.h>
using namespace std;
void Print(const vector<int> & v)
{
    for(int i = 1; i < v.size(); ++i)
    {
        printf("%d", v[i]);
        if(i < v.size()-1) printf(" ");
    }
    printf("\n");
}
void Insert(vector<int> & ori, int id, int n)
{
    ori[0] = ori[id];
    int idex = id;
    while(ori[idex-1] > ori[0])
    {
        ori[idex] = ori[idex-1];
        idex--;
    }
    swap(ori[idex], ori[0]);
    ori[0] = 0;
}
bool InsertSort(vector<int> ori, vector<int> & aim, int n)
{
    for(int i = 2; i < n; ++i)
    {
        Insert(ori, i, n);
        if(ori == aim)
        {
            Insert(aim, i + 1, n);
            return true;
        }
    }
    return false;
}

void DownAdjust(vector<int> & ori, int now, int n)
{
    int v = now, lc = 2 * now;
    while(lc <= n)
    {
        if(lc + 1 <= n && ori[lc+1] > ori[lc]) lc = lc + 1;
        if(ori[lc] > ori[v])
        {
            swap(ori[lc], ori[v]);
            v = lc;
            lc = v * 2;
        }else break;
    }
}
void MakeHeap(vector<int> & ori, int n)
{
    for(int i = n / 2; i > 0; --i)
    {
        DownAdjust(ori, i, n);
    }
}
void HeapSort(vector<int> & ori, vector<int> aim, int n)
{
    MakeHeap(ori, n);
    bool flg = false;
    for(int i = n; i > 0; --i)
    {
        if(ori == aim) flg = true;
        swap(ori[i], ori[1]);
        DownAdjust(ori, 1, i-1);
        if(flg) break;
    }
}
int main()
{
    int n;
    scanf("%d", &n);
    vector<int> ori(n+1), aim(n+1);
    for(int i = 1; i <= n; ++i)
    {
        scanf("%d", &ori[i]);
    }
    for(int i = 1; i <= n; ++i)
    {
        scanf("%d", &aim[i]);
    }
    if(InsertSort(ori, aim, n))
    {
        printf("Insertion Sort\n");
        Print(aim);
    }else
    {
        HeapSort(ori, aim, n);
        printf("Heap Sort\n");
        Print(ori);
    }
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值