目录
选择排序
1.算法思路:
- 选择排序----最简单也最没用的排序算法,有优化空间
- 计算时间、空间复杂度
- 算法验证----随机数据生成器和对数器
- 算法程序思路
思路:
- 一遍一遍的遍历数组找最小数的位置
- 和第一位交换
算法程序写法:
- 由简单到复杂:
验证一步步走;
多打印中间结果;
- 先局部后整体
没思路先细分
- 先粗糙后精细
变量更名
语句合并
边界处理
2.选择排序特点
特点:时间复杂度高,不稳定
不稳定:两个相等的数排序后改变相对位置
以下排序后,改变了两个3的相对位置
3 2 3 1 5
1 2 3 3 5
3. C++ 基本实现:
思路:
- 每次遍历选择并记录最小值的索引
- 使用最小值索引和开始找最小值的起点交换
#include<iostream>
#include<stdio.h>
using namespace std;
class selection{
public:
selection(){};
~selection(){};
int select(int arg[], int len)
{
if(NULL ==arg){
return (-1);
}
int Index;
for(int i=0; i<len-1; ++i)
{
Index = i;
for(int j=i+1; j<len; ++j)
{
if(arg[Index]>arg[j])
Index =j;
}
swap(arg[i],arg[Index]);
}
return 0;
}
void print(int arg[],int len){
for(int i =0; i<len; ++i)
{
cout<< arg[i]<<" ";
}
cout<<endl;
}
private:
void swap(int &a,int &b)
{
int tmp;
tmp =a;
a= b;
b= tmp;
}
};
int main(){
int arg[]={9,1,178,3,4,15,6,17,8,19};
selection sel;
sel.print(arg, sizeof(arg)/sizeof(int));
sel.select(arg, sizeof(arg)/sizeof(int));
sel.print(arg, sizeof(arg)/sizeof(int));
}
c++ 实现: 遍历一次同时寻找最大最小值,循环减少1/2
#include<iostream>
#include<stdio.h>
using namespace std;
class selection{
public:
selection(){};
~selection(){};
int select(int arg[], int len)
{
if(NULL ==arg){
return (-1);
}
int minIndex;
int maxIndex;
for(int i=0; i<len/2; ++i)
{
minIndex = i;
maxIndex = i;
for(int j=i+1; j<len-i; ++j)
{
if(arg[minIndex]>arg[j])
minIndex =j;
if(arg[maxIndex]<arg[j])
maxIndex =j;
}
// print(arg, len);
// std::cout << minIndex<<" "<< maxIndex<< std::endl;
swap(arg[i],arg[minIndex]);
if(i==maxIndex)
maxIndex = minIndex;
swap(arg[len-i-1],arg[maxIndex]);
// print(arg, len);
}
return 0;
}
void print(int arg[],int len){
for(int i =0; i<len; ++i)
{
cout<< arg[i]<<" ";
}
cout<<endl;
}
private:
void swap(int &a,int &b)
{
int tmp;
tmp =a;
a= b;
b= tmp;
}
};
int main(){
int arg[]={9,1,178,3,4,15,6,17,8,19};
selection sel;
sel.print(arg, sizeof(arg)/sizeof(int));
sel.select(arg, sizeof(arg)/sizeof(int));
sel.print(arg, sizeof(arg)/sizeof(int));
}
4. 验证算法--对数器
如何验证算法正确?
- 肉眼观察
- 产生足够多随机样本
- 用确定正确的算法计算样本结果 -- 系统自带的
- 对比被验证的算法结果
#include<iostream>
#include<stdio.h>
#include<ctime>
#include<cstdlib>
#include<string.h>
#include<algorithm>
using namespace std;
class selection{
public:
selection(){};
~selection(){};
int sort(int arg[], int len)
{
if(NULL ==arg){
return (-1);
}
int minIndex;
int maxIndex;
for(int i=0; i<len/2; ++i)
{
minIndex = i;
maxIndex = i;
for(int j=i+1; j<len-i; ++j)
{
if(arg[minIndex]>arg[j])
minIndex =j;
if(arg[maxIndex]<arg[j])
maxIndex =j;
}
// print(arg, len);
// std::cout << minIndex<<" "<< maxIndex<< std::endl;
swap(arg[i],arg[minIndex]);
if(i==maxIndex)
maxIndex = minIndex;
swap(arg[len-i-1],arg[maxIndex]);
// print(arg, len);
}
return 0;
}
void print(int arg[],int len){
for(int i =0; i<len; ++i)
{
cout<< arg[i]<<" ";
}
cout<<endl;
}
void genRandArr(int arg[],int len ){
srand(time(0));
for(int i =0; i<len; ++i){
arg[i]=rand()%10;
}
}
void compare(int arg[], int arg1[], int len){
bool same =true;
static int index =0;
for(int i =0; i<len; ++i){
if(arg[i]!=arg1[i]) {same=false; index =i; }
}
// cout<< arg[index] <<" "<< arg1[index] <<" "<< index <<endl;
// cout<< (same==true ? "right":"wrong")<<endl;
same==false ? cout<<"wrong"<<endl: same =true;
}
private:
void swap(int &a,int &b){
int tmp;
tmp =a;
a= b;
b= tmp;
}
};
bool cmp(int a, int b){
return a<b;
}
#define ARR_SIZE 1000
int main(){
int arg[ARR_SIZE];
int arg1[ARR_SIZE];
selection sel;
for(int i =0;i<1000;++i){
sel.genRandArr(arg,sizeof(arg)/sizeof(int));
memcpy((void*)arg1,(void *)arg, sizeof(arg));
//sel.print(arg, sizeof(arg)/sizeof(int));
sel.sort(arg, sizeof(arg)/sizeof(int));
sort(arg1, arg1+ARR_SIZE,cmp);
sel.compare(arg,arg1,sizeof(arg)/sizeof(int));
//sel.print(arg, sizeof(arg)/sizeof(int));
//sel.print(arg1, sizeof(arg)/sizeof(int));
}
}
5.证明选择排序不稳定
建立另个数组专门存放下标信息
排序时同时swap数组下标数组
对数组遍历,相同数据比较下标,大于报错
#include<iostream>
#include<stdio.h>
#include<ctime>
#include<cstdlib>
#include<string.h>
#include<algorithm>
using namespace std;
class selection{
public:
selection(){};
~selection(){};
int sort(int arg[], int len)
{
if(NULL ==arg){
return (-1);
}
int minIndex;
int maxIndex;
for(int i=0; i<len/2; ++i)
{
minIndex = i;
maxIndex = i;
for(int j=i+1; j<len-i; ++j)
{
if(arg[minIndex]>arg[j])
minIndex =j;
if(arg[maxIndex]<arg[j])
maxIndex =j;
}
// print(arg, len);
// std::cout << minIndex<<" "<< maxIndex<< std::endl;
swap(arg[i],arg[minIndex]);
if(i==maxIndex)
maxIndex = minIndex;
swap(arg[len-i-1],arg[maxIndex]);
// print(arg, len);
}
return 0;
}
int sort(int arg[], int arg1[],int len)
{
if(NULL ==arg){
return (-1);
}
int minIndex;
int maxIndex;
for(int i=0; i<len/2; ++i)
{
minIndex = i;
maxIndex = i;
for(int j=i+1; j<len-i; ++j)
{
if(arg[minIndex]>arg[j])
minIndex =j;
if(arg[maxIndex]<arg[j])
maxIndex =j;
}
// print(arg, len);
// std::cout << minIndex<<" "<< maxIndex<< std::endl;
swap(arg[i],arg[minIndex]);
swap(arg1[i],arg1[minIndex]);
if(i==maxIndex)
maxIndex = minIndex;
swap(arg[len-i-1],arg[maxIndex]);
swap(arg1[len-i-1],arg1[maxIndex]);
// print(arg, len);
}
return 0;
}
void print(int arg[],int len){
for(int i =0; i<len; ++i)
{
cout<< arg[i]<<" ";
}
cout<<endl;
}
void genRandArr(int arg[],int len ){
srand(time(0));
for(int i =0; i<len; ++i){
arg[i]=rand()%10;
}
}
void genArr(int arg[],int len ){
for(int i =0; i<len; ++i){
arg[i]=i;
}
}
void compare(int arg[], int arg1[], int len){
bool same =true;
static int index =0;
for(int i =0; i<len; ++i){
if(arg[i]!=arg1[i]) {same=false; index =i; }
}
// cout<< arg[index] <<" "<< arg1[index] <<" "<< index <<endl;
// cout<< (same==true ? "right":"wrong")<<endl;
same==false ? cout<<"wrong"<<endl: same =true;
}
void checkstab(int arg[], int arg1[] ,int len ){
for(int i =0; i<len-1;++i){
for(int j= i+1; j<len;j++){
if(arg[i]==arg[j]){
cout<<(arg1[i]<arg1[j] ? "right":"wrong")<<endl;
}
}
}
}
private:
void swap(int &a,int &b){
int tmp;
tmp =a;
a= b;
b= tmp;
}
};
bool cmp(int a, int b){
return a<b;
}
#define ARR_SIZE 4
int main(){
int arg[ARR_SIZE]={7,4,7,2};
int arg1[ARR_SIZE];
selection sel;
for(int i =0;i<1;++i){
// sel.genRandArr(arg,sizeof(arg)/sizeof(int));
sel.genArr(arg1,sizeof(arg)/sizeof(int));
sel.print(arg1,sizeof(arg)/sizeof(int));
sel.print(arg,sizeof(arg)/sizeof(int));
sel.sort(arg,arg1, sizeof(arg)/sizeof(int));
sel.checkstab(arg,arg1, sizeof(arg)/sizeof(int));
sel.print(arg1,sizeof(arg)/sizeof(int));
sel.print(arg,sizeof(arg)/sizeof(int));
}
}