排序2:选择排序(选择排序+堆排序)

选择排序,依次找到数据集N、N-1、N-2、....中比它大/小的最大/最小者,最终达到全部数据有序。

1、选择排序:

直接的依次找到数据集合N、N-1、N-2.....的最大/最小者形成排序,非常好理解。选择排序可能是和冒泡排序一样,最直观能想到的排序方法。

显然选择排序和冒泡排序一样,无所谓最好、最坏、平均,选择排序的时间复杂度 = O(N - 1) + O(N - 2) + ...... + O(1) -> O(N * N)

另外很显然选择排序是稳定的排序。

空间复杂度:可以认为几乎没有


select.h(类声明):

#include <iostream>
#include <vector>

template<class T> class selsort {
	std::vector<T> data;
public:
	selsort(T *_data, int size);
	selsort(std::vector<T> _data);
	~selsort(){data.clear();}
	void ssort();
	void show(bool direct);
};
select_func.h(类实现):

#include "select.h"

template<class T> selsort<T>::selsort (T *_data, int size) {
	for (int i = 0; i < size; i++) {
		data.push_back(_data[i]);
	}
	ssort();
}

template<class T> selsort<T>::selsort (std::vector<T> _data) {
	data = _data;
	ssort();
}

template<class T> void selsort<T>::ssort () {
	for (int i = 0; i < data.size() - 1; i++) {
		int min = i;
		for (int j = i + 1; j < data.size() - 1; j++) {
			if (data[j] <= data[min]) {
				min = j;
			}
		}

		T minval = data[min];
		data[min] = data[i];
		data[i] = minval;
	}
}

template<class T> void selsort<T>::show (bool direct) {
	if (direct) {
		for (int i = 0; i < data.size(); i++) {
			std::cout << data[i];
			if (i != data.size() - 1) {
				std::cout << ", ";
			}
		}
	} else {
		for (int i = data.size() - 1; i >= 0; i--) {
			std::cout << data[i];
			if (i != 0) {
				std::cout << ", ";
			}
		}
	}
	std::cout << std::endl;
}
select.cpp(测试程序):
#include "select_func.h"
#include <stdlib.h>


int main () {
	int *testdata = new int[sizeof(int) * 30];
	srand((int)time(0));
	for (int i = 0; i < 30; i++) {
		testdata[i] = rand() % 100;
	}
	selsort<int> selsorter(testdata, 30);
	selsorter.show(1);
	delete []testdata;
	return 0;
}

2、堆排序:

二叉堆本身可参考前面的文章:堆(二叉堆)

堆排序其实过程上和上面的选择排序是一模一样的,只是堆在创建后,堆顶数据已经是当前数据集的最大/小者,然后每次交换堆顶和尚未排序的堆底数据,然后对剩余的数据进行堆排序,这样就依次保证了堆底到堆顶的数据是逐渐排序了的。

因为堆本质是二叉树,所以堆排序比上面的选择排序的最大改进是,每次寻找最大/最小元素的效率由O(X)降低为O(logX),所以堆排序的时间复杂度是O(Nl * ogN),最差、平均、最佳都认为是O(N * logN)。

但是堆排序要考虑创建堆的O(N) + N/2 * O(logN)的时间开销。

堆排序也不稳定,原始排在后面的同值元素,堆排序后可能会在前面。

空间复杂度:可以认为几乎没有


heap.h(类声明):

#include <vector>

template<class T> class heapsort {
	std::vector<T> data;
	int lchild(int i){return i * 2;}
	int rchild(int i){return i * 2 + 1;}
	int parent(int i){return i/2;}
public:
	heapsort(T *data, int size);
	heapsort(std::vector<T> _data);
	~heapsort(){data.clear();}
	void adjust(int i, int size);
	void hsort();
	void show(bool direct);
};
heap_func.h(类定义):
#include "heap.h"
#include <iostream>


template<class T> heapsort<T>::heapsort (T *_data, int size) {
	data.push_back(_data[0]);
	for (int i = 0; i < size; i++) {
		data.push_back(_data[i]);
	}
	for (int i = data.size()/2; i >= 1; i--) {
		adjust(i, data.size() - 1);
	}
}

template<class T> heapsort<T>::heapsort (std::vector<T> _data) {
	data.push_back(_data[0]);
	for (int i = 0; i < _data.size(); i++) {
		data.push_back(_data[i]);
	}
	for (int i = data.size()/2; i >= 1; i--) {
		adjust(i, data.size() - 1);
	}
}

template<class T> void heapsort<T>::adjust (int i, int size) {
	int l = lchild(i), r = rchild(i), maxidx = i;
	if (i <= size/2) {
		if (l < data.size() && data[l] > data[maxidx]) {
			maxidx = l;
		}
		if (r < data.size() && data[r] > data[maxidx]) {
			maxidx = r;
		}

		if (maxidx != i) {
			T ival = data[i];
			data[i] = data[maxidx];
			data[maxidx] = ival;
			adjust(maxidx, size);
		}
	}
}

template<class T> void heapsort<T>::hsort () {
	for (int i = data.size() - 1; i >= 1; i--) {
		T lastval = data[i];
		data[i] = data[1];
		data[1] = lastval;
		adjust(1, i - 1);
	}
}

template<class T> void heapsort<T>::show (bool direct) {
	if (direct) {
		for (int i = 1; i < data.size(); i++) {
			std::cout << data[i];
			if (i != data.size() - 1) {
				std::cout << ", ";
			}
		}
	} else {
		for (int i = data.size() - 1; i >= 1; i--) {
			std::cout << data[i];
			if (i != 1) {
				std::cout << ", ";
			}
		}
	}
	std::cout << std::endl;
}
heap.cpp(测试程序):
#include "heap_func.h"
#include <stdlib.h>


int main () {
	int *testdata = new int[sizeof(int) * 30];
	srand((int)time(0));
	for (int i = 0; i < 30; i++) {
		testdata[i] = rand() % 100;
	}

	heapsort<int> heapsorter(testdata, 30);
	heapsorter.show(1);
	heapsorter.hsort();
	heapsorter.show(1);
	delete []testdata;
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值