问题描述 :
对于顺序存储的线性表,使用vector或数组,实现折半插入排序算法,并输出每趟的排序结果。
参考函数原型:(vector版本)
//折半插入排序
template<class ElemType>
void BinInsertSort( vector<ElemType> &A );
输入说明 :
第一行:顺序表A的数据元素的数据类型标记(0:int,1:double,2:char,3:string)
第二行:待排序顺序表A的数据元素(数据元素之间以空格分隔)
输出说明 :
如第一行输入值为0、1、2、3之外的值,直接输出“err”
否则:
第一行:第一趟的排序结果
第三行:第二趟的排序结果
...
第n行:最终的排序结果
输入范例 :
0
49 38 65 97 76 13 27 49 55 4
输出范例:
38 49 65 97 76 13 27 49 55 4
38 49 65 97 76 13 27 49 55 4
38 49 65 97 76 13 27 49 55 4
38 49 65 76 97 13 27 49 55 4
13 38 49 65 76 97 27 49 55 4
13 27 38 49 65 76 97 49 55 4
13 27 38 49 49 65 76 97 55 4
13 27 38 49 49 55 65 76 97 4
4 13 27 38 49 49 55 65 76 97
思路:
一个想得到的改进方法:既然直插的子表有序且为顺序存储结构,则插入时采用折半查找一定可以加速。
方法:确定第i个纪录所应插入的位置,采用折半查找方法。
优点:可减少关键字的比较次数。每插入一个元素,需要比较的次数最大为折半判定树的深度,改善了算法中的比较次数,全部元素比较次数仅为O(nlog2n)。
时间效率:虽然比较次数大大减少,可惜移动次数并未减少,所以排序效率仍为O(n2) 。
空间效率:仍为 O(1)。
稳定性:稳定。
解题代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <stdlib.h>
#include <cmath>
#include <vector>
#include <sstream> //用于ostringstream、istringstream、stringstream这三个类
#include<stack>
#include<vector>
#include<queue>
#define ArraySize 100
using namespace std;
template<class ElemType>
void createvector( vector<ElemType> &A )
{
A.push_back(0);//设置A[0],方便之后例如直插等存放哨兵
ElemType tmp;
string temp;
getline(cin,temp);
stringstream input(temp); //输入流
while(input>>tmp)
A.push_back(tmp);
}
//折半插入排序
template<class ElemType>
void BinInsertSort( vector<ElemType> &A ){
int length=A.size()-1;
if(length==1){
cout<<A[1]<<endl;
}
else{
int m=2;
while(m<length+1){
if(A[m]>=A[m-1])
m++;
else{
int low=1; //mid范围【1,m-1】不会下标越界,不用哨兵
int high=m-1;
int mid=(1+m-1)/2;
while(low<=high){
mid=(high+low)/2;
if(A[m]<A[mid])
high=mid-1;
else if(A[m]>=A[mid])
low=mid+1;
}
//大于等于最终的mid就插其后,小于就插其前
if(A[m]>=A[mid])
{
ElemType s=A[m];
for(int i=m;i>mid+1;i--)
A[i]=A[i-1];
A[mid+1]=s;
}
else{
ElemType s=A[m];
for(int i=m;i>mid;i--)
A[i]=A[i-1];
A[mid]=s;
}
m++;
}
for(int i=1;i<length;i++)//排序数据从A[1]开始,从第一次排序结束开始输出
cout<<A[i]<<" ";
cout<<A[length]<<endl;
}
}
}
int main()
{
int kd;
cin>>kd;
cin.ignore();
if(kd==0){
vector<int> A;
createvector( A );
BinInsertSort( A );
}
else if(kd==1){
vector<double>A;
createvector( A );
BinInsertSort( A );
}
else if(kd==2){
vector<char>A;
createvector( A );
BinInsertSort( A );
}
else if(kd==3){
vector<string >A;
createvector( A );
BinInsertSort( A );
}
else
cout<<"err"<<endl;
return 0;
}