1.冒泡排序
#include "bubblesort.h"
bool compare(const int &a , const int &b)
{
return a < b;
}
// 暴力冒泡:效率低下,交换
void bubbleSort0(vector<int> &a)
{
for(int k=0;k<10000;++k)
{
int len = a.size();
for(int i=0;i<len-1;++i)
{
for(int j =i+1;j<len;++j)
{
if(a[i]>a[j])
{
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}
}
// 正常冒泡:两两交换
void bubbleSort1(vector<int> &a)
{
for(int k=0;k<10000;++k)
{
int len = a.size();
for(int i=0;i<len;++i)
{
for(int j = len-2;j>=i;--j)
{
if(a[j]>a[j+1])
{
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
}
}
// 改进冒泡:设置flag;一次交换都没发生,表明已经有序,此时退出循环
void bubbleSort2(vector<int> &a)
{
for(int k=0;k<10000;++k)
{
int len = a.size();
bool flag = true;
for(int i=0;i<len && flag;++i)
{
flag = false;
for(int j = len-2;j>=i;--j)
{
if(a[j]>a[j+1])
{
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
flag = true;
}
}
}
}
}
2.选择排序
#include "selectsort.h"
void SelecSort(vector<int> &a)
{
int len = a.size();
for(int i=0;i<len-1;++i)
{
int min = i;
// 找出这一轮的最小值的下标
for(int j=i+1;j<len;++j)
{
if(a[min]>a[j])
min = j;
}
// 最小值放在i这个位置
if(min!=i)
{
int temp = a[i];
a[i] = a[min];
a[min] = temp;
}
}
}
3.插入排序
#include "insertsort.h"
void InsertSort(vector<int> &a)
{
for(int k=0;k<10000;++k)
{
int len = a.size();
for(int i=1;i<len;++i)
{
if(a[i]<a[i-1])
{
// 在i的左边,将大于a[i]的右移一位
// 设置哨兵的方法
int temp = a[i];
int j=i-1;
for(;j>=0 && a[j] > temp;--j)
a[j+1] = a[j];
a[j+1] = temp;
// 上述思路的我的实现
// for(int j=i-1;j>=0;--j)
// {
// if(a[j+1]<a[j])
// swap(a[j],a[j+1]);
// else
// break;
// }
}
}
}
}
4.希尔排序
#include "shellsort.h"
void shellsort(vector<int> &a)
{
for(int k=0;k<10000;++k)
{
int len = a.size();
int increment = len;
do
{
increment = increment/3 +1;
for(int i= increment;i<len;++i)
{
//方法一:我的交换法
for(int j = i;j>=increment;j=j-increment)
{
if(a[j]<a[j-increment])
swap(a[j],a[j-increment]);
else
break;
}
// // 方法二:哨兵法,和插入排序类似
// int temp = a[i];
// int j = i-increment;
// for(;j>=0 && a[j]>temp;j=j-increment)
// a[j+increment] = a[j];
// a[j+increment] = temp;
}
}while(increment>1);
}
}
5.堆排序
#include "heapsort.h"
void HeapSort(vector<int> &a)
{
for(int k=0;k<10000;++k)
{
// 构造一个大顶堆,n/2个非叶子节点
int i = a.size()/2;
for(;i>0;--i)
HeapAdjust(a,i,a.size());
for(i=a.size();i>1;--i)
{
// 大顶堆,a[0]是最大值,将其换到末尾去,然后a[i-1]值从大顶堆中去除
swap(a[0],a[i-1]);
// 从a[0]到a[i-2]再重新构建大顶堆,
// 1表示大顶堆中的根节点,对应数组a[0];i-1对应最后一个叶子节点,对应a[i-2],
HeapAdjust(a,1,i-1);
}
}
}
// 构造大顶堆,有很多-1是因为数组下标从0开始。
// j表示其在完全二叉树中的按层遍历的位置,2j是左孩子,2j+1是右孩子,所以j的值最好不变
void HeapAdjust(vector<int> &a ,int s,int m)
{
int temp = a[s-1];
int j = 2*s;
// 一直向下交换根
for(;j<=m;j*=2)
{
// j=m说明没有右孩子
if(j<m && a[j-1]<a[j+1-1])
++j;
// 根已经大于左右孩子
if(temp>=a[j-1])
break;
a[s-1] = a[j-1];
s = j;
}
a[s-1] = temp;
}
6.归并排序
#include "mergesort.h"
void MergeSort(vector<int> &a)
{
for(int k =0;k<10000;++k)
Msort(a,0,a.size()-1);
}
void Msort(vector<int> &a , int left , int right)
{
if(left < right)
{
int m = left+(right-left)/2;
Msort(a,left,m);
Msort(a,m+1,right);
//将左右两块排好序的,再归并一下,变成一个有序的
Merge(a,left,m,right);
}
}
void Merge(vector<int> &a ,int left, int m, int right)
{
// 上述有递归过程,b的大小应为每次递归的对应容量
vector<int> b(right-left+1,0);
int i = left;
int j = m+1;
int k = 0;
for(;i<=m && j<=right ; ++k)
{
if(a[i] < a[j])
b[k] = a[i++];
else
b[k] = a[j++];
}
while(i<=m)
{
b[k++] = a[i++];
}
while(j<=right)
{
b[k++] = a[j++];
}
// 在与b相应的位置更新排好序的a
for(int num = 0;num<right-left+1;++num)
{
a[left+num] = b[num];
}
}
7.快速排序
#include "quicksort.h"
void QuickSort( vector<int> &a)
{
for(int k=0;k<1000000;++k)
{
Qsort(a, 0,a.size()-1);
// 优化递归
//Qsort1(a, 0,a.size()-1);
}
}
void Qsort(vector<int> &a, int left ,int right)
{
int pivot = 0;
if(left < right)
{
//pivot = Partition(a,left,right);
pivot = Partition1(a,left,right);
Qsort(a,left,pivot-1);
Qsort(a,pivot+1,right);
}
}
// 优化递归
void Qsort1(vector<int> &a, int left ,int right)
{
int pivot = 0;
while(left < right)
{
//pivot = Partition(a,left,right);
pivot = Partition1(a,left,right);
Qsort1(a,left,pivot-1);
left = pivot+1;
}
}
int Partition(vector<int> &a, int left,int right)
{
int pivotkey = a[left];
while(left < right)
{
while(left < right && a[right] >= pivotkey)
--right;
swap(a[left],a[right]);
while(left < right && a[left] <= pivotkey)
++left;
swap(a[left],a[right]);
}
return left;
}
//优化pivotkey(三数取中),优化不必要交换
int Partition1( vector<int> &a, int left ,int right)
{
int m = left + (right-left)/2;
if(a[left] > a[right])
swap(a[left],a[right]);//左端较小
if(a[m] > a[right])
swap(a[m],a[right]);//中间较小
if(a[m] > a[left])
swap(a[left],a[m]);//a[left]取左边和中间的大者
int pivotkey = a[left];
while(left < right)
{
//找右边第一个小于pivotkey的
while(left < right && a[right] >= pivotkey)
--right;
a[left] = a[right];
// 找左边第一个大于pivotkey的
while(left < right && a[left] <= pivotkey)
++left;
a[right] = a[left];
}
a[left] = pivotkey;
return left;
}