井然有序是最高效的。
直接插入排序、希尔排序、选择排序、冒泡排序、位排序、快速排序
1. 直接插入排序
(1) 思想:假设序列n分为两个部分,有序k和无序(n-k)。排序过程中,每次从无序的部分中取出第一个元素,将它插入到有序表中适当的位置,使之有序。
(2) 时间复杂度:最坏O(n2),最好O(n),平均O(n2)。
(3) 空间复杂度:O(1)。
(4) 对于小规模数组和基本有序的数据而言,直接插入排序比较高效。
(5) 关键代码:先在有序区间array[0] …array[k-1]区间给array[k]找到插入的位置;然后将比array[k]大的数据向后移动一个位置。(移动,插入)
for(k = 1; k < n; k++)
{
for( j = k-1; j > 0; j--)
{
if(array[j] < array[i])
{
break;
}
}
if( j != k-1)
{
temp = array[k];
for(m = k; m > j+1; m--)
{
array[m] = array[m-1];
}
array[j+1] = temp;
}
}
2. 希尔排序
(1) 思想:把较大的数据集合按数组下标的一定增量gap进行分组,然后对每组使用直接插入排序。
(2) 增量的选择
(3)关键代码:
for(gap = N/2; gap > 0; gap = gap/2)
{
for(i = gap; i < N; i++)
{
int temp = arr[i];
for(j = i - gap; (j>= 0) && (temp < array[j]; j = j -gap)
{
array[j+gap] = array[j];
}
array[j+gap] = temp;
}
}
3. 选择排序
(1) 思想:假设序列n分为两个部分,有序k和无序(n-k)。排序过程中,每次从无序的部分中,将最大或者最小的元素取出,将它放到有序的末尾。
(2) 时间复杂度:O(n2)。
(3)关键代码:
for(i = 0; i < n; i++)
{
min=i;
for(j = i+1; j < n; j++)
{
if(array[j] < array[min])
{
min = j;
}
}
if(min != i)
{
temp = array[i];
array[i] = array[min];
array[min] = temp;
}
}
4. 冒泡排序
(1) 思想:冒泡,冒泡,以从小到大排序为例说明,依次比较前后两个数,若前面的数大于后面的数,则交换两者的位置。这样,逐个选出最大的,次大的…
(2)时间复杂度:O(n2)。
(3)关键代码:
for(k = n-1; k > 0; k--)
{
int flag = 0; //优化的冒泡,置一个标志位。若某一趟排序没有发生交换,则说明已经是有序的。
for( l = 0; l < k; l++)
{
if(array[l] > array[l+1])
{
flag = 1;
temp = array[l];
array[l] = array[l+1];
array[l+1] = temp;
}
}
if(0 == flag)
{
break;
}
}
5. 位图排序
(1) 数据特点:无重复数据、最大值已知、整型。
(2) 思想:用一个bit位标识一个int 整数是否出现。若该位为1,则出现;若该位为0,则未出现。
- 假设有N个未重复的整数,最大值不大于N。
LENGTH = N/32 + 1;
int bitArray[LENGTH] = {0};
for(i = 0; i < N; i++)
{
int k = i/32;
int l = i%32 + 1;
//将bitArray[k]的第l位置为1。
bitArray[k] = bitArray[k] | (1 << l) ;
}
//输出位排序后的数据
for(i = 0; i < LENGTH;i++)
{
for(j = 0; j< 32; j++)
{
if((bitArray[i] & (1 << j))
{
temp = i * 32 + j;
printf("%d", &temp);
}
}
6. 快速排序
(1) 思想:分而治之。以从小到大排序为例说明。
- 选一个基数。
- 小于基数的往左边扔,大于基数的往右边扔。
- 然后针对基数左右两边的数,重复上述两个步骤,直到往左右两边扔的数只有一个或0个为止。
- 递归。
(2) 关键代码:
void quicksort(int left, int right) {
int i, j, temp, base;
if(left > right)
{
return;
}
base = array[left];
i = left;
j = right;
while(i != j)
{
while(a[j] >= base && i < j)
{
j--;
}
while(a[i] <= base && i < j)
{
i++;
}
if(i < j) //交换两个数在数组中的位置
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
//最终将基准数归位
a[left] = a[i];
a[i] = base;
quicksort(left, i-1);
quicksort(i+1, right);
}