目录
1.快速排序(交换排序类)
(1).基本原理
快速排序是C.R.A.Hoare于1962年提出的,他的基本思路是:
首先从数列中取出一个元素作为基准数;然后扫描数列,将比基准数小的元素全部放到它的左边,大于或等于基准数的元素全部放到它的右边,得到左右两个区间;接着再对左右区间重复第二步(即使用递归),直到各区间少于两个元素。
(2).具体操作讲解
1.选择一个元素作为基准数(一般情况下都选择第一个元素),并创建两个左右指向(指向数组下标)。
2.扫描数组,先从右开始,判断右指向所指的元素与基准数的大小关系,若大于基准数,则将右指向向左移,继续判断大小,若小于基准数,则将该元素“填”入左指向所指的位置,然后将左指向向右移,判断左指向所指元素与基准数的大小关系,若小于基准数,则将左指向右移,若大于基准数,则将该元素“填”入右指向所指位置。随着左右指向不断的移动,最后两个指向会指向同一个元素,这时要把基准数“填”入该位置。这样本轮基准数的位置就确定了,基准数左边都是小于它的,右边都是大于它的。
3.分别对刚才形成的左右区间再继续进行刚才的操作,一直到各区间元素数量小于2时结束。
(3).代码展示
#include<stdio.h>
#include<stdlib.h>
void kuaisu(int *a,int n)
{
int left,right,sign,move=2; //left、right分别作为左右指向(指向数组下标),sign是所选取的中间轴(默认为数组最左边的数),move用来标记应该移动左、右指向所指的值(为1时代表左,为2时代表右)
left=0;
right=n-1;
sign=a[0];
while(left<right) //循环条件为左指向小于右指向
{
if(move==2) //移动右指向所指的值
{
if(a[right]>=sign){right--;continue;} //如果右指向所指的指大于选取的中间轴,则不用移动,继续判断下一个
a[left]=a[right];
move=1; //令move=1,下一次移动左指向所指的值
left++;
continue;
}
if(move==1) //移动左指向所指的值
{
if(a[left]<=sign){left++;continue;} //如果左指向所指的指小于选取的中间轴,则不用移动,继续判断下一个
a[right]=a[left];
move=2; //令move=2,下一次移动右指向所指的值
right--;
continue;
}
}
a[left]=sign; //left=right时表示该次循环结束,将开始时选择的中间轴放到left和right所指的坑
if(left>1){kuaisu(a,left);} //递归,直到所分的数组元素个数为1
if(n-left-1>1){kuaisu(a+left+1,n-left-1);}
}
int main()
{
int a[15]={3,31,4,54,23,67,5,89,68,43,0,87,7,9,1};
printf("该数组经过快速排序后结果为:\n");
kuaisu(a,15);
for(int j=0;j<15;j++)
{
printf("%d ",a[j]);
}
return 0;
}
2.插入排序(插入排序类)
(1).基本原理
插入排序的原理是通过构建有序序列,对于未排序的数据,在已排序列中从后往前扫描,找到相应的位置并插入(即对于未排序元素a,从已排序序列中从后往前比较,如果小于所比元素,则交换两者的值,直到该元素a交换到第一个元素或者大于一个已排序元素为止)。
(2).具体操作讲解
首先默认第一个元素为已排序,从第二个元素开始与已排序序列从后往前比较,大于该元素的往后移,找到合适位置(即找到比该元素小的或者已经比较完了)后继续进行下一个元素的比较,直到所有元素都为有序。
(3).代码展示
#include<stdio.h>
void insertSort(int array[],int length)
{
int t;
for(int i=1;i<length;i++) //从第二个元素开始
{
for(int j=0;j<i;j++) //每次都跟它前面的元素比较
{
if(array[i]<array[j]) //即找到合适位置
{
t=array[i]; //用变量t暂时存放该元素的值
for(int k=i-1;k>=j;k--)
{
array[k+1]=array[k]; //在本轮的比较中,所有大于该元素的都往前移
}
array[j]=t; //最后在把该元素的值填入正确的位置
}
}
}
}
int main()
{
int array[6]={4,3,5,1,9,6};
insertSort(array,6);
for(int i=0;i<6;i++)
{
printf("%d ",array[i]);
}
return 0;
}
3.希尔排序(插入排序类)
(1).基本原理
希尔排序是对上面的插入排序的一种改进,由D.L.Shell于1959年提出而得名。其基本思想是把待排序的数列分为多个组,然后再对每个组进行插入排序,先让数列整体大致有序,然后多次调整分组方式,使数列更加有序,最后再使用一次插入排序,整个数列将会全部有序。
(2).具体操作讲解
先确定分组元素的间隔(即每各多少个元素将元素进行分组)。对于元素个数为length的待排序数组,第一次分组的间隔应为length/2-1(注意length为int型),第二次为length/2/2-1,直到间隔为0时结束分组操作,对已经大致有序的整体再进行一次插入排序。
(3).代码展示
#include<stdio.h>
void printArray(int array[],int length){
for(int i=0;i<length;i++)
{
printf("%d ",array[i]);
}
printf("\n");
}
void shellSort(int array[],int length,int step){
for(int i=0;i<length;i++)
{
for(int j=i+step;j<length;j+=step)
{
for(int k=i;k<j;k+=step)
{
if(array[j]<array[k])
{
int temp=array[j];
for(int l=j-step;l>=k;l-=step)
{
array[l+step]=array[l];
}
array[k]=temp;
}
}
}
}
}
int main()
{
int array[10]={49,38,65,97,76,13,27,49,55,4};
int steps[3]={5,3,1};
for(int i=0;i<3;i++)
{
shellSort(array,10,steps[i]);
printArray(array,10);
}
return 0;
}
学习是痛苦的,但也是快乐的
痛苦+坚持=成功!