排序
这里先介绍俩种排序方法----归并排序和快速排序
1.归并排序
引例 归并排序的图片描述
图片来源:菜鸟教程
引例 对十个数的归并排序
// merge sort
#include<stdio.h>
int a[10]={5,3,13,25,84,64,70,20,90,100};
int b[10];//一个临时数组
int min(int x,int y)
{//先写一个min函数用来比较数字的大小
return x<y?x:y;
}
void Merge(int a[],int s,int m,int e,int b[])
{ int i=0;
int x=0;//负责指向b
int x1=s,x2=m+1;//分别负责指向需要归并的俩个数组
while (x1<=m && x2<=e){
if (a[x1] < a[x2])//开始比较待归并的俩格数组,比较元素的大小,小的就放在前面
b[x++]=a[x1++];
else
b[x++]=a[x2++];
}
//只要有一个数组的数全部都排完了,那么我就可以吧另一个数组剩下的全部数就都放在临时数组里了
while (x1 <=m)
b[x++] = a[x1++];
while (x2<=e)
b[x++] = a[x2++];
for (i=0;i<e-s+1;i++) //这里e-s+1是因为e是从len-1开始的,所以+1
a[s+i] = b[i];//把b中已经排好的数组重新赋值给a
}
void MergeSort(int a[],int s,int e,int b[])//一个参数是要排序的数组,另一个是数组的开始,结尾,b临时存放
{
if(s<e){
int m = s + (e-s)/2; //找到中间的位置
MergeSort(a,s,m,b);//对前一半排序
MergeSort(a,m+1,e,b);//对后一半排序
Merge(a,s,m,e,b);//进行并的操作
}
}
//写一个演义的函数
void Display(int a[],int s,int e){
int i;
for (i=s;i<e+1;i++)
printf("%d,",a[i]);
printf("\n");
return ;
}
int main()
{ int i;
int len = sizeof(a)/sizeof(int);//得到a的长度
Display(a,0,len-1);
MergeSort(a,0,len-1,b);//进行排序操作
Display(a,0,len-1);
}
结果如图所示:
从代码中我们可以看出,我们使用了递归的思想完成了归并排序的操作,其中比较重要的俩格步骤,就是“分(Mergesort)”和“和(Merge)”俩个函数
在Mergesort函数中:
void MergeSort(int a[],int s,int e,int b[])//一个参数是要排序的数组,另一个是数组的开始,结尾,b临时存放
{
if(s<e){
int m = s + (e-s)/2; //找到中间的位置
MergeSort(a,s,m,b);
MergeSort(a,m+1,e,b);//对后一半排序
Merge(a,s,m,e,b);//进行并的操作
}
}
主要是进行了分半的操作,通过二分的过程,把一个大的数组变成一个个小的局部的数组,然后再通过Merge函数,分别对每一小片的数组再次整理组合在了一起.
void Merge(int a[],int s,int m,int e,int b[])
{ int i=0;
int x=0;//负责指向b
int x1=s,x2=m+1;//分别负责指向需要归并的俩个数组
while (x1<=m && x2<=e){
if (a[x1] < a[x2])//开始比较待归并的俩格数组,比较元素的大小,小的就放在前面
b[x++]=a[x1++];
else
b[x++]=a[x2++];
}
//只要有一个数组的数全部都排完了,那么我就可以吧另一个数组剩下的全部数就都放在临时数组里了
while (x1 <=m)
b[x++] = a[x1++];
while (x2<=e)
b[x++] = a[x2++];
for (i=0;i<e-s+1;i++) //这里e-s+1是因为e是从len-1开始的,所以+1
a[s+i] = b[i];//把b中已经排好的数组重新赋值给a
}
快速排序
图片描述
此处图片出处:五分钟学算法
引例:对十个数字进行排序
//QuickSort
#include<stdio.h>
#define BUF_SIZE 10
void display(int array[],int maxlen)
{
int i;
for (i=0;i<maxlen;i++)
{
printf("%d,",array[i]);
}
printf("\n");
}
void swap(int *a,int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
// the implementation of quicksort
void quicksort(int array[],int begin,int end)
{
int i,j;
int k = array[begin];
if (begin >= end )
return;
i = begin; // 把array[begin]作为基准数,因此array[begin+1]开始与基准数吧比较
j = end;
while (i!=j)
{ while (j>i && array[j] >=k) // 保证k右边的数都比K 大
--j; //这个循环的意思就是说,如果满足这个条件,那么我的指针就向下一个元素指去;
swap(&array[i],&array[j]);//自然,不满足循环的条件的话,就会互换位置。
while (j >i && array[i]<=k) //保证k左边的数,都比K 小
++i;
swap(&array[i],&array[j]);
}//此时就已经处理完成了数组,
//进行k左右俩边数组的分别排序
quicksort(array,begin,i-1);
quicksort(array,i+1,end);
}
main()
{
int n;
int array[BUF_SIZE] = {12,85,25,16,34,23,49,95,17,61};
int maxlen = BUF_SIZE;
printf("排序前的数组:\n");
display(array,maxlen);
quicksort(array,0,maxlen-1); // 快速排序
printf("排序后的数组:\n");
display(array,maxlen);
}
结果如图所示:
在给出的快排代码中,我是让a[0]先作为k,然后开始比较。
代码解读:
void quicksort(int array[],int begin,int end)
{
int i,j;
int k = array[begin];
if (begin >= end )
return;
i = begin; // 把array[begin]作为基准数,因此array[begin+1]开始与基准数吧比较
j = end;
while (i!=j)
{ while (j>i && array[j] >=k) // 保证k右边的数都比K 大
--j; //这个循环的意思就是说,如果满足这个条件,那么我的指针就向下一个元素指去;
swap(&array[i],&array[j]);//自然,不满足循环的条件的话,就会互换位置。
while (j >i && array[i]<=k) //保证k左边的数,都比K 小
++i;
swap(&array[i],&array[j]);
}//此时就已经处理完成了数组,
//进行k左右俩边数组的分别排序
quicksort(array,begin,i-1);
quicksort(array,i+1,end);
}
在快排实现的代码中,我们可以看到,我设置了俩个变量i,j然后通过与k的比较,不断地进行交换位置还有指针向中间的移动,到最后使得i,j指向中间的位置,然后,再次递归调用quicksort函数,分别对中间左右的数组元素再次进行排序。
上一篇:我的算法笔记(4)二分查找1
下一篇:我的算法笔记(6)动态规划1