选择排序法

83 篇文章 2 订阅
10 篇文章 0 订阅

算法原理

直接 选择 排序 的 基本 思想: n 个 记录 的 直接 选择 排序 可 经过 n- 1 趟 直接 选择 排序 得到 有序 结果。

(1) 初始 状态: 无序 区 为 A[ 1... n], 有序 区 为 空。

(2) 第 1 趟 排序: 在 无序 区 A[ 1... n] 中选 出 最小 的 记录 A[ k], 将它 与 无序 区 的 第 1 个 记录 A[ 1] 交换, 使 A[ 1… 1] 和 A[ 2... n] 分别 变为 记录 个数 增加 1 的 新 有序 区 和 记录 个数 减少 1 的 新 无序 区。

(3) 第 i 趟 排序: 第 i 趟 排序 开始时, 当前 有序 区 和 无序 区分 别为 A[ 1… i- 1] 和 A[ i.. n]( 1 ≤ i ≤ n- 1)。 该 趟 排序 从 当前 无序 区 中 选出 关键字 最小 的 记录 A[ k], 将它 与 无序 区 的 第 1 个 记录 A[ i] 交换, 使 A[ 1… i] 和 A[ i+ 1... n] 分别 变为 记录 个数 增加 1 的 新 有序 区 和 记录 个数 减少 1 的 新 无序 区。

这样, n 个 记录 的 文件 的 直接 选择 排序 可 经过 n- 1 趟 直接 选择 排序 得到 有序 结果。 直接 选择 排序 是 不稳 定的。

算法草稿,三角列表示本轮排序后的结果

 

 

算法实现

#include <stdio.h>
#include <stdlib.h>


#define SUCCESS		0
#define PARAM_ERR	-1

int getMinPoS(int * array, int low, int high){
	if(NULL == array || low > high){
		printf("%s para error", __func__);
		return PARAM_ERR;
	}	
	
	int i = 0;
	int minPoS = low;
	int min = array[low];

	/*千万注意这里是 <= high, 因为数组的最后一个是high (n-1)*/
	for(i = low; i <= high; i++){
		if(array[i] < min ){
			minPoS = i;
			min = array[i];
		}
	}

	return minPoS;
}

int SelectSort(int * array, int size){
	if(NULL == array){
		printf("%s para error", __func__);
		return PARAM_ERR;
	}

	int i = 0, j = 0;
	int minPoS = 0; /*当前无序区最小值的位置*/
	int temp = 0;
#ifdef DEBUG
		int k = 0;
#endif

	for(i = 0; i < size; i++){ /* 无序区域起始位置逐步向后 */
		
		/*无序区处理,此时 i 还属于无序区,无序区为 [i,.... n-1], 找到无序区最小位置minPoS*/
		/*升序*/
		minPoS = getMinPoS(array, i, size - 1);

		/* 交换最小值到i,通过i++, 将i并入有序区域 */
		if(minPoS != i){
			temp = array[minPoS];
			array[minPoS] = array[i];
			array[i] = temp;
		}

#ifdef DEBUG		
		printf("i = %d min = %d\n", i, temp);				
		printf("[");
		/*有序区域*/
		for(k =0; k < i+1; k++){
			printf("  %d  ", array[k]);
		}
		printf("] ");

		/*无序区域*/
		printf("[");
		for(k = i+1; k < size; k++){
			printf("  %d  ", array[k]);
		}
		printf("]\n");
		printf("\n");
#endif		
	}

	return SUCCESS;
	
}


int main(int argc, char ** argv){
	int array[10] = {7,3,5,8,0,9,1,2,4,6};
	int i = 0;

	printf("Before sort: \n");
	for(i = 0; i < 10; i++){
		printf("  %d  ", array[i]);
	}
	printf("\n");
	

	SelectSort(array, 10);

	printf("after sort: \n");
	for(i = 0; i < 10; i++){
		printf("  %d  ", array[i]);
	}
	printf("\n");
	
	return 0;
}



调试编译

gcc SelectSort.c -DDEBUG

调试输出

Before sort:
  7    3    5    8    0    9    1    2    4    6
i = 0 min = 0
[  0  ] [  3    5    8    7    9    1    2    4    6  ]

i = 1 min = 1
[  0    1  ] [  5    8    7    9    3    2    4    6  ]

i = 2 min = 2
[  0    1    2  ] [  8    7    9    3    5    4    6  ]

i = 3 min = 3
[  0    1    2    3  ] [  7    9    8    5    4    6  ]

i = 4 min = 4
[  0    1    2    3    4  ] [  9    8    5    7    6  ]

i = 5 min = 5
[  0    1    2    3    4    5  ] [  8    9    7    6  ]

i = 6 min = 6
[  0    1    2    3    4    5    6  ] [  9    7    8  ]

i = 7 min = 7
[  0    1    2    3    4    5    6    7  ] [  9    8  ]

i = 8 min = 8
[  0    1    2    3    4    5    6    7    8  ] [  9  ]

i = 9 min = 8
[  0    1    2    3    4    5    6    7    8    9  ] []

after sort:
  0    1    2    3    4    5    6    7    8    9

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值