算法学习之排序算法:选择排序

选择排序:每一趟在n-i+1(i=1,2,...,n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录。

一、简单选择排序

一趟选择排序操作:

通过n-i次关键字间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1<=i<=n)个记录交换之。

对L[1...n]中记录进行简单选择排序的算法为:令i从1至n-1,进行n-1趟选择操作。简单选择排序过程中,所需进行记录移动的操作次数较少,然而,无论记录的初始排列如何,所需关键字间的比较次数相同。因此,总的时间复杂度为O(n^2)。

示例代码(C语言描述):

/*********************************************************************
 Author:李冰 date:2014-9-11
 Email:[email protected]
 @array: the pointer to the records
 @length:the length of the records
*********************************************************************/
//交换数据
void Swap(int *num1, int *num2)
{
	int tmp = *num1;
	*num1 = *num2;
	*num2 = tmp;
}

void SelectSort(int array[], int length)
{
	if(array == NULL || length <= 0)
		return;

	int i, j, index;

	for(i = 0; i < length; i++){

		index = i;

		for(j = i + 1; j < length; j++)
			if(array[j] < array[index])
				index = j;

		if(i != index)
			Swap(&array[i], &array[index]);
	}
}

二、树形选择排序(锦标赛排序)

树形选择排序又称锦标赛排序。首先对n个记录的关键字进行两两比较,然后在其中n/2个较小者之间再进行两两比较,如此重复,直至选出最小关键字的记录为止。该过程可用一颗有n个叶子结点的完全二叉树表示。

代码示例(C语言描述):

/*
 * 对树进行筛选:从叶子节点开始,两两一起选出最小的,作为双亲
 */
static void AdjustTree(int *Tree,int length,int high){
	/*调整至根节点,结束调整*/
	if(length==1){
		return;
	}
	else{
		int nextlength=(length+1)/2;
		int adjustpos=high-length+1-nextlength;
		/*选择两个叶子,选择其中较小的作为两个叶子的双亲*/
		for(int i=high-length+1;i<=high;i+=2){
			/*
			 * 可能最后一个选择时,只有一个叶子,即奇数个叶子
			 * 依然应该把剩下的叶子Tree[i]作为自己的双亲
			 * 所以 i<high 不能丢
			 */
			if( (i<high)&&(Tree[i]>Tree[i+1]) ){
				Tree[adjustpos]=Tree[i+1];
			}
			else{
				Tree[adjustpos]=Tree[i];
			}
			adjustpos++;
		}
		AdjustTree(Tree,nextlength,high-length);
	}
}
/*
 * 根据最底层节点个数n,返回整棵树的节点数
 */
static int GetTreeSize(int n){
	if(n==1){
		return 1;
	}
	else{
		return (n+GetTreeSize((n+1)/2));
	}
}
/*
 * 对sq+1,sq+2,sq+3,...,sq+length 进行树形选择排序
 */
void TreeSelectSort(int *sq,int length){
	/*根据叶子节点数为length,创建一个二叉树,用顺序存储结构表示*/
	/* 7个叶子,需要节点数为 7+4+2+1=14

                O
              /                 O       O
            /\      /            O  O    O   O
          /\  /\  /\  /
         O  OO O O  OO
	*/
	/*Tree指向这个二叉树的指针,TreeSize保存二叉树的节点总数*/
	int TreeSize=0;
	int *Tree=NULL;

	TreeSize=GetTreeSize(length);
	//printf("\nTreeSize=%d\n",TreeSize);
	Tree=(int *)malloc(TreeSize*sizeof(int));

	if(Tree!=NULL){
		memset(Tree,0,TreeSize*sizeof(int));
		//复制序列到树结构中
		for(int i=TreeSize-length,j=1;i<TreeSize;i++,j++){
			Tree[i]=sq[j];
		}
		for(int pos=1;pos<=length;){
			AdjustTree(Tree,length,TreeSize-1);

			printf("Min node =%d\n",Tree[0]);
			//选出所有关键字等于当前最小的记录,填到结果中
			for(int i=TreeSize-length;i<TreeSize;i++){
				if(Tree[i]==Tree[0]){
					Tree[i]=MAX_INT;
					/*
					 * 20120910更改此处的 break
					 * 原因是:如果有大量数据重复,对每个重复的数据也进行选择效率太低
					 * 对一个关键字选择后,对所有关键字等于这个关键字的记录都应不再进行选择
					 */
					//break;
					sq[pos]=Tree[0];
					pos++;
					/*
					 * 注意这点:pos++ 的位置,并没有放在for循环中
					 * 因为每次筛选出来的最小关键字肯定存在于叶子节点中
					 * if(Tree[i]==Tree[0])至少成立一次
					 * 如果不止成立一次,即有相同关键字,则应该减少筛选次数
					 */
				}
			}
		}

		free(Tree);
		Tree=NULL;
	}
}

由于含有 n 个叶子节点的完全二叉树的深度为  『( log2(N) )+1 ,则在树形选择排序中除最小关键字之外,每选择一个次小关键字仅需进行 『( log2(N) )次比较,因此它的时间复杂度为 O(NlogN)。『代表上取整

参考文献:

