日常生活中,我们用的最多的算法大概就是排序了吧,相信大家多半都曾经体会过被“别人家的孩子”统治过的恐惧,用排序的思想来说,毕竟你的排名在人家后面嘛,不知道大家现在,超越曾经的“别人家的孩子”了吗?
以上是闲话,正题开始
在计算机中,排序的算法有许许多多种,各种方法之间不论优劣,因为都存在各自的针对性,工作在不同的领域,而且因为排序的用处过于广泛,所以排序的方法也多种多样,这里也就不一一列举来了,值挑几个常用并且不是太难的算法来简单介绍一下吧。
排序算法1:冒泡排序 稳定 时间复杂度O(n^2)
冒泡排序的优点是简单、稳定,在少量数据时性能较为优秀,顾名思义,冒泡算法的原理就是将两两相邻的两个数进行比较,然后将其中较大的数放在后面,较小的数放在前面,然后再往后移动一位,再次进行比较,如此循环,直至排序完成。
示例代码如下:
void bubble(int a[],int len){
int i,j;
for(i=0;i<len;i++){
for(j=0;j<len-i;j++){
if(a[j]>a[j+1]){
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
}
排序算法2:插入排序 稳定 时间复杂度O(n^2)
严格来说,插入排序算法有很多种,例如直接插入排序,链表插入、二分插入等,这里只讨论直接插入排序,所以这段里所有的插入排序指的都是直接插入排序。
插入排序算法的优点同样是简单、稳定, 个人感觉性能上和冒泡差别不大,原理是将一个未排序数组分为两个部分,一个是默认有顺序部分,在最开始默认为1,相对的,无序的部分就是总长减1,然后每次选择无序部分的一个元素,放入有序部分的合适位置,直至无序部分为空时完成排序。
示例代码如下:
void insert(int a[], int len)
{
int i,j,t;
for (i = 1; i < len; i ++)
{
t = a[i];
j = i - 1;
while (j > -1 && t < a[j] )
{
a[j + 1] = a[j];
j --;
}
a[j + 1] = t;
}
}
排序算法3:选择排序 非稳定 时间复杂度O(n^2)
选择排序是一种不稳定的算法(根据若干相关论帖,不稳定之处大约在于数组实现时的交换操作,而使用链表实现时这个算法是稳定的算法。在下此时对于此概念尚且较为模糊,于是此处不作讨论)原理是每次找出未排序数组中最大或最小数放在有序数组合适的位置,直到未排序数组为空
示例代码如下:
void select(int a[],int len){
int i,j,t;
for(i=0;i<len;i++){
for(int j=i+1;j<len;j++){
if(a[i]>a[j]){
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
}
}
排序算法4:快速排序 非稳定 时间复杂度平均O(nlogn),最差O(n^2)
快速排序在对大量非重复数据排序速度较快,但出现重复则会极大降低实现速度,原理是将未排序的数据按照一个数为界限分为较大和较小两个未排序区域,然后再在两个区域内再次分为较大较小两个区域,如此往复若干次,就能得到一个有序的数列
示例代码:
void quiksort(int a[],int low,int high)
{
int i = low;
int j = high;
int temp = a[i];
if( low < high)
{
while(i < j)
{
while((a[j] >= temp) && (i < j))
{
j--;
}
a[i] = a[j];
while((a[i] <= temp) && (i < j))
{
i++;
}
a[j]= a[i];
}
a[i] = temp;
quiksort(a,low,i-1);
quiksort(a,j+1,high);
}
else
{
return;
}
}
排序算法5:堆排序 非稳定 时间复杂度O(nlogn)
堆排序是将待排序的数据构建成近似二叉树的形式来进行排序的一种算法,但在实际算法设计中,我们一般还是使用数组来进行排序,近似二叉树的结构只存在于构建者的思维中。
示例代码如下:
void max(int a[],int len) {
int j,t;
for (j = len - 1; j > 0; j--) {
int parent = j / 2;
int child = j;
if (j < len - 1 && a[j] < a[j+1]) {
child++;
}
if (a[child] > a[parent]) {
t = a[child];
a[child] = a[parent];
a[parent] = t;
}
}
}
void heap(int a[],int len) {
int j,t;
for (j = len; j > 0; j--) {
max(a, j);
t = a[0];
a[0] = a[j - 1];
a[j - 1] = t;
}
}
排序算法6:归并排序 稳定 时间复杂度O(nlogn)
归并排序的思想来源于分治法,是一种可靠,速度也不慢的排序算法,原理是将待排序数据层层分解为单个有序数据,再按照大小关系依照分解的路径重新归并为有序的数据
示例代码如下:
void merge(int arr[], int tarr[], int sindex, int mindex, int eindex)
{
int i = sindex, j = mindex + 1;
int k = 0;
while (i < mindex + 1 && j < eindex + 1)
{
if (arr[i] > arr[j])
tarr[k++] = arr[j++];
else
tarr[k++] = arr[i++];
}
while (i < mindex + 1)
{
tarr[k++] = arr[i++];
}
while (j < eindex + 1)
tarr[k++] = arr[j++];
for (i = 0, j = sindex; j < eindex + 1; i ++, j ++)
arr[j] = tarr[i];
}
void merge_sort(int arr[], int tarr[], int sindex, int eindex)
{
if (sindex < eindex)
{
int mindex = (sindex + eindex) / 2;
merge_sort(arr, tarr, sindex, mindex);
merge_sort(arr, tarr, mindex + 1, eindex);
merge(arr, tarr, sindex, mindex, eindex);
}
}
时间有限,暂时也只想到这些,后面待续……