1.冒泡排序
举个栗子:arr[10]={22,7,9,10,4,3,11,13,5,1};
对任意两个相邻的元素进行大小比较,第一次遍历,即从下标为1的元素开始,
每一个元素都与它前面的元素进行比较,大的放后面,小的放前面(也可以小的在后),
之后考虑的都是递增的情况。这样经过一次遍历之后,最大的元素已经到达数组最末。
然后进行第二次遍历,遍历的元素为n-1个(即9个),最后一个元素已经是最大的了,
不用考虑。如果有n个元素,只要重复上述步骤n-1次即可。(遍历到第n-1次时,最小的
元素已经在第一位,所以不需要继续遍历了)。
优化:如果经过一次遍历之后没有任何元素发生变化,就已经是有序了。
以下为代码部分:
void bubble_sort(int arr[],size_t n){
size_t i,j;
for(i=0;i<n;i++){
bool hasSwap = false;
for(j=1;j<n-i;j++){
if(arr[j-1]>arr[j]){
swap(&arr[j-1],&arr[j]);
hasSwap = true;
}
}
if(!hasSwap){
break;
}
}
}
2.直接插入
举个栗子:arr[10]={8,3,6,10,15,1,7,22,15,11};
j i
将从i开始的元素插入到i之前的有序数组中。将下标为i的元素记为key,将key插入到
arr[0]----arr[i-1]之间,使这个数组保持有序。j从i-1开始遍历,如果arr[j]>key,
arr[j+1]=arr[j],直到j<0或者arr[j]<key,arr[j+1]=key;
以下是代码部分:
void insert_sort(int arr[],size_t n){
int i,j;
for(i=1;i<n;i++){
int key = arr[i];
for(j=i-1;j>=0&&arr[j]>key;--j){
arr[j+1] = arr[j];
}
arr[j+1] = key;
}
}
3.折半插入
折半插入的思路和直接插入有些许类似,只是要考虑一个左右区间的问题。
以下为代码部分:
void bin_insert_sort(int arr[],size_t n){
int i,j;
for(i=1;i<n;i++){
int key = arr[i];
int left = 0;
int right = i-1;
while(left <= right){
int mid = (left+right)/2;
if(key<arr[mid]){
right = mid-1;
}else{
left = mid+1;
}
}
for(j=i-1;j>=left;j--){
arr[j+1] = arr[j];
}
arr[j+1] = key;
}
}
4.希尔排序
希尔排序的本质也是插入,就是要先对数据进行分组。
举个栗子:arr[10]={8,4,2,1,10,15,6,7,3,11};
定义一个步长 step;
step = 10/2=5;先将10个数分为5组:
对应关系:
arr[0]-----arr[5];
arr[1]-----arr[6];
arr[2]-----arr[7];
arr[3]-----arr[8];
arr[4]-----arr[9];
step = step/2=2;再将数据分为2组:
第一组:arr[0] arr[2] arr[4] arr[6] arr[8];
第二组: arr[1] arr[3] arr[5] arr[7] arr[9];
step = step/2=1;就是直接插入了,分为一组。
以下是代码部分:
void shell_sort(int arr[],size_t n){
size_t step;
int i,j;
for(step=n/2;step>0;step=step/2){
for(i=step;i<n;i++){
int key = arr[i];
for(j=i-step;j>=0&&arr[j]>key;j=j-step){
arr[j+step] = arr[j];
}
arr[j+step] = key;
}
}
}
5.选择排序
第一次遍历将数组中的最大值放在数组的最末;
第二次遍历不考虑最后一个元素,将最大的元素放在倒数第二个位置;
每次在一个区间找一个最大值,将它放在数组的最末即可。
void choice_sort(int arr[],size_t n){
size_t i,j;
for(i=0;i<n-1;i++){
int m = 0;
for(j=1;j<n-i;j++){
if(arr[j]>arr[m]){
m = j;
}
}
if(m != n-1-i){
swap(&arr[m],&arr[n-1-i]);
}
}
}
6.鸡尾酒排序
遍历一次能够记录最大值和最小值。
将最大值放在区间最末,最小值放在区间首。
改变区间的大小。
代码部分:
void cook_tail_sort(int arr[],size_t n){
size_t i,j;
for(i=0;i<n/2;i++){
int max = i;
int min = i;
for(j=i+1;j<n-i;j++){
if(arr[max]<arr[j]){
max = j;
}
if(arr[min]>arr[j]){
min = j;
}
}
if(max != n-1-i){
swap(&arr[max],&arr[n-1-i]);
}
if(min == n-1-i){
min = max;
}
if(min != i){
swap(&arr[min],&arr[i]);
}
}
}
7.堆排序
将数据调整成大堆,将第一个元素与最后一个元素交换。
然后不考虑最后一个元素,重复上述步骤。
代码如下:
void reheap(int arr[],size_t index,size_t n){
size_t child = 2*index+1;
int key = arr[index];
while(child < n){
if(child+1<n && arr[child]<arr[child+1]){
++child;
}
if(key < arr[child]){
arr[index] = arr[child];
}else{
break;
}
index = child;
child = 2*index+1;
}
arr[index] = key;
}
void heap_sort(int arr[],size_t n){
int i;
for(i=n/2;i>=0;i--){
reheap(arr,i,n);
}
for(i=n-1;i>0;i--){
swap(&arr[0],&arr[i]);
reheap(arr,0,i);
}
}
8.归并排序
对一个数组不断分组,直到组内只有一个元素为止。
代码如下:
void mergeArr(int arr[],size_t n){
if(n<=1){
return;
}
int mid = n/2;
int len = mid;
int *prr = malloc(sizeof(int)*len);
size_t i;
for(i=0;i<len;i++){
prr[i] = arr[i];
}
size_t j,k;
i=0;
j=mid;
k=0;
while(i<len && j<n){
if(prr[i]<arr[j]){
arr[k++] = prr[i++];
}else{
arr[k++] = arr[j++];
}
}
while(i<len){
arr[k++] = prr[i++];
}
free(prr);
}
void merge_sort(int arr[],size_t n){
if(n<=1){
return;
}
int mid = n/2;
merge_sort(arr,mid);
merge_sort(arr+mid,n-mid);
mergeArr(arr,n);
}
9.快速排序
找一个基准值 把该基准值放到合适的位置
左边的元素小等于该基准值 右边的元素大小等于该基准值
左右重复该动作即可
在[left,right]区间里找。
int key = arr[left];
i=left,j=right;
只要i<j
首先从右边找小于key的值放到arr[i]位置
然后从左边找大于key的值放到arr[j]位置
当i<j不成立时 i==j
arr[i] = key。
代码如下:
void quick(int arr[],int left,int right){
if(left >= right){
return;
}
int i=left,j=right;
int key = arr[i];
while(i<j){
while(i<j&&arr[j]>=key){
--j;
}
arr[i] = arr[j];
while(i<j&&arr[i]<=key){
++i;
}
arr[j] = arr[i];
}
arr[i] = key;
if(i-1-left+1>1)
quick(arr,left,i-1);
if(right-(i+1)+1>1)
quick(arr,i+1,right);
}
10.计数排序
void count_sort(int arr[],size_t n){
int max = arr[0];
int min = arr[0];
size_t i;
for(i=1;i<n;i++){
if(max < arr[i]){
max = arr[i];
}
if(min > arr[i]){
min = arr[i];
}
}
int cnt = max-min+1;
int *prr = malloc(cnt*sizeof(int));
for(i=0;i<n;i++){
prr[i] = 0;
}
for(i=0;i<n;i++){
prr[arr[i]-min]++;
}
size_t j=0;
for(i=0;i<cnt;i++){
while(prr[i] > 0){
arr[j++] = i+min;
--prr[i];
}
}
}