//
// Created by Jayson on 2023/7/30.
//
#include "vector"
using namespace std;
#ifndef DATASTURCTURE_SORTMETHOD_H
#define DATASTURCTURE_SORTMETHOD_H
class sortMethod {
public:
void bubbleSort(vector<int>& A);
void bubbleSortPro(vector<int>& A);
void selectSort(vector<int>& A);
void selectSortPro(vector<int>& A);
void insertSort(vector<int>& A);
void shellSort(vector<int>& A);//希尔排序其实就是插入
void quickSort(vector<int>& A,int lo,int hi);
void merge(vector<int>& A,int lo,int hi,int mid);
void mergeSort(vector<int>& A,int lo,int hi);
void countSort(vector<int>& A);
};
#endif //DATASTURCTURE_SORTMETHOD_H
//
// Created by Jayson on 2023/7/30.
//
#include <iostream>
#include "sortMethod.h"
#include <map>
#include <unordered_map>
using namespace std;
//交换元素,可直接用swap()
void swapElement(int& a,int& b){
int temp = a;
a = b;
b = temp;
}
//冒泡初始版本
void sortMethod::bubbleSort(vector<int> &A) {
int size = A.size();
int flag = size-1;
for(int i = size; i>=1; i--){
int k = 0;
while(k<flag){
if(A[k] > A[k+1]){
swapElement(A[k],A[k+1]);
}
k++;
}
flag--;
}
}
//冒泡改进
void sortMethod::bubbleSortPro(vector<int> &A) {
int flag = A.size()-1;
int temp;
while(temp!=1){
int k = 0;
while(k<flag){
if(A[k] > A[k+1]){
swapElement(A[k],A[k+1]);
temp = k;
}
k++;
}
flag = temp;
}
}
//选择排序初始版本
void sortMethod::selectSort(vector<int> &A){
int maxPos=0;
int flag = A.size()-1;
for(int i = A.size(); i>=1;i--){
int k = 0;
while(k<=flag){
if(A[k]>A[maxPos]){
maxPos = k;
}
k++;
}
swapElement(A[flag],A[maxPos]);
flag--;
}
}
//选择排序改进
void sortMethod::selectSortPro(vector<int> &A){
int maxPos=0;
int minPos=0;
int hi = A.size()-1;
int lo = 0;
while(lo<hi){
int k = lo;
while(k<=hi){
if(A[k]>A[maxPos]){
maxPos = k;
}
if(A[k]<A[minPos]){
minPos = k;
}
k++;
}
swap(A[hi],A[maxPos]);
if(minPos == hi){
minPos = maxPos;
}//这句话很重要
swap(A[lo],A[minPos]);
hi--;
lo++;
minPos = lo;
maxPos = lo;
}
}
//插入排序
void sortMethod::insertSort(vector<int> &A) {
for(int i = 1; i<A.size();i++){
int temp = A[i];
int k = i;
while(temp<A[k-1] && k>0){
A[k] = A[k-1];
k--;
}
A[k] = temp;
}
}
//希尔排序,相当于插入排序的改进
void sortMethod::shellSort(vector<int> &A) {
int stepLength = A.size()/2;
//对增量序列的选择很有讲究,增量序列选择不同,shell排序的性能也不同
//当n在特定范围内,shell排序时间复杂度为O(n^1.3),最坏为O(n^2)
int temp;
while(true){
temp = 0;
while(temp+stepLength<=A.size()){
for(int i = temp+stepLength ; i<A.size(); i+=stepLength){
int flag = i;
int value = A[flag];
while(value<A[flag-stepLength] && (flag-stepLength)>=0){
A[flag] = A[flag-stepLength];
flag = flag - stepLength;
}
A[flag] = value;
}
temp++;
}
stepLength = stepLength/2;
if(stepLength == 0)break;
}
}
//快速排序
void sortMethod::quickSort(vector<int> &A, int lo, int hi) {//大于等于放右边,小于放左边
//我写的代码,操作区间为[lo,hi],左指针初始指向基准元素,也就是第一个
int start = lo;
int end = hi;
int baseNumber = A[lo];
if(hi<lo) return;
while(lo!=hi){
while(A[hi]>=baseNumber && hi>lo)hi--;
if(hi>lo){
A[lo] = A[hi];
lo++;
}
while(A[lo]<baseNumber && hi>lo)lo++;
if(hi>lo){
A[hi] = A[lo];
hi--;
}
}
A[lo] = baseNumber;
quickSort(A,start,lo-1);
quickSort(A,lo+1,end);
return;
}
//归并排序,先分再合
void sortMethod::merge(vector<int> &A, int lo, int hi, int mid) {
int left1 = lo;
int left2 = mid+1;
int newArrayPoint = 0;
int* newArray = new int[hi-lo+1];
while(left1 <=mid && left2 <=hi){
if(A[left1]<A[left2]){
newArray[newArrayPoint] = A[left1];
left1++;
}else{
newArray[newArrayPoint] = A[left2];
left2++;
}
newArrayPoint++;
}
while(left1<=mid){
newArray[newArrayPoint] = A[left1];
newArrayPoint++;
left1++;
}
while(left2<=hi){
newArray[newArrayPoint] = A[left2];
newArrayPoint++;
left2++;
}
int k = 0;
for(int i = lo; i<=hi; i++){
A[i] = newArray[k];
k++;
}
delete newArray;
}
void sortMethod::mergeSort(vector<int> &A, int lo, int hi) {
if(lo>=hi)return;
int mid = (hi+lo)/2;
mergeSort(A,lo,mid);
mergeSort(A,mid+1,hi);
merge(A,lo,hi,mid);
}
//计数排序
void sortMethod::countSort(vector<int> &A) {
map<float,int> m;
for(int i = 0; i<A.size(); i++){
m[A[i]]++;
}
map< float,int>::iterator it;
int temp = 0;
for(it=m.begin();it!=m.end();it++){
while(it->second>0){
A[temp] = it->first;
it->second--;
temp++;
}
}
}
//test
int main(){
vector<int> array = {99,3,2,1,0,5,5,2,1,7,98,-1,-1,-1,-1};
sortMethod* sort;
sort->countSort(array);
for(auto& x : array){
cout<<x<<" ";
}
}