年后打算找个好工作先复习下排序的各种算法。
方法有插入(直接插入、希尔排序)、交换(冒泡排序、快速排序)、选择(直接选择、堆排序)、归并、基数等排序算法。
上述的各种排序方法各有优缺点,适合场合也不同。
如何选择排序方法?
在选择排序方法时需要考虑的因素有下4点:
1、待排序的数目大小
2、记录本身数据量的大小,也就是记录中除关键字外的其他信息量的大小
3、关键字的结构以及其分布情况
4、对排序稳定性的要求
考虑以上因素可以得出以下结论
1、如果待排序的初始状态已经按关键字基本有序,则选择直接插入排序法或冒泡排序
2、如果待排序的数目较小,则可以选择直接插入排序或直接选择排序
3、如果待排序的数目较大,则采用时间复杂度为O(nlog2 n)的排序方法,快速排序、堆排序、归并排序
4、快速排序、堆排序、希尔排序和直接选择排序是不稳定排序;直接插入排序、冒泡排序、归并排序、基数排序都是 稳定排序
5、基数排序只适于字符串和整数这类有明显结构特征的关键字。
6、插入排序和归并排序在链表上实现容易,快速排序和堆排序在链表实现难。
性能评价标准有两条:
1、执行排序算法所需时间。
2、执行排序算法所需的附加空间
下面具体实现各种排序算法
1、插入排序法
1.1直接插入排序
算法
1、验证数据的合法性
2、循环比较
开始把第一个记录看成是已经排好的子序,这时子序只有一个记录。
从第二个记录起到最后一个记录,依次将其和前面的子序中的记录按关键字比较,确定插入的位置。
将记录插入到子序中,子序记录加1,直到子序长度跟原序列一样结束循环。
void insert_sort(int a[], int length)
{
int i = 0;
int j;
int temp;
if ( NULL == a || 0 == length)
return;
for(i=1; i<length; ++i)
if( a[i] < a[i-1])
{
temp = a[i-1];
for( j=i-1; j>0 && temp<a[j]; --j)//循环找正确的位置
{
a[j+1] = a[j]; //记录后移
}
a[j+1] = temp;//插入到正确的位置
}
}
1.2希尔排序
取di = length/2 di+1 = di/2
void shell_sort ( int a[], int length)
{
int dk;
if( NULL == a || 0 == length)
return;
for( dk=length/2 ; dk > 0; dk /= 2 )
shell_insert( a,length,dk);
}
void shell_insert(int a[]. int length, int dk)
{
int i, j,temp;
for( i=dk; i<length; ++i)
{
if(a[i] < a[i-dk])
{
temp = a[i-dk];
for( j = i -dk; j>0&&temp<a[j]; j -= dk)
{
a[j+dk] = a[j];
}
a[j+dk] = temp;
}
}
}
2、交换排序
2.1冒泡排序
viod bubbler_sort( int a[], int length)
{
int i,j,flag,temp;
flag = 0;
if( NULL == a || 0 == length)
return;
for(i=0; flag=0&&i<length; ++i)
{
flag = 1;//在一趟排序后没有进行交换记录,说明不需要排序跳出循环
for(j = i+1; j<length-1; j++)
{
if(a[j] > a[j-1])
{
temp = a[j-1];
a[j-1] = a[j];
a[j] = temp;
flag =0;
}
}
}
}
2.1快速排序
是冒泡排序的一种改进。
http://blog.csdn.net/feixiaoxing/article/details/6845132改博主写的很清楚
void quick_sort( int data[], int length)//验证数据的合法性
{
if( NULL == a || 0 == length)
return;
_quick_sort(data,0,length-1);
}
void _quick_sort(int data[], int left, int right)
{
int pos;
if(left < right)
{
pos = quickOnce(data, left, right); //寻找中间位置
_quick_sort(data, left, pos-1);
_quick_sort(data, pos+1, right);
}
}
/*
* quick once
*/
int quickOnce(int * data, int left, int right)
{
int tmp = data[left];
while(left<right)
{
while(left<right)
{
if(data[right] < tmp)
{
data[left] = data[right];
break;
}
right--;
}
while(left<right)
{
if(data[left] > tmp)
{
data[right] = data[left];
break;
}
left++;
}
}
data[left] = tmp;
return left;
}
3、选择排序
select_sort(int a[], int length)
{
int i,j,k,temp;//k记录
for(i=0; i<length; i++)
{
k = i;
for(j=i+1;j<length-1;j++)
{
if(a[j] < a[k])
k = j;
}
if( i != k)
{
temp = a[i];
a[i] = a[k];
a[k] = temp;
}
}
堆排序