数据结构之内部排序算法的性能分析

  临近期末,学了一学期“数据结构”让写课程设计,就选了“内部排序算法的性能分析”。

主要是分析关键字的移动次数和比较次数,其中关键字若发生交换,则记为三次移动。下列代码中,“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;
}

 

  • 4
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值