选择排序原理及代码实现(c/c++)

选择排序与冒泡排序类似,采用逐轮扫描最值然后将其置于顶端的方式完成数组排序。区别是,冒泡法采取的是依次比较相邻元素并不断交换逆序元素的策略,逐步将最值向前推进;而选择排序法采取标记最值位置的策略,扫描过程中不交换元素位置,只修改标记,直至找到最值,将最值交换到顶端。相对于冒泡法,可显著减少交换次数,每轮扫描至多交换1次。

原理:设置最值位置标记,逐轮扫描未排序部分元素最值。每一轮扫描过程中,以未排序部分首部元素为基准(将位置标记设置为未排序首元素下标)与后续元素进行比较。遇到更小(或更大)的元素则将位置标记修改为其下标,直至扫描完成,将标记位置的元素与未排序部分首元素交换位置。至多进行n-1轮扫描,序列完全有序。

步骤

1 轮,所有元素均未经排序,将标记设置为第一个元素下标,以第一个元素为基准依次与后面的元素进行比较,不断修改最值标记为较小元素的下标,经过 n-1 次比较位置标记必将为最值下标,然后将最值与第一个元素交换位置。此时首元素称作已排序部分,其余元素为未排序部分。

i 轮,前 i-1 个元素为已排序部分,将标记设置为第 i 个元素下标,并以第 i 个元素为基准依次与后面的元素进行比较,不断修改最值标记为较小元素的下标,经过 n-i 次比较位置标记必将为最值下标,然后将最值与未排序部分第一个元素(即第 i 个元素)交换位置。此时前 i 个元素有序,其余元素无序。

n-1 轮,将标记设置为第 n-i 个元素下标,然后与最后一个元素进行比较,较小者前置,至此所有元素完成排序。

代码

void selectionsort(int A[], int n)
{
	int mark;
	for (int i = 1; i < n; i++)  //i的取值范围为[1,n-1],共n-1轮
	{
		mark = i-1;   //初始化标记,元素下标从零开始,比轮次落后1
		for (int j = i; j < n; j++)  //j的取值范围为[i,n-1],共比较n-1-i+1次,即n-i次
		{
			if (A[mark]>A[j])        //最值不在标记处则修改标记
				mark = j;
		}
		if (mark != i - 1)           //标记若修改则将最值置换至顶端
		{
			A[mark] = A[mark] + A[i - 1];
			A[i-1] = A[mark] - A[i - 1];
			A[mark] = A[mark] - A[i - 1];
		}
	}
}

 

你可能感兴趣的:(数据结构与算法)