1、《数据结构(C语言描述)
严蔚敏 吴伟东 编著

2、http://blog.csdn.net/to_be_it_1/article/details/37866391

3、http://blog.csdn.net/zhccl/article/details/7960983

4、http://blog.csdn.net/morewindows/article/details/6671824

时间: 2024-12-14 05:31:50

算法学习之排序算法:选择排序的相关文章

经典排序算法学习笔记五——直接选择排序

一.直接选择排序 数据结构 数组 最差时间复杂度 O(n^2) 最优时间复杂度 O(n^2) 平均时间复杂度 O(n^2) 最差空间复杂度 О(n) total, O(1) auxiliary 1.算法思想: 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置. 然后,再从剩余未排序元素中继续寻找最小(大)元素,放到已排序序列的末尾. 以此类推,直到所有元素均排序完毕. 2.伪代码: repeat (numOfElements - 1) times set the first uns

算法基础之排序(2)--选择排序 改进

1 /********************************************************************************************************** 2 * Function : test 3 * Create Date : 2014/03/23 4 * Author : NTSK13 5 * Email : [email protected] 6 * Copyright : 欢迎大家和我一起交流学习,转载请保持源文件的完整性

基础算法之排序(2)--选择排序

1 /********************************************************************************************************** 2 * Function : test 3 * Create Date : 2014/03/23 4 * Author : NTSK13 5 * Email : [email protected] 6 * Copyright : 欢迎大家和我一起交流学习,转载请保持源文件的完整性

【排序】选择排序算法

特别说明 对于算法,重在理解其思想.解决问题的方法,思路.因此,以下内容全都假定待排序序列的存储结构为:顺序存储结构. 选择排序思想 选择排序又称为简单选择排序,主要思想描述如下: 01.假设待排序列表为 .选择排序将  划分为由已排序好序的  部分 以及 未排序的  部分: 注意:刚开始时  部分其实可认为只有一个元素,即: 元素 02.每次从  部分中选出最小(或最大)的那个元素,将其放在  的末尾位置: 03.重复02步骤,直到  部分为空为止: 编码参考 简单选择排序是非常简单的一种排序

排序算法6--选择排序--简单选择排序

简单选择排序 简单选择排序属于选择排序, 选择排序的思想是:每一趟从待排序的记录中选出关键字最小的记录,按顺序放在以排序的记录序列的后面,知道全部排完为止. 1.简单选择排序法是每次循环找出最值,循环结束后将最值调整到合适位置,交换的次数少. 每次找出当前无序队列中的最小的元素与第一个交换位置,再选择第二小的与第二个交换位置 原始队列:   3 5 6 2 4 1(最小元素1与3交换) 第一步: 1 5 6 2 4 3 (当前最小元素2与5交换) 第二步: 1 2 6 5 4 3 (当前最小元素

十大排序算法之(三)——选择排序

#1,选择排序简介 选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完. 选择排序是不稳定的排序方法(比如序列[5, 5, 3]第一次就将第一个[5]与[3]交换,导致第一个5挪动到第二个5后面),我个人认为,按照数值来讲,这两个5没差别,所以这是不是决定这个算法不稳定还有待商榷. #2,c++实现算法 #include<iostream>#include&l

简单排序之选择排序算法JAVA实现

选择排序原理 选择排序是一种简单排序算法.这是一个基于位置比较的算法,通常实现是左边是已经排好序的元素列表,右边是待排序的元素.当然,一开始的时候,我们认为都是未经排序的. 选择排序的精髓:与冒泡排序不同,选择排序是第N趟排序先确定最小元素的位置,然后和第N个元素交换位置.主要特点是每一趟选择一个最小值的索引作为梅一堂最后交换的位置.以一个元素个数为N的整形数组arr为例: 第一趟 以第一个元素arr[0]为基准,准备好一个中间变量temp用来记录该趟最小元素的位置,一开始,temp=0,比较a

选择排序—简单选择排序(Simple Selection Sort)

基本思想: 在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换:然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止. 简单选择排序的示例: 操作方法: 第一趟,从n 个记录中找出关键码最小的记录与第一个记录交换: 第二趟,从第二个记录开始的n-1 个记录中再选出关键码最小的记录与第二个记录交换: 以此类推..... 第i 趟,则从第i 个记录开始的n-i+1 个记录中选出关键码最小的记录与

排序(1)---------选择排序(C语言实现)

选择排序的基本思想: 选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理如下.首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾.以此类推,直到所有元素均排序完毕. 我的通俗解释: ①第一遍先在整个序列中寻找到最小值,将其移到首位,序列被分为1,n-1; ②继续在n-1中寻找最小值,将其移到n-1的首位,也就是整个序列的第二位 ③以此类推,反复操作步骤②,得到结果 选择排序的主要优

选择排序—简单选择排序(Simple Selection Sort)原理以及Java实现

基本思想: 在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换:然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止. 简单选择排序的示例: 操作方法: 第一趟,从n 个记录中找出关键码最小的记录与第一个记录交换: 第二趟,从第二个记录开始的n-1 个记录中再选出关键码最小的记录与第二个记录交换: 以此类推..... 第i 趟,则从第i 个记录开始的n-i+1 个记录中选出关键码最小的记录与