排序实现功能,将数组从大到小排序。
代码:https://github.com/Fu4ng/Cpp/blob/master/sort.cpp
1.冒泡排序
冒泡排序(Bubble sorting)像是一个泡泡冒出海面,完成排序。但这样描述很飘渺,特别是和插入排序(Insert sorting)对比。这两种算法太像了。冒泡排序将后一个元素与前面的元素逐次比较,将最大(小)的值移到左(右)端。 先看代码
void Bubblesorting(int arr[],int n)
{ //冒泡排序
for(int a=0;a<n-1;a++)
{
for(int b=n-1;b>a;b--)
{
if(arr[b]>arr[b-1]) swap(arr[b-1],arr[b]);
}
}
}
如果我们有一个数组 1,2,3,4
那么第一次循环,数字4 就是泡泡(因为我们从第n-1个元素开始循环)。当“4”不断和相邻的数字交换最后跑到“1”的前面,那么就算“4”的冒泡之旅完成了。下一次循环,我们就从“3”开始冒泡。(因为2在上一次循环时与1交换位置,成为了第n-1个元素。)
2.插入排序
插入排序也是通过于相邻的元素进行交换从而进行排序的。但是插入排序的思想与冒泡不同。 始终定义第一个元素是已排序的数组,然后不断扩大数组,然后腾出位置给“插入进来的元素”
void Insetsorting(int arr[],int n)
{
for(int a= 1;a<n;a++)
{
for(int b=a ; b>0 ;b--)
{
if(arr[b]>arr[b-1]) swap(arr[b],arr[b-1]);
}
}
}
还是 1,2,3,4的数组
插入排序的思想是
先将1,2排序成正序序列{2,1},而未排序的{3,4},在下次循环中插入到已排序的序列中。
{{3,2,1},{4}}
把插入排序的数组就像你拿着一副排好的牌,然后从牌组抽牌,然后把抽的牌插入你手里的牌里。
3.选择排序
选择排序就是假设第一个元素带着一个“最大值”的王冠跟其他元素比较,如果某个元素比他大,他就要把“最大值”王冠让给他,然后这个带着王冠的元素要就与其他元素比较。如果比了一圈,还是他最大,他就退隐山林(移到数组第一个元素的位置)把王冠让出来,然后让剩下的元素继续比较。
void Selectionsorting(int arr[],int n)
{
for(int a =0;a<n;a++)
{
int bigest = a;
for(int b = a+1;b<n;b++)
{
if(arr[bigest]<arr[b])
swap(arr[bigest],arr[b]);
}
cout<<arr[bigest]<<",";//输出最大值
}
}
4.希尔排序(shellsorting)
希尔排序是插入排序的变体,但效率比插入排序有较大的提升。步长为2的shell排序的时间代价可以达到θ(n的3/2次方),有的增量可以达到θ(n的7/6次方),很接近θ(n)
将一个无序的数组,以步长为单位看成几个子数组,在对子数组分别排序,然后再缩短步长,在进行排序,最后步长缩小至1,也就是相邻对比,完成排序。
插入循环的在最优情况下,就是对一个已经排好序的数组进行排序的时候,时间复杂度是O(n),也就是不进行交换。希尔排序就是把数组局部调换,一步步变成一个接近有序的数组,最后在插入排序,一步搞定。
void Shellsorting (int arr[],int n)
{
for(int delta=n/2;delta>0;delta/=2)
{ //delta 为步长
for(int a =delta;a<n;a++)
{
for(int b=a-delta;b>=0;b-=delta)
{ if(arr[b]<arr[b+delta])
swap(arr[b],arr[b+delta]);
}
}
还有快速排序,归并排序,之后再更把。。脖子酸。。。。去操场走一走
3.12 新增快速排序
5.快速排序
快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常被采用。思想大概就是:
在一个无序数组中找到一个基准数,然后把比基准数大的数放到右边,比其小的放到左边。然后再对基准数两边的无序数组进行快速排序(递归)。
这里用语言有点难表达,上一张图,来自
http://blog.csdn.net/morewindows/article/details/6684558
void Quicksorting(int arr[],int left,int right)
{
if(left>right)
return ;
int a,b;
a=left;
b=right;
int key = arr[left];//key 为基准数
while(a!=b)
{
while(a<b&&arr[b]<=key)
b--;
while(a<b&& arr[a]>=key)
a++;
if(a<b)
swap(arr[a],arr[b]);
}
arr[left]=arr[a]; //防止相同的数
arr[a]=key;
//递归部分
Quicksorting(arr,left,a-1);
Quicksorting(arr,a+1,right);
}
如果要实现程序确定left和right的值的话,有一点要注意。
left值一般是从0开始,而right= size(arr)/size(0) -1
记得-1 否则内存越界。因为从0开始计数。
6.归并排序
代码实现图
void MemeryArray(int *arr,int first,int mid,int last )
{ //归并算法—分解部分
//将数组分解成两个临时数组
int numOfTemp1 = mid - first+1;
int numOfTemp2 = last -mid;
int *Temp1 =new int [numOfTemp1+1];
int *Temp2 =new int [numOfTemp2+1];
int i =0 , j=0 ,k=0;
while(i<numOfTemp1)
{
Temp1[i]=arr[first+i];
i++;
}
while(j<numOfTemp2)
{
Temp2[j]=arr[mid+j+1];
j++;
}
Temp1[numOfTemp1]=10000;
Temp2[numOfTemp2]=10000;
//定义这两个数值是因为上面FOR循环不能循环到numOfTemp项,而系统会给他们随便赋值,所以要给一个大过所有数的数值。
//归并算法—合并部分
for(i=0,j=0,k=first;k<=last;k++)
{
if(Temp1[i]<=Temp2[j])
{
arr[k]=Temp1[i];
i++;
}
else
{
arr[k]=Temp2[j];
j++;
}
}
delete[]Temp1; //重置指针
delete[]Temp2;
}
void Mergesorting(int *arr,int first,int last)
{
if(first<last)
{
int mid =(first+last)/2;
Mergesorting(arr,first,mid);
Mergesorting(arr,mid+1,last);
MemeryArray(arr,first,mid,last);
}
}