读取文件big-a.txt的数据(包含500000个随机数,[1,5000000]),利用插入排序、希尔排序,冒泡排序、快速排序、选择排序、堆排序,归并排序、基数排序8种排序方法进行排序(结果为由小到大的顺序),并统计每一种排序算法对不同样本所耗费的时间。
(1)排序后的数据分别写入insertsort.txt、shellsort.txt、bubblesort.txt、mergesort.txt、quicksort.txt、selectionsort.txt、heapsort.txt、radixsort.txt
(2)屏幕显示每种排序算法前100个数和排序所用时间
#include<iostream>
#include<fstream>
#include<ctime>
using namespace std;
#define MAXSIZE 500000
typedef int Status;
typedef struct Record{
int key;
}Record;
typedef struct SqList{
int length;
Record r[MAXSIZE+1];//0号单元闲置
}SqList;
typedef struct SeqList{
Record *r;
int length;//存储数据元素的个数
int size;//当前已经分配的存储空间大小
}SeqList;
typedef struct LNode{
Record data;
struct LNode *next;
}LNode , *QueuePtr;
typedef struct LinkQueue{
QueuePtr front; //队头指针
QueuePtr rear; //队尾指针,若队列不空,指向队尾的下一个位置
}LinkQueue;
Status InitQueue(LinkQueue &Q); //初始化队列
Status EnQueue(LinkQueue &Q,Record r);//链式队列的入队操作
Status DeQueue(LinkQueue &Q,Record &r);//链式队列的出队操作
Status QueueEmpty(LinkQueue &Q);//判断队列是否为空
Status InitList(SqList &L);//初始化序列
void Insert(SqList &L,int i);
void InsertSort(SqList &L);//插入排序
void BubbleSort(SqList &L);//冒泡排序
void SelectionSort(SqList &L);//选择排序
void Shell(SqList &L,int d);//对间隔为d的子序列进行直接插入排序
void ShellSort(SqList &L,int d[],int t);//希尔排序
int Partition(SqList &L,int low,int high);//一趟快速排序
void QSort(SqList &L,int low,int high);//low和high之间的快排
void QuickSort(SqList &L);//快速排序
void HeapAdjust(SqList &L,int low,int high);//堆调整的算法
void HeapSort(SqList &L);//堆排序
void Merge(SqList &L,int low,int mid,int high);//两路归并
void MSort(SqList &L,int len);//两路归并的非递归调用
void MergeSort(SqList &L);//归并排序
void RadixSort(SqList &L);//基数排序
int main()
{
SqList L;
InitList(L);
InsertSort(L);//插入排序
InitList(L);
BubbleSort(L);//冒泡排序
InitList(L);
SelectionSort(L);//选择排序
int i = 0, d[64], len = L.length/2;
do{
d[i++] = len;
len/=2;
}
while(len != 1);
if(d[i-1] != 1){
d[i++] = 1;//保证希尔排序最后一次的增值为1
}
// for(int j = 0;j<i;j++)
// cout<<d[j]<<" ";
InitList(L);
ShellSort(L, d, i);//希尔排序
InitList(L);
QuickSort(L);//快速排序
InitList(L);
HeapSort(L);//堆排序
InitList(L);
MergeSort(L);//归并排序
InitList(L);
RadixSort(L);//基数排序
return 0;
}
Status InitList(SqList &L)//初始化序列
{
ifstream ifs;
ifs.open("big-a.txt");
L.length = 0;
if(!ifs)
cout<<"文件打开失败!"<<endl;
int i = 1;
while(!ifs.eof())
{
ifs>>L.r[i++].key;
L.length++;
}
ifs.close();
return 1;
}
void Insert(SqList &L,int i)
{
Record temp = L.r[i];//将第i个记录临时保存
int j;
for(j = i;j>1;j--)
{
if(temp.key < L.r[j-1].key)
L.r[j] = L.r[j-1];//依次向后移动
else
break;
}
L.r[j] = temp;
}
void InsertSort(SqList &L)//插入排序
{
clock_t t1, t2;
double dur;
t1 = clock();
for(int i = 2;i<=L.length; i++)//从第二个开始插入
Insert(L,i);
t2 = clock();
dur = double(t2)-double(t1);
cout<<"插入排序的时间为:"<<dur<<"ms"<<'\n';
ofstream ins;
ins.open("insertsort.txt");
for(int i = 1;i<=L.length;i++)
{
ins<<L.r[i].key<<endl;
if(i<=100)
cout<<L.r[i].key<<" ";
}
cout<<endl;
ins.close();
}
void BubbleSort(SqList &L)//冒泡排序
{
clock_t t1, t2;
double dur;
t1 = clock();
for(int i = 1;i<=L.length-1;i++)
{
for(int j = 1;j<=L.length-i;j++)
{
if(L.r[j].key > L.r[j+1].key)
{
Record temp = L.r[j];
L.r[j] = L.r[j+1];
L.r[j+1] = temp;//进行交换
}
}
}
t2 = clock();
dur = double(t2)-double(t1);
cout<<"冒泡排序的时间为:"<<dur<<"ms"<<'\n';
ofstream bub;
bub.open("bubblesort.txt");
for(int i = 1;i<=L.length;i++)
{
bub<<L.r[i].key<<endl;
if(i<=100)
cout<<L.r[i].key<<" ";
}
cout<<endl;
bub.close();
}
void SelectionSort(SqList &L)//选择排序
{
clock_t t1, t2;
double dur;
t1 = clock();
for(int i = 1;i<=L.length; i++)
{
int min = L.r[i].key;
int k = i;//起始记录的关键字为最小者
for(int j = i+1;j<=L.length;j++)
{
if(L.r[j].key < min)//发现更小者就记录下来
{
min = L.r[j].key;
k = j;
}
}
Record temp = L.r[i];
L.r[i] = L.r[k];
L.r[k] = temp;
}
t2 = clock();
dur = double(t2)-double(t1);
cout<<"选择排序的时间为:"<<dur<<"ms"<<'\n';
ofstream sel;
sel.open("selection.txt");
for(int i = 1;i<=L.length;i++)
{
sel<<L.r[i].key<<endl;
if(i<=100)
cout<<L.r[i].key<<" ";
}
cout<<endl;
sel.close();
}
void Shell(SqList &L,int d)//对间隔为d的子序列进行直接插入排序
{
for(int i = d+1;i<=L.length;i++)
{
if(L.r[i].key < L.r[i-d].key)
{
Record temp = L.r[i];//将第i个记录临时保存
int j;
for(j = i;j>d;j = j-d)
{
if(temp.key < L.r[j-d].key)
L.r[j] = L.r[j-d];//依次向后移动
else
break;
}
L.r[j] = temp;
}
}
}
void ShellSort(SqList &L,int d[],int t)//希尔排序
{
clock_t t1, t2;
double dur;
t1 = clock();
for(int k = 0; k<t;k++)
Shell(L,d[k]);//每趟的增量为d[k]
t2 = clock();
dur = double(t2)-double(t1);
cout<<"希尔排序的时间为:"<<dur<<"ms"<<'\n';
ofstream she;
she.open("shellsort.txt");
for(int i = 1;i<=L.length;i++)
{
she<<L.r[i].key<<endl;
if(i<=100)
cout<<L.r[i].key<<" ";
}
cout<<endl;
she.close();
}
int Partition(SqList &L,int low,int high)//一趟快速排序
{
Record temp = L.r[low];
int pivotkey = L.r[low].key;
while(low < high)
{
while(low < high && L.r[high].key >= pivotkey)
high--;
L.r[low] = L.r[high];
while(low < high && L.r[low].key <= pivotkey)
low++;
L.r[high] = L.r[low];
}
L.r[low] = temp;
return low;
}
void QSort(SqList &L,int low,int high)//low和high之间的快排
{
if(low < high)
{
int pivotloc = Partition(L,low,high);//一趟快速排序
QSort(L,low,pivotloc-1);//对前部子序列进行递归快排
QSort(L,pivotloc+1,high);//对后部子序列进行递归快排
}
}
void QuickSort(SqList &L)//快速排序
{
clock_t t1, t2;
double dur;
t1 = clock();
QSort(L,1,L.length);
t2 = clock();
dur = double(t2)-double(t1);
cout<<"快速排序的时间为:"<<dur<<"ms"<<endl;
ofstream ofs;
ofs.open("quicksort.txt");
for(int i = 1;i<=L.length;i++)
{
ofs<<L.r[i].key<<endl;
if(i<=100)
cout<<L.r[i].key<<" ";
}
cout<<endl;
ofs.close();
}
void HeapAdjust(SqList &L,int low,int high)//堆调整的算法
{//假设L中记录的关键字除了L.r[low].key之外,左右子树均满足大顶堆的定义,进行堆的“筛选”
Record temp = L.r[low];
int i = low,j = 2*i;
while(j<=high){//向下筛选
if(j+1 <= high && L.r[j].key < L.r[j+1].key)
j++;//在左右子树中找大的那个
if(temp.key >= L.r[j].key)
break;//已经是大顶堆
L.r[i] = L.r[j];
i = j;
j = 2*i; //大者上移,继续向下筛选
}
L.r[i] = temp;//插入最终位置
}
void HeapSort(SqList &L)//堆排序
{
clock_t t1,t2;
double dur;
t1 = clock();
for(int i = L.length/2;i > 0;i--){//建成一个大顶堆
HeapAdjust(L,i,L.length);
}
for(int i = L.length;i>1;i--){
Record temp = L.r[1];
L.r[1] = L.r[i];
L.r[i] = temp;
HeapAdjust(L,1,i-1);
}
t2 = clock();
dur = double(t2) - double(t1);
cout<<"堆排序的时间为:"<<dur<<"ms"<<endl;
ofstream ofs;
ofs.open("heapsort.txt");
for(int i = 1;i<=L.length;i++)
{
ofs<<L.r[i].key<<endl;
if(i<=100)
cout<<L.r[i].key<<" ";
}
cout<<endl;
ofs.close();
}
void Merge(SqList &L,int low,int mid,int high)//两路归并
{
SeqList T;//临时的合并存储序列
T.r = new Record [high-low+1];
int i = low,j = mid+1,k = 0;
while(i <= mid && j <= high){//将L中的记录由小到大并入T
if(L.r[i].key <= L.r[j].key){
T.r[k] = L.r[i];
i++;
k++;
}
else{
T.r[k] = L.r[j];
j++;
k++;
}
}
while(i <= mid){
T.r[k] = L.r[i];//将剩余的内容复制到T中
i++;
k++;
}
while(j <= high){
T.r[k] = L.r[j];//将剩余的内容复制到T中
j++;
k++;
}
for(k = 0,i = low;i <= high;k++,i++){
L.r[i] = T.r[k];
}
delete(T.r);
}
void MSort(SqList &L,int len)//两路归并的非递归调用
{
int i = 1;
while(i+2*len <= L.length){
// cout<<i<<" "<<i+len-1<<" "<<i+2*len-1;
Merge(L,i,i+len-1,i+2*len-1);
i += 2*len;
}
if(i+len <= L.length){
Merge(L,i,i+len-1,L.length);
}
}
void MergeSort(SqList &L)//归并排序
{
clock_t t1, t2;
double dur;
t1 = clock();
for(int len = 1;len<=L.length;len = len*2)
MSort(L,len);
t2 = clock();
dur = double(t2)-double(t1);
cout<<"归并排序的时间为:"<<dur<<"ms"<<endl;
ofstream ofs;
ofs.open("mergesort.txt");
for(int i = 1;i<=L.length;i++)
{
ofs<<L.r[i].key<<endl;
if(i<=100)
cout<<L.r[i].key<<" ";
}
cout<<endl;
ofs.close();
}
void RadixSort(SqList &L)//基数排序
{
clock_t t1,t2;
double dur;
t1 = clock();
LinkQueue Q[10];
for(int i = 0;i<10;i++){
InitQueue(Q[i]);
}
int radix = 1;
for(int k = 1;k<=5;k++)//分别对个,十,百,千,万位进行处理
{
radix *= 10;
for(int i = 1;i<=L.length;i++)//分配到合适的队列
{
int m = (L.r[i].key % radix) / (radix/10);
EnQueue(Q[m],L.r[i]);
}
for(int i = 1,m = 0;m<10; m++)//将数据从队列中收集到L里
{
while(!QueueEmpty(Q[m])){
DeQueue(Q[m],L.r[i]);
i++;
}
}
}
t2 = clock();
dur = double(t2)-double(t1);
cout<<"基数排序的时间为:"<<dur<<"ms"<<endl;
ofstream ofs;
ofs.open("radixsort.txt");
for(int i = 1;i<=L.length;i++)
{
ofs<<L.r[i].key<<endl;
if(i<=100)
cout<<L.r[i].key<<" ";
}
cout<<endl;
ofs.close();
}
Status InitQueue(LinkQueue &Q)//初始化队列
{
Q.front = new LNode [sizeof(LNode)];
Q.rear = Q.front;
if(Q.front ==NULL)
exit;
Q.front->next = NULL;
return 1;
}
Status EnQueue(LinkQueue &Q,Record r)//链式队列的入队操作
{
LNode *s = new LNode [sizeof(LNode)];
if (s == NULL)
exit;
s->data = r;
Q.rear->next = s;
Q.rear = s; //更新队尾指针指向新的队尾
return 1;
}
Status DeQueue(LinkQueue &Q,Record &r)//链式队列的出队操作
{
if(Q.front ==Q.rear)//空队列
exit;
LNode *p = Q.front->next;
Q.front->next = p->next;
r = p->data;
if(Q.rear == p)
Q.rear = Q.front;
delete(p);
return 1;
}
Status QueueEmpty(LinkQueue &Q)//判断队列是否为空
{
if(Q.front == Q.rear)
return 1;
return 0;
}
的数据和所花的时间