- 简单选择排序
循环遍历整个数组,每次遍历都是从当前待填充位置开始,找出未排序集合中的最小值,每次找到更小值都记录其值和位置信息,遍历完成后,将最小值与当前待填充点 进行交换。继续下一个位置,直到外循环到达数组尾。
#include <iostream>
using namespace std;
int main()
{
int a[10]={23,11,6,33,14,99,23,2,14,20};
int smallest;
int smallpos;
for(int i=0;i<10;i++)
{
cout<<a[i]<<‘ ‘;
}
for(int i=0;i<9;i++)
{
smallest=a[i];
smallpos=i;
for(int j=i+1;j<10;j++)
{
if(a[j]<smallest)
{
smallest=a[j];
smallpos=j;
}
}
a[smallpos]=a[i];
a[i]=smallest;
}
cout<<endl;
for(int i=0;i<10;i++)
{
cout<<a[i]<<‘ ‘;
}
return 1;
}
- 插入排序
插入排序的原理为在未排序集合中选择一个值在已排序集合中寻找其合适的位置插入。首先整个集合默认为未排序集合,从头开始遍历,得到一个未排序数据并记录,然后从该数据位置开始往回遍历寻找插入位置,首先判断待插入位置是否为首位,如果是则直接插入。否则,每次将待插入值与待插入位置前一位的值相比,若比待插入值大,则该值往后移动一位,待插入位置前移一位,否则将待插入值填入待插入位置。
#include <iostream>
using namespace std;
/******插入排序***********/
int main()
{
int a[10]={23,11,6,33,14,99,23,2,14,20};
int cur;
for(int i=0;i<10;i++)
{
cout<<a[i]<<‘ ‘;
}
cout<<endl;
for(int i=1;i<10;i++)
{
cur=a[i];
for(int j=i;j>=0;j--)
{
if(j==0)
{
a[j]=cur;
}
else if(a[j-1]>cur)
{
a[j]=a[j-1];
}
else
{
a[j]=cur;
break;
}
}
}
for(int i=0;i<10;i++)
{
cout<<a[i]<<‘ ‘;
}
return 1;
}
-交换排序
循环遍历数组,每次比较相邻两个元素,将大的放在后面,小的放在前面,直到达到最后交换元素位置,每次达到最后交换元素位置并完成交换后,就将最后交换元素位置前移一位。直至最后交换元素位置与首位重合,则排序结束,退出循环。
下面程序中last表示最后交换元素的位置。
#include <iostream>
using namespace std;
/*******交换排序***********/
int main()
{
int a[10]={23,11,6,33,14,99,23,2,14,20};
int last=9;
for(int i=0;i<10;i++)
{
cout<<a[i]<<‘ ‘;
}
cout<<endl;
while(last>0)
{
for(int i=0; i < last; i++ )
{
if(a[i]>a[i+1])
{
int tmp=a[i];
a[i]=a[i+1];
a[i+1]=tmp;
}
}
last--;
}
for(int i=0;i<10;i++)
{
cout<<a[i]<<‘ ‘;
}
return 1;
}
-归并排序
其原理是,将两个有序集合同时遍历,每次比较两个集合中当前位置的元素,将较小的元素赋给合并集合相应位置,然后合并集合待填充位置右移一位,较小元素所在集合当前位置右移一位,继续比较,同时还需要判断哪个集合先遍历完,对于另外一个还有剩余元素的集合,则直接把剩余的元素直接赋给合并集合剩余的位置中。但是由于集合是乱序的,因而需要将集合不断分割至单元素集合(可认为是有序集合),然后再进行集合的的重新组合,组合得到的新集合则是有序的,如此回溯直至回到从原始集合中分开的两个子集为有序集合,再进行最后一次合并,完成原始集合的排序。
总体而言,其步骤是递归地分割原始集合,直至集合中只有单元素,然后往回结合成有序集合,即排序的过程是从下往上的。
#include <iostream>
using namespace std;
int mergesort(int* array,int i,int j);
int merge(int* arr,int i,int k,int j);
int main()
{
int a[10]={23,11,6,33,14,99,23,2,14,20};
int n=9;
for(int i=0;i<=n;i++)
{
cout<<a[i]<<‘ ‘;
}
cout<<endl;
mergesort(a,0,n);
for(int i=0;i<=n;i++)
{
cout<<a[i]<<‘ ‘;
}
return 1;
}
int mergesort(int* array,int i,int j)
{
if(i<j)
{
int k=(i+j)/2 ;
mergesort(array,i,k);
mergesort(array,k+1,j);
merge(array,i,k,j);
}
return 0;
}
int merge(int* arr,int i,int k,int j)
{
int ipos=i;
int kpos=k+1;
int mpos=0;
int* tmparr=new int[j-i+1];
while(ipos<=k || kpos<=j)
{
if(ipos>k) //表示左集合数据合并完毕
{
while(kpos<=j)
{
tmparr[mpos]=arr[kpos];
kpos++;
mpos++;
}
continue;
}
else if(kpos>j) //右集合数据合并完毕
{
while(ipos<=k)
{
tmparr[mpos]=arr[ipos];
ipos++;
mpos++;
}
continue;
}
if(arr[ipos]<arr[kpos])
{
tmparr[mpos]=arr[ipos];
ipos++;
mpos++;
}
else
{
tmparr[mpos]=arr[kpos];
kpos++;
mpos++;
}
}
ipos=i;
int tmpi=0;
while(ipos<=j)
{
arr[ipos]=tmparr[tmpi];
ipos++;
tmpi++;
}
delete tmparr;
return 0;
}
图中箭头序号表示的是执行顺序,实现框为原始数据顺序,虚线框为排序过后顺序。
-快速排序
快速排序与归并排序有点相似,都是需要分割,但是其过程却是相反的,归并排序是先分割,然后回溯时候进行排序,当回溯到原集合的时候完成排序。而快速排序是先排序(确定基准元素位置,以及其他元素所处集合)然后分割,再确定分割后的集合中基准元素位置,递归进行,当分割至最后一个元素则意味着最后一个元素的位置确定了,即整个集合完成排序。
#include <iostream>
using namespace std;
int qsort(int* array,int l,int r);
int sort(int* array,int lp,int rp);
int main()
{
int a[10]={23,11,6,33,14,99,23,2,14,20};
for(int i=0;i<10;i++)
{
cout<<a[i]<<‘ ‘;
}
cout<<endl;
qsort(a,0,9);
for(int i=0;i<10;i++)
{
cout<<a[i]<<‘ ‘;
}
return 1;
}
int qsort(int* array,int l,int r )
{
int pos;
if(l<r)
{
pos=sort(array,l,r);
qsort(array,l,pos-1);
qsort(array,pos+1,r);
}
}
int sort(int* array,int lp,int rp)
{
int lpos=lp;
int rpos=rp;
int pivot=array[lp];
while(lpos<rpos)
{
while(array[rpos]>pivot)
rpos--;
while( (lpos<rpos) && array[lpos]<=pivot)
{
lpos++;
}
if(lpos<rpos)
{
int tmp=array[lpos];
array[lpos]=array[rpos];
array[rpos]=tmp;
lpos++;
rpos--;
continue;
}
}
array[lp]=array[rpos];
array[rpos]=pivot;
return rpos;
}