排序-选择排序-简单选择排序(直接选择排序)

简单选择排序

简单选择排序Simple Selection Sort)也称作直接选择排序

算法思路

[算法步骤]

① 设待排序的记录窜访在数组r[1…n]中。第一趟从r[1]开始,通过n-1次比较,从n个记录中选出关键字最小的记录,记为r[k],交换r[1]和r[k]。
② 第二趟从r[2] 开始,通过n-2次比较,从n-1个记录中选出关键字最小的记录,记为r[k],交换r[2]和r[k]。
③ 依次类推,第i趟从r[i]开始,通过n-i次比较,从n-i+1个记录中选出关键字最小的记录,以为r[k],交换r[i]和r[k]。
④ 经过n-1趟,排序完成。

算法实现

定义存放记录的线性表结构

//记录
typedef struct ElemType{
    
    
    int key;
    string info;
}ElemType;

#define InitSize 50
typedef struct {
    
    
    ElemType data[InitSize];
    int length;
}SqList;

void toString(SqList L);

void toString(SqList L,int low,int high);

void InitSqList(SqList &L);

代码实现

void SelectSort(SqList &L) {
    
    
    ElemType min = L.data[0];
    for (int i = 0; i < L.length-1; i++) {
    
    
        int k = i;
        cout << " -----------------第" << k+1 << "趟排序--------------------- "
             << endl;
        cout << "初始min r["<< k <<"]= " << L.data[k].key
             << endl;
        for (int j = i + 1; j < L.length; j++) {
    
    
            if (L.data[j].key < L.data[k].key) {
    
    
                k = j;
                cout << "新的min r["<< k <<"]= " << L.data[k].key << endl;
            }
        }
        if (k != i) {
    
    
            swap(L.data[i], L.data[k]);
        }
        cout << "有序 " ;
        toString(L,0,i);
        cout << "待排序 " ;
        toString(L,i+1,L.length-1);
    }
}

测试案例

void testSelectSort(){
    
    
    SqList L;
    InitSqList0(L);
    cout <<" ----------------------------初始 L----------------------------------"<< endl;
    toString(L,0,L.length-1);
    SelectSort(L);
    cout <<" -------------------------最终排序结果--------------------------------"<< endl;
    toString(L,0,L.length-1);

}
int main() {
    
    
    testSelectSort();
    return 0;
}

测试结果

 ----------------------------------初始 L----------------------------------------
 [ 41 67 34 0 69 24 78 58 62 64 ]
 -----------------------------------1趟排序--------------------------------------- 
初始min r[0]= 41
新的min r[2]= 34
新的min r[3]= 0
有序  [ 0 ]
待排序  [ 67 34 41 69 24 78 58 62 64 ]
 -----------------------------------2趟排序--------------------------------------- 
初始min r[1]= 67
新的min r[2]= 34
新的min r[5]= 24
有序  [ 0 24 ]
待排序  [ 34 41 69 67 78 58 62 64 ]
 -----------------------------------3趟排序--------------------------------------- 
初始min r[2]= 34
有序  [ 0 24 34 ]
待排序  [ 41 69 67 78 58 62 64 ]
 -----------------------------------4趟排序--------------------------------------- 
初始min r[3]= 41
有序  [ 0 24 34 41 ]
待排序  [ 69 67 78 58 62 64 ]
 -----------------------------------5趟排序--------------------------------------- 
初始min r[4]= 69
新的min r[5]= 67
新的min r[7]= 58
有序  [ 0 24 34 41 58 ]
待排序  [ 67 78 69 62 64 ]
 -----------------------------------6趟排序--------------------------------------- 
初始min r[5]= 67
新的min r[8]= 62
有序  [ 0 24 34 41 58 62 ]
待排序  [ 78 69 67 64 ]
 -----------------------------------7趟排序--------------------------------------- 
初始min r[6]= 78
新的min r[7]= 69
新的min r[8]= 67
新的min r[9]= 64
有序  [ 0 24 34 41 58 62 64 ]
待排序  [ 69 67 78 ]
 -----------------------------------8趟排序--------------------------------------- 
初始min r[7]= 69
新的min r[8]= 67
有序  [ 0 24 34 41 58 62 64 67 ]
待排序  [ 69 78 ]
 -----------------------------------9趟排序--------------------------------------- 
初始min r[8]= 69
有序  [ 0 24 34 41 58 62 64 67 69 ]
待排序  [ 78 ]
 -------------------------------最终排序结果--------------------------------------
 [ 0 24 34 41 58 62 64 67 69 78 ]

进程已结束,退出代码0

算法分析

① 时间复杂度:

简单选择排序过程中,所需进行记录移动次数较少。

  • 最好情况(正序):不移动;
  • 最坏情况(逆序):移动3(n-1)次。

然而,无论记录的初始排序如何,所需进行的关键字间的比较次数相同,均为
KCN=(n-1)+(n-2)+…+(3-1)+(2-1)=n(n-1)/2
因此,简单选择排序的时间复杂度为O(n^2/2)

② 空间复杂度

同冒泡排序一样,只有在两个记录交换时需要一个辅助空间,所以空间复杂度为O(1)

[算法特点]

① 本身时稳定的排序方法,采用”交换记录“的策略会产生不稳定的现象
② 可用于链式结构
③ 移动记录次数较少,当每一项记录占用空间较大时,简单选择排序比直接插入排序快。

猜你喜欢

转载自blog.csdn.net/QQ657205470/article/details/127754354