ALDS1_2_B:Selection Sort

来源:互联网 发布:统计学中数据的类型 编辑:程序博客网 时间:2024/06/15 23:41


选择排序法

重复执行N-1次下述处理

1.找出未排序部分最小值的位置minj。

2.将minj位置的元素与未排序部分的起始元素交换。

以数组A={5,4,8,7,9,3,1}为例,我们对其使用选择排序法时,排序过程如图3.6所示。


    步骤0为初始状态,此时所有元素均属于未排序部分。

    在步骤1中,我们找出未排序部分最小值的位置(minj=6),然后将该位置的元素A[6](=1)与未排序部分的起始元素A[0](=5)进行交换。这样一来,已排序部分就增加了一个元素。

    在步骤2中,找出未排序部分最小值的位置(minj=5),然后将该位置的元素A[5](=3)与未排序部分的起始元素A[1](=4)进行交换。后边的步骤同理,从数组开头按有小到大的顺序逐个确定每个位置的值。

    实现选择排序法时需要的主要变量如图3.7所示。


A[N]             长度为N的整型数组

i                    循环变量,表示未排序部分的开头元素,从数组开头向末尾移动

minj             各轮循环处理中,第i号到第N-1号元素中最小值的位置

j                    循环变量,用来查找未排序部分中最小值的位置(minj)

    在每一轮i的循环中,通过j自增来遍历A[i]到A[N-1],从而确定minj。确定minj后,让起始元素A[i]与最小值元素A[minj]进行交换。

考察

    假设现在有一组由数字和字母组成的数据,我们试着用选择排序法对其进行升序排列。在如图3.8所示的例子里,我们"以数字为基准"进行排序,该排序数组中2个元素带有数字"3",初始状态下其顺序为3H->3D。


    我们会发现,排序结束后这两个元素的顺序反了过来,变成了3D->3H。也就是说,由于选择排序法会直接交换两个不相邻的元素,所以属于不稳定的排序算法。

    然后再来看看选择排序法的复杂度。假设数据总数为N,那么无论在何种情况下,选择排序法都需要进行(N-1)+(N-2)+...+1=(N^2-N)/2次比较运算,用于搜索未排序部分的最小值。因此该算法的复杂度与N^2基本成正比,即复杂度数量级为O(N^2)。

    冒泡排序法与选择排序法相比,一个从局部入手减少逆序元素,一个放眼大局逐个选择最小值,二者思路大不相同。但是,它们又都有着"通过i次外层循环,从数据中顺次求出i个最小值"的相同特征。相对地,插入排序法是通过i次外层循环,直接将原数组的i个元素重新排序。另外,不含flag的简单冒泡排序法和选择排序法不依赖数据,即比较运算的次数(算法复杂度)不受输入数据影响,而插入算法在执行时却依赖数据,处理某些数据时具有很高的效率。

C语言版本:

#include<stdio.h>int selectionSort(int A[],int N){int i,j,t,sw=0,minj;for(i=0;i<N-1;i++){minj=i;for(j=i;j<N;j++){if(A[j]<A[minj])minj=j;}t=A[i];A[i]=A[minj];A[minj]=t;if(i!=minj)sw++;}return sw;}int main(){int A[100],N,i,sw;scanf("%d",&N);for(i=0;i<N;i++)scanf("%d",&A[i]);sw = selectionSort(A,N);for(i=0;i<N;i++){if(i>0)printf(" ");printf("%d",A[i]);}printf("\n");printf("%d\n",sw);return 0;}

C++版本:

#include <iostream>using namespace std; int main(int argc, const char * argv[]) {    //read    int n;    cin>>n;    int a[n];    int count = 0;         for(int i=0;i<n;i++){        cin>>a[i];    }         //solve    for(int i=0;i<n;i++){        int minj = i;        for(int j=i;j<n;j++){            if(a[j]<a[minj]){                minj = j;            }        }        if(a[i]!=a[minj]){            int tmp = a[i];            a[i]=a[minj];            a[minj]=tmp;            count++;        }    }    //output    cout<<a[0];    for(int i = 1;i<n;i++){        cout<<' '<<a[i];    }    cout<<endl;    cout<<count<<endl;}

JAVA版本:

import java.io.*;class Main{    public static void main(String args[])throws IOException    {    BufferedReader input=new BufferedReader(new InputStreamReader(System.in));    int n=Integer.parseInt(input.readLine());    String str=input.readLine();    String str_ary[]=str.split(" ");    int a[]=new int[n];    int x=0;    for(int i=0;i<n;i++)        {        a[i]=Integer.parseInt(str_ary[i]);        }    for(int i=0;i<n;i++)        {        int mini=i;        int lowkey=a[i];        for(int j=i;j<n;j++)            {            if(a[j]<lowkey)                {                mini=j;                lowkey=a[j];                                 }                         }        if(a[i]>lowkey)            {        int temp=a[i];        a[i]=a[mini];        a[mini]=temp;            }        else x++;        }       for(int i=0;i<n;i++)        {        System.out.print(a[i]+((i!=n-1)?" ":"\n"));        }    System.out.println(n-x);    }}

Python版本:

n = int(input())*A, = map(int, input().split())ans = 0for i in range(n):    j = A[i:].index(min(A[i:])) + i    A[i], A[j] = A[j], A[i]    if i != j:        ans += 1print(*A)print(ans)

PHP版本:

<?php$N=(int)trim(fgets(STDIN));$A=explode(' ',trim(fgets(STDIN)));$trade=0;for($i=0;$i<$N;$i++){  $mini=$i;  for($j=$i;$j<$N;$j++) if($A[$j]<$A[$mini]) $mini=$j;  if($mini==$i) continue;  list($A[$i],$A[$mini])=[$A[$mini],$A[$i]];  ++$trade;}echo implode(' ',$A),PHP_EOL,$trade;?>

JavaScript版本:

var input = require('fs').readFileSync('/dev/stdin', 'utf8');var lines = input.split('\n');var n = lines[0];var A = lines[1].split(' ').map(function(i) {return i - 0;});var cnt = 0;for (var i = 0; i < n; i++) {var min = i;for (var j = i; j < n; j++) {if (A[j] < A[min])min = j;}if (min == i)continue;var tmp = A[i];A[i] = A[min];A[min] = tmp;cnt++;}  console.log(A.join(' '));console.log(cnt);

C#版本:

using System; namespace Sort{    class Progarm    {        static void Main()        {            int n = int.Parse(Console.ReadLine());            var a = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);            int c = 0;            for( int i = 0; i < n; i++)            {                int m = i;                for (int j = i; j < n; j++)                    if (a[j] < a[m]) m = j;                int t = a[i];                a[i] = a[m]; a[m] = t;                if (i != m) c++;            }            var r = Array.ConvertAll(a, e => e.ToString());            Console.Write("{0}\n{1}\n", string.Join(" ", r), c);        }    }}

























原创粉丝点击