五种排序的思想及其基本实现
1. 简介:这两天重学了冒泡排序、插入排序、选择排序、归并排序、快速排序,这五种排序,现就学到知识做以总结,我的代码风格有所变化,注释不仅成块出现,而且用了英语,语句中的空白运用也有所变化。
2. 算法分析
a. 冒泡排序
在序列中从左到右比较相邻的两个元素,若右边元素小于左边元素则交换(从小到大);
依次遍历比较至指定的位置(冒泡点),同步将最大元素交换至冒泡点,完成一次冒泡;
冒泡点的顺序是从第n个元素位置到第2个元素位置。
伪算法
1> loop( 由大到小遍历冒泡点 [1..n], p )
2> loop( 遍历冒泡点前的元素 [0..p] )
3> 比较当前元素与下一元素的大小,若当前元素大于下一元素则交换
b. 插入排序
将原序列划分为'有序序列'与'无序序列'两个序列;
遍历无序序列,取出当前元素,插入至有序序列中;
当无序原数组遍历完成时,插入排序完成。
伪算法
1> 将原序列分为两个序列,'有序序列'仅含第一个元素,'无序序列'包含剩下的元素。
2> loop( 遍历无序序列,取出当前元素[1..n], p )
3> loop( 遍历有序序列,确定插入点[0..p] )
4> 移动有序数组中数据,为有序序列开辟空间
5> 复制入数据
c. 选择排序
将原序列划分为'有序序列'与'无序序列'两个序列;
在无序序列中找到最小(从小到大排序)的元素, 将其追加到有序序列中, 并在无序序列中删除该元素。
当无序序列为空时,选择排序完成。
伪算法
1> 将原序列分为两个序列,'有序序列'为空,'无序序列'为原序列。
2> loop( 无序序列不为空 )
3> loop( 遍历无序序列,取出最小元素 )
4> 取出当前最小元素,交换至有序序列尾
d. 归并排序
将有n个元素序列的排序问题,划分为2个有n/2个元素序列的排序问题, 再有序连接这2个序列;
再将其划分为4个有n/4个元素序列的排序问题, 再有序连接这4个序列;
......
最终划分成有n/2个有2个元素序列的排序问题, 再有序连接这n/2个序列;
排序完成
伪算法
1> 把n个元素分为两个长度为n/2的元素数组。
2> 归并排序前n/2个元素。
3> 归并排序后n/2个元素。
4> 将两个排好序的逻辑数组合并成一个有序数组。
e. 快速排序
确定一个元素在序列中的有序位置,使其作为分割点,让其左边序列小于它,让其右边序列大于它;
再将左右序列分别取有序分割点,将原序列分成四个序列;
......
最终将n个元素的序列分成,n个序列,确定n-1个有序分割点;
排序完成。
1> 将第一个元素在序列中的位置确定。
2> 快速排序该位置前面的序列。
3> 快速排序该位置后面的序列。
3. 程序实现
/*
* 五种排序思维基本实现
* */
# include <stdio.h>
# define LEN 10
/* 冒泡排序
* */
void bubble_sort( int *base, int len );
/* 插入排序
* */
void insert_sort( int *base, int len );
/* 选择排序
* */
void select_sort( int *base, int len );
/* 归并排序
* */
void merger_sort( int *base, int start, int end );
/* 快速排序
* */
void quick_sort( int *base, int start, int end );
int
main( void )
{
void print( int *base, int len );
int tmp[LEN] = { 55, 32, -1, -12, 15, 4, 7, 0, 15, 40 };
//bubble_sort( tmp, LEN );
//insert_sort( tmp, LEN );
//select_sort( tmp, LEN );
//merger_sort( tmp, 0, LEN - 1 );
quick_sort( tmp, 0, LEN - 1 );
print( tmp, LEN );
return 0;
}
/*
* function: print the valuse arr
* */
void
print( int *base, int len )
{
while (len-- > 0)
printf( "%5d", *base++ );
printf( "\n" );
return;
}
/* function bubble
* */
void
bubble_sort( int *base, int len )
{
int i, j, tmp;
/* 1. Find the current bubble point
* first: len - 1 seat
* last: 1 seat
* 0 seat cannot bubble
*
* 2. Bubble by some method
* */
for (i = len -1; i > 0; i--)
for (j = 0; j < i; j++)
if (base[j] > base[j+1]){
tmp = base[j];
base[j] = base[j+1];
base[j+1] = tmp;
}
return;
}
/* function insert;
* */
void
insert_sort( int *base, int len )
{
int i, j, tmp;
for (i = 1; i < len; i++){
j = i - 1;
tmp = base[i];
/*
* Find insert point and move the array values
* Base[j+1] are always a logical empty element
* */
while (j >= 0 && tmp < base[j])
base[j+1] = base[j--];
base[j+1] = tmp;
}
return;
}
/* function select
* */
void
select_sort( int *base, int len ){
int i, j, tmp;
/* Used current element compare's with others
* Select the min value write's in the current element
* */
for (i = 0; i < len - 1; i++){
for (j = i + 1; j < len; j++)
if (base[i] > base[j]){
tmp = base[i];
base[i] = base[j];
base[j] = tmp;
}
//printf( "NO.%d select the min value is %3d , arr is ", i, base[i] );
//print( base, len );
}
return;
}
/* function merger
* */
void
merger_sort( int *base, int start, int end )
{
void merger( int *base, int start, int mid, int end );
void print_sub( int *base, int start, int end );
if (start < end){
/* Divide */
int mid = ( start + end ) / 2;
//printf( "Sort: ( %d - %d ) AND ( %d - %d )", start, mid, mid+1, end );
//print_sub( base, start, end );
/* Conguer */
merger_sort( base, start, mid );
merger_sort( base, mid + 1, end );
/* combine */
merger( base, start, mid, end);
//printf( "merger: ( %d - %d ) AND ( %d - %d )", start, mid, mid+1, end );
//print_sub( base, start, end );
}
}
/* sub function to merger_sort
* */
void
merger( int *base, int start, int mid, int end ){
/* cnt1 is left lenght, cnt2 is right length */
int cnt1 = mid - start + 1;
int cnt2 = end - mid;
int left[LEN], right[LEN];
int i,j,k;
/* Copy data from base array to left and right array
* */
for ( i = 0, k = start; i < cnt1; i++, k++ )
left[i] = base[k];
for ( i = 0, k = mid + 1; i < cnt2; i++, k++ )
right[i] = base[k];
/* Compare left and right array's data, the smaller insert to base array
* */
for (i = 0, j = 0, k = start; i < cnt1 && j < cnt2; k++)
if (left[i] <= right[j])
base[k] = left[i++];
else
base[k] = right[j++];
/* left[] is not exhausted*/
while (i < cnt1)
base[k++] = left[i++];
/* right[] is not exhausted*/
while (j < cnt2)
base[k++] = right[j++];
return;
}
/* function: used start and end columns, printf a sub array from a array.
* */
void print_sub( int *base, int start, int end )
{
int i;
for (i = start; i != end + 1; i++)
printf( "%3d", base[i]);
printf( "\n" );
return;
}
/* function quick
* */
void
quick_sort( int *base, int start, int end )
{
void print_sub( int *base, int start, int end );
if (end > start){
int partition( int *base, int start, int end );
/* After find partition point, partition base array */
int pos = partition( base, start, end );
//printf( "the partition value is : ( %d ) ", base[pos] );
//printf( "sort(%3d,%3d) AND (%3d,%3d) \n", start, pos-1, pos+1, end );
quick_sort( base, start, pos - 1 );
quick_sort( base, pos + 1, end );
}
}
/* sub function to quick_sort
* */
int
partition( int *base, int start, int end )
{
int tmp = base[start];
while (end > start){
/* first right */
while (end > start)
if( base[end] < tmp ) {
base[start++] = base[end];
break;
} else
end--;
/*second left */
while (end > start)
if (base[start] > tmp) {
base[end--] = base[start];
break;
}else
start++;
}
base[end] = tmp;
return end;
}
Writer: Anden Email: andensemail@163.com Time: 2016.04.26