五种排序的思想及其基本实现

五种排序的思想及其基本实现
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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值