改进的冒泡排序
//time:26.760s
#include<cstring>
#include<iostream>
#include<fstream>
#include<algorithm>
using namespace std;
class MY{
int a;
//public:
friend ostream& operator <<(ostream& os,const MY &my){
os<<my.a;return os;
}
friend istream& operator >>(istream& is,MY& my){
is>>my.a;return is;
}
public:
bool operator<(const MY& another){
return this->a<another.a;
}
};
template<class T>
void bubble(T A[],int n)
{
int isSorted=0;
for(int i=n-1;i>=1&&!isSorted;i--){
isSorted=1;
for(int j=0;j<i;j++)
if(A[j+1]<A[j]) {swap(A[j+1],A[j]);isSorted=0;}
}
}
template<typename T>
bool check_if_sorted(T A[],int n)
{
for(int i=1;i<n;i++)
if(A[i]<A[i-1])return false;
return true;
}
int main()
{
//测试数据:
//输入格式:第一行是n,元素个数。第二行是n个元素。
//0.txt 无元素
//1.txt 1个元素
//2.txt 2个元素
//3.txt 5个元素
//4.txt 均为相同元素
//5.txt 大量相同元素
//6.txt 随机元素
//7.txt 逆序元素
//8.txt 升序元素
//有a后缀即为排序后的输出
char index[10]="0";
for(int i=0;i<9;i++){
char file[10];strcpy(file,index);
strcat(file,".txt");
ifstream fin(file);
if(!fin){cerr<<"can't open input file \""<<file<<"\""<<endl;exit(EXIT_FAILURE);}
int n;fin>>n;
MY* A=new MY [n];
for(int i=0;i<n;i++) fin>>A[i];
bubble(A,n);
cout<<check_if_sorted(A,n)<<endl;
char filea[10];strcpy(filea,index);
strcat(filea,"a.txt");
ofstream fout(filea);
for(int i=0;i<n;i++) fout<<A[i]<<" ";
index[0]++;
delete[] A;
}
return 0;
}
插入排序
- //time:10.920s
- #include<cstring>
- #include<iostream>
- #include<fstream>
- #include<algorithm>
- using namespace std;
- class MY{
- int a;
- //public:
- friend ostream& operator <<(ostream& os,const MY &my){
- os<<my.a;return os;
- }
- friend istream& operator >>(istream& is,MY& my){
- is>>my.a;return is;
- }
- public:
- bool operator<(const MY& another){
- return this->a<another.a;
- }
- };
- template<class T>
- void insertion(T A[],int n)
- {
- //A[0...i-1]是非递减序的
- for(int i=1;i<n;i++){
- T key=A[i];
- int j=i-1;
- //A[j+2...i]是非递减序的,且都大于key
- while(j>=0&&key<A[j]){A[j+1]=A[j];j--;}
- A[j+1]=key;
- }
- }
- template<typename T>
- bool check_if_sorted(T A[],int n)
- {
- for(int i=1;i<n;i++)
- if(A[i]<A[i-1])return false;
- return true;
- }
- int main()
- {
- //测试数据:
- //输入格式:第一行是n,元素个数。第二行是n个元素。
- //0.txt 无元素
- //1.txt 1个元素
- //2.txt 2个元素
- //3.txt 5个元素
- //4.txt 均为相同元素
- //5.txt 大量相同元素
- //6.txt 随机元素
- //7.txt 逆序元素
- //8.txt 升序元素
- //9.txt 1000000个元素
- //有a后缀即为排序后的输出
- char index[10]="0";
- for(int i=0;i<9;i++){
- char file[10];strcpy(file,index);
- strcat(file,".txt");
- ifstream fin(file);
- if(!fin){cerr<<"can't open input file \""<<file<<"\""<<endl;exit(EXIT_FAILURE);}
- int n;fin>>n;
- MY* A=new MY [n];
- for(int i=0;i<n;i++) fin>>A[i];
- insertion(A,n);
- cout<<check_if_sorted(A,n)<<endl;
- char filea[10];strcpy(filea,index);
- strcat(filea,"a.txt");
- ofstream fout(filea);
- for(int i=0;i<n;i++) fout<<A[i]<<" ";
- index[0]++;
- delete[] A;
- }
- return 0;
- }
选择排序
- //time:18.650s
- #include<cstring>
- #include<iostream>
- #include<fstream>
- #include<algorithm>
- using namespace std;
- class MY{//设置此class只是为了C++练手
- int a;
- //public:
- friend ostream& operator <<(ostream& os,const MY &my){
- os<<my.a;return os;
- }
- friend istream& operator >>(istream& is,MY& my){
- is>>my.a;return is;
- }
- public:
- bool operator<(const MY& another){
- return this->a<another.a;
- }
- };
- template<class T>
- void selection(T A[],int n)
- {
- for(int i=0;i<n-1;i++){
- T min=A[i];int min_index=i;
- for(int j=i+1;j<n;j++)
- if(A[j]<min){min=A[j];min_index=j;}
- swap(A[i],A[min_index]);
- }
- }
- template<typename T>
- bool check_if_sorted(T A[],int n)
- {
- for(int i=1;i<n;i++)
- if(A[i]<A[i-1])return false;
- return true;
- }
- int main()
- {
- //测试数据:
- //输入格式:第一行是n,元素个数。第二行是n个元素。
- //0.txt 无元素
- //1.txt 1个元素
- //2.txt 2个元素
- //3.txt 5个元素
- //4.txt 均为相同元素
- //5.txt 大量相同元素
- //6.txt 随机元素
- //7.txt 逆序元素
- //8.txt 升序元素
- //9.txt 1000000个元素
- //有a后缀即为排序后的输出
- char index[10]="0";
- for(int i=0;i<9;i++){
- char file[10];strcpy(file,index);
- strcat(file,".txt");
- ifstream fin(file);
- if(!fin){cerr<<"can't open input file \""<<file<<"\""<<endl;exit(EXIT_FAILURE);}
- int n;fin>>n;
- MY* A=new MY [n];
- for(int i=0;i<n;i++) fin>>A[i];
- selection(A,n);
- cout<<check_if_sorted(A,n)<<endl;
- char filea[10];strcpy(filea,index);
- strcat(filea,"a.txt");
- ofstream fout(filea);
- for(int i=0;i<n;i++) fout<<A[i]<<" ";
- index[0]++;
- delete[] A;
- }
- return 0;
- }
堆排序
- //time:2.460s
- #include<cstring>
- #include<iostream>
- #include<fstream>
- #include<algorithm>
- using namespace std;
- class MY{
- int a;
- //public:
- friend ostream& operator <<(ostream& os,const MY &my){
- os<<my.a;return os;
- }
- friend istream& operator >>(istream& is,MY& my){
- is>>my.a;return is;
- }
- public:
- bool operator<(const MY& another){
- return this->a<another.a;
- }
- };
- int RANDOM(int begin,int end)
- {//[begin,end]
- int seed=rand()*(RAND_MAX+1)+rand();
- return seed%(end-begin+1)+begin;
- }
- template<class T>
- void fixdown(T A[],int parent,int n)
- {//A[parent]元素是以A[parent...n]为大顶堆的唯一违反。
- while(true){
- int left=(parent<<1),right=left+1;
- int max=parent;
- if(left<=n&&A[max]<A[left]) max=left;
- if(right<=n&&A[max]<A[right]) max=right;
- if(max==parent) break;
- swap(A[parent],A[max]);parent=max;
- }
- }
- template<class T>
- void heapsort(T A[],int n)
- {
- for(int i=n>>1;i>=1;i--) fixdown(A,i,n);
- //for(int i=1;i<=n;i++) printf("%d ",A[i]);putchar('\n');
- while(n>1){
- swap(A[1],A[n]);fixdown(A,1,--n);
- }
- }
- template<typename T>
- bool check_if_sorted(T A[],int n)
- {
- for(int i=1;i<n;i++)
- if(A[i+1]<A[i])return false;
- return true;
- }
- int main()
- {
- //测试数据:
- //输入格式:第一行是n,元素个数。第二行是n个元素。
- //0.txt 无元素
- //1.txt 1个元素
- //2.txt 2个元素
- //3.txt 5个元素
- //4.txt 均为相同元素
- //5.txt 大量相同元素
- //6.txt 随机元素
- //7.txt 逆序元素
- //8.txt 升序元素
- //9.txt 1000000个元素
- //有a后缀的文件即为排序后的输出
- char index[10]="0";
- for(int i=0;i<10;i++){
- char file[10];strcpy(file,index);
- strcat(file,".txt");
- ifstream fin(file);
- if(!fin){cerr<<"can't open input file \""<<file<<"\""<<endl;exit(EXIT_FAILURE);}
- int n;fin>>n;
- MY*A=new MY [n+1];//堆排序下标是1~n
- for(int i=1;i<=n;i++) fin>>A[i];
- heapsort(A,n);
- cout<<check_if_sorted(A,n)<<endl;
- char filea[10];strcpy(filea,index);
- strcat(filea,"a.txt");
- ofstream fout(filea);
- for(int i=1;i<=n;i++) fout<<A[i]<<" ";
- index[0]++;
- delete[] A;
- }
- return 0;
- }
使用非递归的归并排序
- //time:3.400s
- //使用非递归的归并排序
- #include<cstring>
- #include<iostream>
- #include<fstream>
- #include<algorithm>
- using namespace std;
- class MY{
- int a;
- //public:
- friend ostream& operator <<(ostream& os,const MY &my){
- os<<my.a;return os;
- }
- friend istream& operator >>(istream& is,MY& my){
- is>>my.a;return is;
- }
- public:
- bool operator<(const MY& another){
- return this->a<another.a;
- }
- };
- int RANDOM(int begin,int end)
- {//[begin,end]
- int seed=rand()*(RAND_MAX+1)+rand();
- return seed%(end-begin+1)+begin;
- }
- template<class T>
- int merge(T A[],int left,int middle,int right)
- {//归并两个有序数组A[left...middle]和A[middle+1...right]
- int len1=middle-left+1,len2=right-middle;
- T* Aux1=new T[len1],*Aux2=new T[len2];
- for(int i=left;i<=middle;i++) Aux1[i-left]=A[i];
- for(int j=middle+1;j<=right;j++) Aux2[j-middle-1]=A[j];
- int i=0,j=0,k=0;
- while(i<len1&&j<len2){
- if(Aux1[i]<Aux2[j]) A[left+k++]=Aux1[i++];
- else A[left+k++]=Aux2[j++];
- }
- while(i<len1) A[left+k++]=Aux1[i++];
- while(j<len2) A[left+k++]=Aux2[j++];
- delete[] Aux1;delete[] Aux2;
- }
- template<class T>
- void bottom_up_mergesort(T A[],int n)
- {
- for(int len=1;len<=n;len<<=1)
- for(int i=0;i<n-len;i+=(len<<1))//由i+len-1<n-1得i<n-len。最后一趟合并,一边是len长,另一边是剩下的长。i+len-1<n-1是保证一边有len长,且剩下有至少1的长度
- merge(A,i,i+len-1,min(i+(len<<1)-1,n-1));
- }
- template<typename T>
- bool check_if_sorted(T A[],int n)
- {
- for(int i=1;i<n;i++)
- if(A[i]<A[i-1])return false;
- return true;
- }
- int main()
- {
- //测试数据:
- //输入格式:第一行是n,元素个数。第二行是n个元素。
- //0.txt 无元素
- //1.txt 1个元素
- //2.txt 2个元素
- //3.txt 5个元素
- //4.txt 均为相同元素
- //5.txt 大量相同元素
- //6.txt 随机元素
- //7.txt 逆序元素
- //8.txt 升序元素
- //9.txt 1000000个元素
- //有a后缀的文件即为排序后的输出
- char index[10]="0";
- for(int i=0;i<10;i++){
- char file[10];strcpy(file,index);
- strcat(file,".txt");
- ifstream fin(file);
- if(!fin){cerr<<"can't open input file \""<<file<<"\""<<endl;exit(EXIT_FAILURE);}
- int n;fin>>n;
- MY*A=new MY [n];
- for(int i=0;i<n;i++) fin>>A[i];
- bottom_up_mergesort(A,n);
- cout<<check_if_sorted(A,n)<<endl;
- char filea[10];strcpy(filea,index);
- strcat(filea,"a.txt");
- ofstream fout(filea);
- for(int i=0;i<n;i++) fout<<A[i]<<" ";
- index[0]++;
- delete[] A;
- }
- return 0;
- }
使用递归的归并排序
- //3.370s
- //使用递归的归并排序
- #include<cstring>
- #include<iostream>
- #include<fstream>
- #include<algorithm>
- using namespace std;
- class MY{
- int a;
- //public:
- friend ostream& operator <<(ostream& os,const MY &my){
- os<<my.a;return os;
- }
- friend istream& operator >>(istream& is,MY& my){
- is>>my.a;return is;
- }
- public:
- bool operator<(const MY& another){
- return this->a<another.a;
- }
- };
- int RANDOM(int begin,int end)
- {//[begin,end]
- int seed=rand()*(RAND_MAX+1)+rand();
- return seed%(end-begin+1)+begin;
- }
- template<class T>
- int merge(T A[],int left,int middle,int right)
- {//归并两个有序数组A[left...middle]和A[middle+1...right]
- int len1=middle-left+1,len2=right-middle;
- T* Aux1=new T[len1],*Aux2=new T[len2];
- for(int i=left;i<=middle;i++) Aux1[i-left]=A[i];
- for(int j=middle+1;j<=right;j++) Aux2[j-middle-1]=A[j];
- int i=0,j=0,k=0;
- while(i<len1&&j<len2){
- if(Aux1[i]<Aux2[j]) A[left+k++]=Aux1[i++];
- else A[left+k++]=Aux2[j++];
- }
- while(i<len1) A[left+k++]=Aux1[i++];
- while(j<len2) A[left+k++]=Aux2[j++];
- delete[] Aux1;delete[] Aux2;
- }
- template<class T>
- void mergesort(T A[],int p,int q)
- {
- if(p>=q) return ;
- int middle=(p+q)/2;
- mergesort(A,p,middle);
- mergesort(A,middle+1,q);
- merge(A,p,middle,q);
- }
- template<typename T>
- bool check_if_sorted(T A[],int n)
- {
- for(int i=1;i<n;i++)
- if(A[i]<A[i-1])return false;
- return true;
- }
- int main()
- {
- //测试数据:
- //输入格式:第一行是n,元素个数。第二行是n个元素。
- //0.txt 无元素
- //1.txt 1个元素
- //2.txt 2个元素
- //3.txt 5个元素
- //4.txt 均为相同元素
- //5.txt 大量相同元素
- //6.txt 随机元素
- //7.txt 逆序元素
- //8.txt 升序元素
- //9.txt 1000000个元素
- //有a后缀的文件即为排序后的输出
- char index[10]="0";
- for(int i=0;i<10;i++){
- char file[10];strcpy(file,index);
- strcat(file,".txt");
- ifstream fin(file);
- if(!fin){cerr<<"can't open input file \""<<file<<"\""<<endl;exit(EXIT_FAILURE);}
- int n;fin>>n;
- MY*A=new MY [n];
- for(int i=0;i<n;i++) fin>>A[i];
- mergesort(A,0,n-1);
- cout<<check_if_sorted(A,n)<<endl;
- char filea[10];strcpy(filea,index);
- strcat(filea,"a.txt");
- ofstream fout(filea);
- for(int i=0;i<n;i++) fout<<A[i]<<" ";
- index[0]++;
- delete[] A;
- }
- return 0;
- }
随机化的快速排序
- //time:3.770s
- //随机化的快速排序。若不使用随机化的话,遇到极端情况,升序或逆序排列,就会递归深度过大,stack overflow。
- #include<cstring>
- #include<iostream>
- #include<fstream>
- #include<algorithm>
- using namespace std;
- class MY{
- int a;
- //public:
- friend ostream& operator <<(ostream& os,const MY &my){
- os<<my.a;return os;
- }
- friend istream& operator >>(istream& is,MY& my){
- is>>my.a;return is;
- }
- public:
- bool operator<(const MY& another){
- return this->a<another.a;
- }
- };
- int RANDOM(int begin,int end)
- {//[begin,end]
- int seed=rand()*(RAND_MAX+1)+rand();
- return seed%(end-begin+1)+begin;
- }
- template<class T>
- int partition(T A[],int p,int q)
- {
- int pivot=p-1;T key=A[q];
- //A[p...pivot] < key
- //A[pivot+1...j-1] >= key
- //A[q] = key
- for(int j=p;j<q;j++)
- if(A[j]<key) swap(A[j],A[++pivot]);
- swap(A[pivot+1],A[q]);
- return pivot+1;
- }
- template<class T>
- void quicksort(T A[],int p,int q)
- {
- if(p>=q) return ;
- swap(A[q],A[RANDOM(p,q)]);//随机选择划分主元
- int pivot=partition(A,p,q);
- quicksort(A,p,pivot-1);
- quicksort(A,pivot+1,q);
- }
- template<typename T>
- bool check_if_sorted(T A[],int n)
- {
- for(int i=1;i<n;i++)
- if(A[i]<A[i-1])return false;
- return true;
- }
- int main()
- {
- //测试数据:
- //输入格式:第一行是n,元素个数。第二行是n个元素。
- //0.txt 无元素
- //1.txt 1个元素
- //2.txt 2个元素
- //3.txt 5个元素
- //4.txt 均为相同元素
- //5.txt 大量相同元素
- //6.txt 随机元素
- //7.txt 逆序元素
- //8.txt 升序元素
- //9.txt 1000000个元素
- //有a后缀的文件即为排序后的输出
- char index[10]="0";
- for(int i=0;i<10;i++){
- char file[10];strcpy(file,index);
- strcat(file,".txt");
- ifstream fin(file);
- if(!fin){cerr<<"can't open input file \""<<file<<"\""<<endl;exit(EXIT_FAILURE);}
- int n;fin>>n;
- MY*A=new MY [n];
- for(int i=0;i<n;i++) fin>>A[i];
- quicksort(A,0,n-1);
- cout<<check_if_sorted(A,n)<<endl;
- char filea[10];strcpy(filea,index);
- strcat(filea,"a.txt");
- ofstream fout(filea);
- for(int i=0;i<n;i++) fout<<A[i]<<" ";
- index[0]++;
- delete[] A;
- }
- return 0;
- }