选择排序

选择排序

选择排序算法通过重复查找未排序部分的最小元素(考虑升序)并将其放在开头来对数组进行排序。该算法在给定的数组中维护两个子数组:

  • 已经排序的子数组。
  • 未排序的剩余子阵列。

在选择排序的每次迭代中,从未排序的子数组中拾取最小元素(考虑升序)并将其移动到排序的子数组。

以下示例说明了上述步骤:

ARR[]=64 25 12 22 11。

//查找arr[0...4]中的最小元素。
//并将其放在开头。
11 25 12 22 64。

//查找arr[1...4]中的最小元素。
//并将其放在arr[1...4]的开头。
11 12 25 22 64。

//查找arr[2...4]中的最小元素。
//并将其放在arr[2...4]的开头。
11 12 22 25 64。

//查找arr[3...4]中的最小元素。
//并将其放在arr[3...4]的开头。
11 12 22 25 64

代码实现

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


int *getRandArray(int max, int min, int n)
{
    srand(time(NULL));
    int *array = (int *)malloc(sizeof(int) * n);
    for(int i=0; i<n; i++) 
        array[i] = rand() % max + min;
    return array;
}

void printArray(int *array, int n)
{
    for(int i=0; i<n; i++)
        printf("%d ", array[i]);
    printf("\n\n");
}

void swap(int *xp, int *yp)  
{  
    int temp = *xp;  
    *xp = *yp;  
    *yp = temp;  
}  


void selectionSort(int arr[], int n)
{
    int i, j, min_idx;
    // 逐个移动未排序数组的边界
    for(int i=0; i<n-1; i++) {
        min_idx = i;
        // 在未排序数组中的查找最小元素
        for(int j=i+1; j<n; j++) {
            if(arr[j] < arr[min_idx])
                min_idx = j;
        }
        // 将找到的最小元素与第一个元素交换
        swap(&arr[min_idx], &arr[i]);
    }
}

int main()
{
    int len = 30;
    int *arr = getRandArray(100, 1, len);
    printArray(arr, len);

    // 排序
    selectionSort(arr, len);
    printArray(arr, len);

    free(arr);
    return 0;
}

时间复杂度:O(N2),因为有两个嵌套循环。

辅助空间:O(1)。
选择排序的好处是它从来不会进行超过O(N)的交换,并且在内存写入是一个代价高昂的操作时非常有用。

练习:

  • 使用选择排序对字符串数组进行排序。

稳定性:默认实现不稳定。但是,可以使其稳定。

就地完成:是的,它不需要额外的空间。

posted @ 2019-11-21 11:38  wjundong  阅读(114)  评论(0编辑  收藏  举报