冒泡排序
冒泡排序是比较排序算法中较为基础的一种,以下是原始算法以及其优化
经典冒泡
//冒泡排序原始算法
void bubbleSort(int a[],int n)
{
int swapcout=0;
int handlecount=0;
for(int i=0;i<n;++i)//确定排序趟数
{
for(int j=0;j<n-i-1;++j)//确定比较次数,注意j的边界条件
{
if(a[j]>a[j+1])
{
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
swapcout++;
}
}
handlecount++;
}
cout<<swapcount<<' '<<handlecount<<endl;
}
优化之减少排序趟数
/优化冒泡排序第一版
//加入flag,避免数组已经有序热然继续循环
void bubbleSort2(int a[],int n)
{
int swapcout=0;
int handlecount=0;
for(int i=0;i<n;++i)
{
bool flag =true;
for(int j=0;j<n-i-1;++j)
{
if(a[j]>a[j+1])
{
int tmp=a[j];
a[j]=a[j+1];
a[j+1]=tmp;
flag=false;
swapcout++;
}
}
//如果flag为true,则数组已经有序
if(flag)
{
cout<<swapcount<<' '<<handlecount<<endl;
return;
}
handlecount++;
}
}
优化之减少比较次数
//记录最后一次的交换位置,避免重复交换
void bubbleSort3(int a[],int n)
{
int swapcount=0;
int handlecount=0;
int k=n-1;
for(int i=0;i<n-1;++i)
{
bool flag =true;
int loc = 0;//记录最后一次交换的位置
for(int j=0;j<k;++j)
{
if(a[j]>a[j+1])
{
int tmp=a[j];
a[j]=a[j+1];
a[j+1]=tmp;
loc=j+1;
flag=false;
swapcount++;
}
}
k=loc;
if(flag)
{
cout<<swapcount<<' '<<handlecount<<endl;
return;
}
handlecount++;
}
}
优化之双向冒泡(作用不大)
双向冒泡的思路是从前往后找最大值的时候,同时从后往前找最小值,达到并行的效果。
事实上,因为他们操作的是同一个数组,后一次的排序结果依赖于前一次排序的结果,所以无法做到真正的并行,优化效果不大。
void BubbleSort(int arr[], int len)
{
int i = 0;
int j = 0;
int n = 0;//同时找最大值的最小需要两个下标遍历
int flag = 0;
int pos = 0;//用来记录最后一次交换的位置
int k = len - 1;
for (i = 0; i < len - 1; i++)//确定排序趟数
{
pos = 0;
flag = 0;
//正向寻找最大值
for (j = n; j < k; j++)//确定比较次数
{
if (arr[j]>arr[j + 1])
{
//交换
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
flag = 1;//加入标记
pos = j;//交换元素,记录最后一次交换的位置
}
}
if (flag == 0)//如果没有交换过元素,则已经有序,直接结束
{
return;
}
k = pos;//下一次比较到记录位置即可
//反向寻找最小值
for (j = k; j > n; j--)
{
int tmp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = tmp;
flag = 1;
}
n++;
if (flag == 0)//如果没有交换过元素,则已经有序,直接结束
{
return;
}
}
}
插入排序
选择排序
快速排序
较为经典的一种排序方式。思路也较为简单确立基准元素之后,让比基准元素小的和大的分别在基准元素的两端,再用分治的思想,对基准元素两端的数进行排序。
经典版本
void quicksort(int a[],int low,int high)
{
//递归出口
if(low>=high){
return;
}
int i=low;
int j=high;
while(i<j)
{
while(i<j&&a[j]>=a[low])
{
j--;
}
while(i<j&&a[i]<=a[low])
{
i++;
}
//两数交换
if(i<j)
{
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
//i,j相等时与枢轴元素交换
int temp2=a[low];
a[low]=a[i];
a[i]=temp2;
//递归
quicksort(a,low,i-1);
quicksort(a,j+1,high);
}
改良版本
快排在原序列有序时时间复杂度会退化,所以要加入随机化。