一、插入法
所谓插入法就是再一堆数中,对每一个元素向前找到合适的位置,然后坐下。
具体一点讲就是 第二个数先和第一个比较。那么前两个数就变得有序;再找到第三个数,先和他第二位比较,需要的情况再和地位比较;那么前3位就有序了,如此循环。
先看代码:
#include<stdio.h>
#define n 6
int main()
{
int a[n]={0,99,10,56,235,4};
int i,t,j;
for(i=0;i<n-1;i++)
{
j=i+1;
while(j>=0)
{
if(a[j]<a[j-1])
{
t=a[j];a[j]=a[j-1];a[j-1]=t;
j--;
}
else
{
break;
}
}
}
for(i=0;i<n;i++)
{
printf("%d ",a[i]);
}
return 0;
}
运行结果:
这个排序需要完成的任务就是1.确定元素;2.元素插空。
分析一下代码:
外循环:for循环完成任务1;当前面都排好序,那么叫下一个元素插孔;
内循环:while循环完成任务2;这个元素需要和他前一个元素比较;比前面的小就交换;j–后;在和前面的比较;当比前面的大就break跳出。如果一直小,那就让他放第一个位置,那么此时j<0,也就while循环结束。
二、希尔排序
步骤:
将一组n个无序的数据,对数据进行分成2部分,那么对就应得到n/2个组,,然后每组数据组内排序,再此处用上边的插入排序法,最后就是第二个图。然后再分成4部分,再对其组内排序,一直到分成组内只有一个元素。
很多人可能会有疑问,为什么还是会用到插入法,那不是变得更复杂了嘛?但是当我们要排列的数据很多的时候,那么希尔排序更高效,他交换的次数会更少。
#include<stdio.h>
#define n 6
int main()
{
int a[n]={6,90,200,103,7,1}; //6 90 200 | 103 7 1
int i,j,t,z;
t=n;
while(t>0)
{
t=t/2;
for(i=0;i<n-t;i++) //插入法
{
j=i+1;
while(j>=0)
{
if(a[j]<a[j-1])
{
z=a[j];
a[j]=a[j-1];
a[j-1]=z;
j--;
}
else
{break;}
}
}
}
for(i=0;i<n;i++)
{
printf("%d ",a[i]);
}
return 0;
}
结果为
三、选择法
每次在序列中选出最小的值,放在序列的第一个,直至全部排完。
代码如下:
#include<stdio.h>
#define n 6
int main()
{
int a[n]={6,90,200,103,7,1}; //6 90 200 | 103 7 1
int i,j,t,k;
for(i=0;i<n-1;i++)
{
k=i;
for(j=i+1;j<n;j++)
{
if(a[k]>a[j])
{
k=j;
t=a[i];
a[i]=a[k];
a[k]=t;
}
}
}
for(i=0;i<n;i++)
{
printf("%d ",a[i]);
}
return 0;
}
运行结果
四、冒泡法
就是对于一个对于一个无序的数组,从第0个开始,相邻两个数进行比较,如果左边较大就交换,这样一轮下来,最大的数就在最后;然后再继续下一趟;如此循环。
代码:
#include<stdio.h>
#define n 6
int main()
{
int a[n]={6,90,200,103,7,1}; //6 90 200 | 103 7 1
int i,j,t,k;
for(i=0;i<n-1;i++)
{
for(j=0;j<n-1-i;j++)
{
if(a[j]>a[j+1])
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
for(i=0;i<n;i++)
{
printf("%d ",a[i]);
}
return 0;
}
运行如下:
五、快排
在这里就简单复习一下:
void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*));
他主要有四个部分:①首元素的地址。通常指:数组名②元素个数。数组大小③元素的大小④函数名详细请看:http://t.csdn.cn/OCfgj
六、 归并
就是将数列一步步往下拆分,直至最小单元;申请空间放一个新的数组,用来存放每次归并后的序列;比较两个序列元素的大小,将较小的元素存放到新申请的空间,其中一个序列被检测完后,将未检测完的序列元素复制到新数组后面。
代码:
#include <stdio.h>
#include <malloc.h>
#define len 6
void Merge(int *a, int low, int mid, int high); //用来每一轮的归并及排序
void MergeSort(int *a, int first, int last); //排序时往下划分
int main(void)
{
int i;
int a[len]={6,90,200,103,7,1};
MergeSort(a, 0, len-1); //调用排序函数
for(i = 0; i < len; ++i)
{
printf("%d ", a[i]);
}
printf("\n"); //输出排序结果
return 0;
}
void MergeSort(int *a, int first, int last)
{
int mid; //mid为整型变量,因此mid为1/2时,向下取整为0,跳出递归
if (first < last)
{
mid = (first + last) / 2;
MergeSort(a, first, mid); //递归,不断往下划分
MergeSort(a, mid+1, last);
Merge(a, first, mid, last); //调用排序函数
}
return;
}
void Merge(int *a, int low, int mid, int high)
{
int k, i;
int *tmp = (int *) malloc ((high-low+1) * sizeof(int)); //定义临时数组,申请空间,用于临时存放排序序列
int left_low = low; //分成左右两个数组
int left_high = mid;
int right_low = mid+1;
int right_high = high;
for (k = 0; left_low <= mid && right_low <= high; k++)
//左右两个数组自小到大两两比较,小的复制到临时数组tmp[],则临时数组是升序序列
{
if (a[left_low] < a[right_low])
{
tmp[k] = a[left_low++];
}
else
{
tmp[k] = a[right_low++];
}
}
while (left_low <= mid)
tmp[k++] = a[left_low++];
while (right_low <= high)
tmp[k++] = a[right_low++];
for (i = 0; i < high-low+1; i++)
a[low+i] = tmp[i]; //将排序好的临时数组复制回原数组
free(tmp); //释放分配给临时数组的空间
return;
}
运行结果为:
七、堆排序
将数组元素创建为一个大顶堆,调整元素使得每个分支节点大于孩子节点;将堆首(最大值)元素与堆尾元素互换;排除掉堆尾元素,剩下的元素再次调整为新的堆;直至堆的尺寸为1。
代码:
#include <stdio.h>
#include <malloc.h>
#include <math.h>
void Swap(int * a, int * b);
void HeapSort(int *a, int len);
void AdjustHeap(int *a, int i, int len);
int main(void)
{
int len,i;
len=6;
int a[len]={6,90,200,103,7,1};
HeapSort(a, len); //调用排序函数
for(i = 0; i < len; ++i)
{
printf("%d ", a[i]);
}
printf("\n"); //输出排序结果
return 0;
}
void HeapSort(int *a, int len)
{
int i;
for(i = len/2; i >= 0; --i)
{
AdjustHeap(a, i, len);
}
for(i = len-1; i > 0; --i)
{
Swap(&a[0], &a[i]);
AdjustHeap(a, 0, i);
}
}
void AdjustHeap(int *a, int i, int len) //调整成大顶堆
{
int temp = a[i];
for(int child; 2*i+1 < len; i = child) //当没有孩子时跳出循环
{
child = 2*i+1;
if(child != len-1 && a[child] < a[child+1])
++child;
if(temp < a[child])
a[i] = a[child]; //采用大顶堆,比孩子节点小,则交换
else
break;
}
a[i] = temp;
}
void Swap(int * a, int * b) //交换元素
{
int t;
t = *a;
*a = *b;
*b = t;
}