#include <iostream>
class Sort
{
public:
Sort();
~Sort();
void BubbleSort(int* nums,int len);
void InsertSort(int* nums, int len);
void SelectionSort(int* nums, int len);
void QuickSort(int* nums, int len,int left,int right);
void HeapSort(int* nums, int len);
void MergeSort(int* nums, int start, int end);
void ShowNums(int* nums, int len);
private:
void max_heap(int nums[], int start, int end);
void Merge(int* nums, int start, int mid, int end);
void swap(int& a, int& b);
};
#include "pch.h"
#include "Sort.h"
Sort::Sort()
{
}
Sort::~Sort()
{
}
//冒泡 时间复杂度:平均:O(N^2) 最好:O(N) 最坏:O(N~2) 稳定性:稳定
void Sort::BubbleSort(int * nums, int len)
{
if (nums == nullptr|| len <= 1)
return;
for (int i = 0; i < len - 1; i++) {
//一趟排序把最大的放到最后了
for (int j = 0; j < len-2-i ; j++) {
if (nums[j] > nums[j+1]) {
swap(nums[j], nums[j+1]);
}
}
}
}
//直接插入排序 时间复杂度:平均:O(N^2) 最好:O(N) 最坏:O(N~2) 稳定性:稳定
void Sort::InsertSort(int * nums, int len)
{
if (nums == nullptr || len <= 1)
return;
for (int i = 0; i < len; i++) {
//当前值往前比较,如果当前值比前面的值大就跳出下面循环,前面都是有序的
for (int j = i; j > 0 && nums[j] < nums[j - 1]; j--) {
swap(nums[j], nums[j - 1]);
}
}
}
//直接选择排序 时间复杂度:平均:O(N^2) 最好:O(N^2) 最坏:O(N~2) 稳定性:不稳定
void Sort::SelectionSort(int * nums, int len)
{
if (nums == nullptr || len <= 1)
return;
for (int i = 0; i < len; i++) {
int index = i;
//每次找到第i个最小的
for (int j = i + 1; j < len; j++) {
if (nums[index] > nums[j]) {
index = j;
}
}
//如果当前不是第i个最小的就交换
if (index != i) {
swap(nums[i], nums[index]);
}
}
}
//快速排序 时间复杂度:平均:O(NlogN) 最好:O(NlogN) 最坏:O(N~2) 稳定性:不稳定
void Sort::QuickSort(int * nums, int len, int left, int right)
{
//left >= right 这个条件容易忘记
if (nums == nullptr || len <= 1 || left >= right)
return;
int key = nums[left];
int i = left;
int j = right;
//一次while循环将比key小的都放在key的左边,比key大的都放在右边
//一次循环后i==j;
while (i < j) {
while (i < j && key <= nums[j]) {
j--;
}
nums[i] = nums[j];
while (i<j && key >= nums[i]) {
i++;
}
nums[j] = nums[i];
}
nums[i] = key;
QuickSort(nums, len, left, i-1);//对key左边的继续排序
QuickSort(nums, len, i + 1, right);//对key右边的继续排序
}
//堆排序 时间复杂度:平均:O(NlogN) 最好:O(NlogN) 最坏:O(NlogN) 稳定性:不稳定
void Sort::HeapSort(int * nums, int len)
{
if (nums == nullptr || len <= 1)
return;
//调整为大顶堆,从最后一个父节点开始
for (int i = len / 2 - 1; i >= 0; i--) {
max_heap(nums, i, len - 1);
}
//先将第一个元素和已经排好的元素前一位做交换,再从新调整(刚调整的元素之前的元素),直到排序完毕
for (int i = len - 1; i > 0; i--) {
swap(nums[0], nums[i]);
max_heap(nums, 0, i-1);
}
}
//归并排序 时间复杂度:平均:O(NlogN) 最好:O(NlogN) 最坏:O(NlogN) 稳定性:稳定
void Sort::MergeSort(int * nums, int start,int end)
{
if (nums == nullptr || start == end)
return;
int mid = start + (end - start) / 2;
MergeSort(nums, start, mid);
MergeSort(nums, mid + 1, end);
//两两合并
Merge(nums, start, mid, end);
}
//构造大顶堆
void Sort::max_heap(int nums[], int start, int end)
{
if (start == end)
return;
int parent = start;
int element = 2 * parent + 1;
while (element <= end) {
//比较左右孩子哪个大
if (element+1 <= end && nums[element] < nums[element+1]) {
element++;
}
//与父节点比较大小,如果比父节点大,交换后则继续对后面的节点进行比较
if (nums[element] > nums[parent]) {
swap(nums[element], nums[parent]);
parent = element;
element = 2 * parent + 1;
}
else {
return;
}
}
}
//合并
void Sort::Merge(int * nums, int start, int mid, int end)
{
//start是第一部分的起点,mid+1是第二部分的起点
int* temp = new int[end - start + 1];
int i = start;
int j = mid + 1;
int index = 0;
//两部分进行排序
while (i <= mid && j <= end) {
if (nums[j] > nums[i]) {
temp[index++] = nums[i++];
}
else {
temp[index++] = nums[j++];
}
}
//如果i这边还有剩下的
while (i <= mid) {
temp[index++] = nums[i++];
}
//如果j这边还有剩下的
while (j <= end) {
temp[index++] = nums[j++];
}
for (int i = 0; i < index; i++) {
nums[start+i] = temp[i];
}
delete[] temp;
}
void Sort::ShowNums(int * nums, int len)
{
if (nums == nullptr || len < 0)
return;
for (int i = 0; i < len; i++) {
std::cout << nums[i] << " ";
}
std::cout << std::endl;
}
void Sort::swap(int & a, int & b)
{
int temp = a;
a = b;
b = temp;
}