排序知识点小结1-手写堆排序及STL实现

首先是造轮子:

// maximum heap based on integer type
#include <bits/stdc++.h>
using namespace std;
const int MAX_SIZE = 100000;
int heap[MAX_SIZE], result[MAX_SIZE];
int size;
void init(){ 
	memset(heap, 0, sizeof(heap));
	memset(result, 0, sizeof(result));
}
bool is_leaf(int pos){
	return pos > size / 2 - 1; // n/2 - 1 has been proved to be the last branch node in the tree 
}
void swap(int a, int b){
	int temp = heap[a];
	heap[a] = heap[b];
	heap[b] = temp;
}
bool is_legal(int pos){
	return pos <= size - 1;
}
void sift_down(int pos){
	int left, right;
	while(!is_leaf(pos)){
		left = 2 * pos + 1;
		right = 2 * pos + 2;
		if(is_legal(right)){  // node have both left child and right child
			if(heap[pos] < max(heap[left], heap[right])){
				if(heap[left] == max(heap[left], heap[right])){
					swap(pos, left);
					pos = left;
				}
				else{
					swap(pos, right);
					pos = right;
				}
			}
			else{
				break;
			}
		}
		else if(is_legal(left)){  // node just have left child
			if(heap[pos] < heap[left]){
				swap(pos, left);
				pos = left;
			}
			else{
				break;
			}
		}
		else{ // node have no left child or right child
			break;
		}
	}
}
void build_heap(int *arr){
	for(int i = 0 ; i < size ; i++){
		heap[i] = arr[i];
	}
	for(int i = size / 2 - 1 ; i >= 0 ; i--){
		sift_down(i);
	}
}
//when there is just one num in the heap, then for sift_down function, 1 / 2 - 1 = -1; 
int removefirst(){
	int temp = heap[0];
	swap(0, size - 1);
	size--;
	sift_down(0);
	return temp;
}
void heap_sort(int* arr){
	build_heap(arr);
	for(int i = size - 1 ; i >= 0 ; i--)
		result[i] = removefirst();
}
int main(){
	cout << "Enter the size of the list: ";
	cin >> size; // the size of the heap
	int max_size = size;
	init();
	int *a = new int[size];
	cout << "Enter n numbers: ";
	for(int i = 0 ; i < max_size ; i++){
		cin >> 	a[i];
	}
	heap_sort(a);
	for(int i = 0 ; i < max_size ; i++){
		cout << result[i] << " ";
	}
	return 0;
}

吐槽下,shaffer那本书真的有毒,就用来学习下思想,各种边界情况是不会有限制的

但个人挺喜欢里面的函数设计,命名和使用非常清晰易懂

然后是STL实现:

预备知识:STL里面的priority_queue

#include <bits/stdc++.h>
using namespace std;
struct Fish {
	string color;
	int weight;
	Fish() {}
	Fish(string c, int w) {color = c; weight = w;}
	bool operator < (const Fish & f) const {
		return weight > f.weight;
	}
};
//Here, we define the fish with lower weight has supreme privilage 
int main(){
	priority_queue <Fish> q;
	Fish f1("red", 100);
	Fish f2("pink", 140);
	Fish f3("blue", 99);
	q.push(f1);
	q.push(f2);
	q.push(f3);
	Fish temp;
	while(!q.empty()){
		temp = q.top();
		q.pop();
		cout << temp.color << " : " << temp.weight << endl;
	}
	return 0;
}

运行结果:

然后借助这个STL容器的重载可以实现堆排序

#include<bits/stdc++.h>
using namespace std;
int main(){
	priority_queue <int> q;
	int a[10] = {1,3,4,5,6,7,8,9,20,2};
	for(int i = 0 ; i < 10 ; i++){
		q.push(a[i]);
	}
	int temp = 0;
	while(!q.empty()){
		temp = q.top();
		cout << temp << " ";
		q.pop();
	}
	return 0;
}

运行结果:

当然,如果不想使用默认的值大的优先,可以重载如下:

#include<bits/stdc++.h>
using namespace std;
struct Num{
	int num;
	Num(){};
	Num(int n){
		num = n;
	}
	bool operator < (const Num & another) const{
		return num > another.num;
	}
};
int main(){
	priority_queue <Num> q;
	int a[10] = {1,3,4,5,6,7,8,9,20,2};
	for(int i = 0 ; i < 10 ; i++){
		q.push(Num(a[i]));
	}
	Num temp;
	while(!q.empty()){
		temp = q.top();
		cout << temp.num << " ";
		q.pop();
	}
	return 0;
}

输出结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值