临近期末,学了一学期“数据结构”让写课程设计,就选了“内部排序算法的性能分析”。
主要是分析关键字的移动次数和比较次数,其中关键字若发生交换,则记为三次移动。下列代码中,“move”记为关键字的移动次数,“num”记为关键字的比较次数。比较的是对相同的数据,不同排序算法的效率高低。
下列代码中涉及六种排序算法,分别是:冒泡排序、直接排序、简单选择排序、快速排序、希尔排序、堆排序。在具体的运行过程中,希尔排序可能会出现不能执行的问题,具体是怎么出现的我也没弄清楚,有可能是编译器的问题,时而能执行,时而不能。在产生随机数的函数中,我设置的是产生一千以内的随机数。
稍后,会将这次的课程设计实验报告也放出来。
#include<windows.h>
#include<bits/stdc++.h>
using namespace std;
#define OK 1
#define ERROR 0
typedef int Status;
#define MAXSIZE 1005
typedef int KeyType;
typedef char InfoType[256];
long long int move=0;
int a[MAXSIZE] = {0};
int *d = a;
static long long move1=0;//移动次数
static long long move2=0;
static long long move3=0;
static long long move4=0;
static long long move5=0;
static long long move6=0;
long long num1 = 0;//比较次数
long long num2 = 0;
long long num3 = 0;
long long num4 = 0;
long long num5 = 0;
long long num6 = 0;
typedef struct
{
KeyType key;
InfoType otherinfo;
}RedType;
typedef struct
{
RedType r[MAXSIZE+1];
int length;
}SqList;
Status InitList(SqList &L)
{
L.length = 0;
return 0;
}
Status CreateList(SqList &L, int n, int *d)
{
if(!L.r||n<1||n>MAXSIZE)
return ERROR;
for(int i=1;i<=n;i++)
L.r[i].key = d[i];
L.length=n;
return OK;
}
Status CreateList_1(SqList &L,SqList &l, int n)
{
for(int i=1; i<=n ; i++)
l.r[i].key = 0;
for(int i=1 ; i<=n ; i++)
l.r[i].key = L.r[i].key;
l.length = n;
}
void ListTraverse(SqList L, long long move, long long num)
{
for(int i=1;i<=L.length;i++)
{
cout<<L.r[i].key<<" ";
if(i%10 == 0)
cout<<endl;
}
cout<<endl;
cout<<"关键字移动次数:"<<move<<endl;
cout<<"关键字比较次数:"<<num<<endl;
}
void ListTraverse_1(SqList l)
{
for(int i=1 ; i<=l.length ; i++)
{
cout<<l.r[i].key<<" ";
if(i%10 == 0)
cout<<endl;
}
cout<<endl;
}
//此处定义产生随机函数
void Srand(int n)
{
srand(time(NULL));
for(int i=1 ; i<=n ; i++)
a[i] = rand()%1001;//设置随机数产生的范围
for(int i=1 ; i<=n ; i++)
{
cout<<a[i]<<" ";
if(i%10 == 0)
cout<<endl;
}
cout<<endl;
}
//此处定义冒泡排序
void BubbleSort(SqList &L)
{
int m = L.length,flag = 1;
RedType t;
while((m>0) && (flag==1))
{
flag = 0;
for(int j=1 ; j<=m-1 ; j++)
{
num1 += 1;
if(L.r[j].key > L.r[j+1].key)
{
flag = 1;
t = L.r[j];
L.r[j] = L.r[j+1];
L.r[j+1] = t;
move1 += 3;
}
--m;
}
}
ListTraverse(L,move1,num1);
}
//此处定义快速排序
int Partition(SqList &L , int low , int high)
{
L.r[0] = L.r[low];
int pivotkey = L.r[low].key;
while(low < high)
{
while(low < high && L.r[high].key >= pivotkey)
{
--high;
num4 += 1;
}
L.r[low] = L.r[high], move4 += 1;
while(low<high && L.r[low].key <= pivotkey)
{
++low;
num4 += 1;
}
L.r[high] = L.r[low], move4 += 1;
}
L.r[low] = L.r[0];
move4 += 1;
return low;
}
void QSort(SqList &L, int low, int high)
{
if(low < high)
{
int pivotloc = Partition(L, low, high);
QSort(L, low, pivotloc-1);
QSort(L, pivotloc+1, high);
}
}
void QuickSort(SqList &L)
{
QSort(L, 1, L.length);
ListTraverse(L,move4,num4);
}
//此处定义简单选择排序
void SelectSort(SqList &L)
{
for(int i=1 ; i<L.length ; ++i)
{
RedType t;
int k = i;
for(int j=i+1 ; j<=L.length ; ++j)
{
num3 += 1;
if(L.r[j].key < L.r[k].key)
{
k = j;
}
}
if(k != i)
{
t = L.r[i];
L.r[i] = L.r[k];
L.r[k] = t;
move3 += 3;
}
}
ListTraverse(L,move3,num3);
}
// 此处定义为直接插入排序函数
void InsertSort(SqList &L)
{
int i=0,j=0;
for( i=2 ; i<=L.length ; ++i)
{
num2 += 1;
if(L.r[i].key < L.r[i-1].key)
{
move2 += 1;
L.r[0] = L.r[i];
move2 += 1;
L.r[i] = L.r[i-1];
for( j=i-2 ; L.r[0].key < L.r[j].key ; --j)
{
L.r[j+1] = L.r[j];
move2 += 1, num2 += 1;
}
move2 += 1;
L.r[j+1] = L.r[0];
}
}
ListTraverse(L,move2,num2);
}
//此处定义希尔排序函数
void ShellInsert(SqList &L , int dk)
{
int i=0,j=0;
for(i=dk+1 ; i<=L.length ; ++i)
{
num5 += 1;
if(L.r[i].key < L.r[i-dk].key)
{
move5 += 1;
L.r[0] = L.r[i];
for(j = i-dk ; j>0&&L.r[0].key<L.r[j].key ; j-=dk)
{
L.r[j+dk] = L.r[j];
move5 += 1, num5 += 1;
}
move5 += 1;
L.r[j+dk] = L.r[0];
}
}
}
void ShellSort(SqList &L, int dt[], int t)
{
//按增量序列dt【0..t-1】对顺序表L作t趟希尔排序;
for(int k=0 ; k<t ; ++k )
ShellInsert(L,dt[k]);
ListTraverse(L,move5,num5);
}
//此处定义堆排序
void HeapAdjust(SqList &L, int s, int m)
{
RedType rc = L.r[s];
move6 += 1;
for(int j=2*s ; j<=m ; j *= 2)
{
num6 += 1;
if(j<m && L.r[j].key<L.r[j+1].key)
++j;
num6 += 1;
if(rc.key >= L.r[j].key)
break;
L.r[s] = L.r[j];
s = j;
move6 += 1;
}
L.r[s] = rc;
move6 += 1;
}
void CreatHeap(SqList &L)
{
int n = L.length;
for(int i=(n/2) ; i>0 ; --i)
HeapAdjust(L, i, n);
}
void HeapSort(SqList &L)
{
//对顺序表L进行堆排序
CreatHeap(L);
for(int i=L.length ; i>1 ; --i)
{
RedType x = L.r[1];
L.r[1] = L.r[i];
L.r[i] = x;
move6 += 3;
HeapAdjust(L, 1, i-1);
}
ListTraverse(L,move6,num6);
}
int main()
{
SqList L,l;
InitList(L);
int N;
cout<<"请输入“N ”来确定此次产生多少个随机数:"<<endl;
cin>>N;
cout<<"此次产生的随机数个数为:"<<N<<"个"<<endl;
Srand(N); //产生随机数
CreateList(L, N, d);
int dt[3] = {5, 3, 1};
int d = *dt;
DWORD t1=0, t2=0; //计时
//此处调用冒泡排序
cout<<"冒泡排序"<<endl;
CreateList_1(L, l, N);
ListTraverse_1(l);
t1 = ::GetTickCount();
BubbleSort(l);
t2 = ::GetTickCount();
cout<<"Use time : "<<(t2-t1)<<"ms."<<endl;
cout<<endl;
//此处调用直接插入排序
t1=0,t2=0;
cout<<"直接插入排序"<<endl;
CreateList_1(L, l, N);
ListTraverse_1(l);
t1 = ::GetTickCount();
InsertSort(l);
t2 = ::GetTickCount();
cout<<"Use time : "<<(t2-t1)<<"ms."<<endl;
cout<<endl;
//此处调用简单选择排序
t1=0,t2=0;
cout<<"简单选择排序"<<endl;
CreateList_1(L, l, N);
ListTraverse_1(l);
t1 = ::GetTickCount();
SelectSort(l);
t2 = ::GetTickCount();
cout<<"Use time : "<<(t2-t1)<<"ms."<<endl;
cout<<endl;
//此处调用快速排序
t1=0,t2=0;
cout<<"快速排序"<<endl;
CreateList_1(L, l, N);
ListTraverse_1(l);
t1 = ::GetTickCount();
QuickSort(l);
t2 = ::GetTickCount();
cout<<"Use time : "<<(t2-t1)<<"ms."<<endl;
cout<<endl;
//此处调用希尔排序函数
t1=0,t2=0;
cout<<"希尔排序"<<endl;
CreateList_1(L, l, N);
ListTraverse_1(l);
t1 = ::GetTickCount();
ShellSort(l, &d, N);
t2 = ::GetTickCount();
cout<<"Use time : "<<(t2-t1)<<"ms."<<endl;
cout<<endl;
//此处调用 堆排序
t1=0,t2=0;
cout<<"堆排序"<<endl;
CreateList_1( L, l , N);
ListTraverse_1(l);
t1 = ::GetTickCount();
HeapSort(l);
t2 = ::GetTickCount();
cout<<"Use time : "<<(t2-t1)<<"ms."<<endl;
cout<<endl;
cout<<"冒泡排序 "<<"关键字移动次数:"<<move1<<","<<"关键字比较次数:"<<num1<<"。"<<endl;
cout<<"直接插入排序 "<<"关键字移动次数:"<<move2<<","<<"关键字比较次数:"<<num2<<"。"<<endl;
cout<<"简单选择排序 "<<"关键字移动次数:"<<move3<<","<<"关键字比较次数:"<<num3<<"。"<<endl;
cout<<"快速排序 "<<"关键字移动次数:"<<move4<<","<<"关键字比较次数:"<<num4<<"。"<<endl;
cout<<"希尔排序 "<<"关键字移动次数:"<<move5<<","<<"关键字比较次数:"<<num5<<"。"<<endl;
cout<<"堆排序 "<<"关键字移动次数:"<<move6<<","<<"关键字比较次数:"<<num6<<"。"<<endl;
return 0;
}