⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sort.c

📁 这是数据结构的课程设计
💻 C
字号:
/*头文件和宏定义部分*/
#include"string.h"
#include"ctype.h"
#include"time.h"
#include"malloc.h" /* malloc()等 */
#include"limits.h" /* INT_MAX等 */
#include"stdio.h" /* EOF(=^Z或F6),NULL */
#include"stdlib.h" /* atoi() */
#include"io.h" /* eof() */
#include"math.h" /* floor(),ceil(),abs() */
#include"process.h" /* exit() */
/* 函数结果状态代码 */

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define MAXSIZE 100   //示例数据类型的最大长度



typedef int KeyType;		//定义关键字类型为整数类型
typedef int InfoType;	//定义关键字类型为整数类型
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
typedef struct{
	KeyType key;	//关键字项
	InfoType otherinfo;		//其它数据项
}RedType;		//记录类型

typedef struct {
	RedType r[MAXSIZE+1];		//r[0]闲置或用作哨兵单元
	int length;		//顺序表长度
}SqList;		//顺序表类型



void InitData(SqList *L,int dataCopy[])
{
	int i;
	L->length=MAXSIZE;
	srand((unsigned)time(NULL)); 
	for(i=0;i<=MAXSIZE;i++)
	{
		L->r[i].otherinfo=0;
		dataCopy[i]=L->r[i].key=rand();
	}
}

void PrintData(SqList L)
{
	int i;
	for(i=1;i<=L.length;i++)
	{
		printf("%d\t",L.r[i].key);
	}
}

void ResumeData(SqList *L,int dataCopy[])
{
	int i;
	for(i=0;i<=MAXSIZE;i++)
	{
		L->r[i].key=dataCopy[i];
	}
}

void PrintStatistic(int *compareCounts,int *moveCounts)
{
	printf("\n\t\t各种排序方法比较结果:\n\n");
	printf("\t\t起泡排序:    比较次数  %d,移动次数  %d\n",compareCounts[0],moveCounts[0]);
	printf("\t\t直接插入排序:比较次数  %d,移动次数  %d\n",compareCounts[1],moveCounts[1]);
	printf("\t\t简单选择排序:比较次数  %d,移动次数  %d\n",compareCounts[2],moveCounts[2]);
	printf("\t\t快速排序:    比较次数  %d,移动次数  %d\n",compareCounts[3],moveCounts[3]);
	printf("\t\t希尔排序:    比较次数  %d,移动次数  %d\n",compareCounts[4],moveCounts[4]);
	printf("\t\t堆排序:      比较次数  %d,移动次数  %d\n",compareCounts[5],moveCounts[5]);
}



/*******************************直接插入排序*******************************/

void InsertSort(SqList *L,int *compareCounts,int *moveCounts )		//直接插入排序
{
	int i,j;		//
	for(i=2;i<=L->length;i++)		//从顺序表的第二个元素开始进行比较
	{
		if(L->r[i].key<L->r[i-1].key)		//将每个元素与它的前一个元素关键字进行比较
		{
			L->r[0]=L->r[i];		//如果关键字比前一个元素关键字小,就将元素复制作为哨兵
			L->r[i]=L->r[i-1];
			(*moveCounts)+=2;		//关键字移动了2次
			j=i-2;		//从要比较的关键字的前第二个记录开始进行比较,然后后移
			while(L->r[0].key<L->r[j].key)
			{
				L->r[j+1]=L->r[j];		//记录后移
				(*moveCounts)++;		//每作一次后移,移动次数加1
				j--;
				(*compareCounts)++;		//每作一次比较,比较次数加1
			}
			L->r[j+1]=L->r[0];		//插入到正确位置
		}
		(*compareCounts)++;
	}
}



/*******************************希尔排序*******************************/

void ShellInsert(SqList *L,int increment,int *compareCounts,int *moveCounts)
{		//对顺序表作一趟希尔插入排序
	int j,n;
	for(j=1+increment;j<=L->length;j++)
	{
		if(L->r[j].key<L->r[j-increment].key)		//将L->[i]插入到有序增量子表
		{
			L->r[0]=L->r[j];		//暂存在L->r[0]
			L->r[j]=L->r[j-increment];
			(*moveCounts)+=2;
			for(n=j-2*increment;n>0&&L->r[0].key<L->r[n].key;n-=increment)
			{
				L->r[n+increment]=L->r[n];		//记录后移,查找插入位置
				(*moveCounts)++;
				(*compareCounts)++;
			}
			L->r[n+increment]=L->r[0];		//插入
			(*moveCounts)++;
		}
		(*compareCounts)++;
	}
}



void ShellSort(SqList *L,int IncreList[],int times,int *compareCounts,int *moveCounts)		//希尔排序
{		//按增量序列Increlist[0.....times-1]对顺序表L作希尔排序
	int k;		//
	for(k=0;k<times;k++)
	{
		ShellInsert(L,IncreList[k],compareCounts,moveCounts);		//一趟增量为IncreList[k]的插入排序
	}
}



/*******************************起泡排序*******************************/

void BubbleSort(SqList *L,int *compareCounts,int *moveCounts)		//起泡排序
{
	int i,j;
	for(i=1;i<=L->length;i++)
	{
		for(j=L->length;j>i;j--)
		{		//从后往前两两进行比较,将元素关键字小的交换到前面
			if(L->r[j].key<L->r[j-1].key)	
			{
				L->r[0]=L->r[j];
				L->r[j]=L->r[j-1];
				L->r[j-1]=L->r[0];
				(*moveCounts)+=3;
			}
			(*compareCounts)++;
		}
	}
}



/*******************************快速排序*******************************/

int Partition(SqList *L,int low,int high,int *compareCounts,int *moveCounts)		//快速排序中的分
{
	int pivotkey;
	L->r[0]=L->r[low];
	(*moveCounts)++;
	pivotkey=L->r[low].key;
	while(low<high)
	{
		while(low<high&&L->r[high].key>=pivotkey)
		{
			high--;
			(*compareCounts)++;
		}
		L->r[low]=L->r[high];
		(*moveCounts)++;
		while(low<high&&L->r[low].key<=pivotkey)
		{
			low++;
			(*compareCounts)++;
		}
		L->r[high]=L->r[low];
		(*moveCounts)++;
		(*compareCounts)++;
	}
	L->r[low]=L->r[0];
	(*moveCounts)++;
	return low;
}



void QSort(SqList *L,int low,int high,int *compareCounts,int *moveCounts)
{
	int pivotloc;
	if(low<high)
	{
		pivotloc=Partition(L,low,high,compareCounts,moveCounts);
		QSort(L,low,pivotloc-1,compareCounts,moveCounts);
		QSort(L,pivotloc+1,high,compareCounts,moveCounts);
	}
}



void QuickSort(SqList *L,int *compareCounts,int *moveCounts)
{
	QSort(L,1,L->length,compareCounts,moveCounts);
}



/*******************************简单选择排序*******************************/

void SelectSort(SqList *L,int *compareCounts,int *moveCounts)
{
	int i,j,minPoint;
	for(i=1;i<=L->length;i++)
	{
		L->r[0]=L->r[i];
		(*moveCounts)++;
		minPoint=i;
		for(j=i+1;j<=L->length;j++)
		{
			if(L->r[j].key<L->r[0].key)
			{
				L->r[0]=L->r[j];
				(*moveCounts)++;
				minPoint=j;
			}
			(*compareCounts)++;
		}
		L->r[minPoint]=L->r[i];
		L->r[i]=L->r[0];
		(*moveCounts)++;
	}
}



/*******************************堆排序*******************************/

void HeapAdjust(SqList *L,int s,int m,int *compareCounts,int *moveCounts)
{
	RedType cmpKey;		//待比较的值
	int j;
	cmpKey=L->r[s];
	(*moveCounts)++;
	for(j=s*2;j<=m;j*=2)
	{
		(*compareCounts)+=2;
		if(j<m&&L->r[j].key<L->r[j+1].key) j++;
		if(!(cmpKey.key<L->r[j].key)) break;
		L->r[s]=L->r[j];
		(*moveCounts)++;
		s=j;		
	}
	L->r[s]=cmpKey;
	(*moveCounts)++;
}



void HeapSort(SqList *L,int *compareCounts,int *moveCounts)
{
	int i;
	RedType temp;
	for(i=L->length/2;i>0;i--)	HeapAdjust(L,i,L->length,compareCounts,moveCounts);
	for(i=L->length;i>1;i--)
	{
		temp=L->r[1];
		L->r[1]=L->r[i];
		L->r[i]=temp;
		(*moveCounts)+=3;
		HeapAdjust(L,1,i-1,compareCounts,moveCounts);
	}
}



void SortCompare()
{
	SqList L;		//用顺序表存放待排序的元素
	int dataCopy[MAXSIZE+1],i;
	int compareCounts[7],moveCounts[7];
	int increList[6];
	for(i=0;i<5;i++)
	{
		increList[i]=(int)pow(2,7-i)-1;
	}
	increList[5]=1;
	for(i=0;i<7;i++)
	{

		compareCounts[i]=0;
		moveCounts[i]=0;
	}
	InitData(&L,dataCopy);		//初始化数据,随机产生100个正整数的数列
	printf("\t\t\t初始化数据后产生的数列:\n");		
	PrintData(L);		//显示出未排序的数列

	printf("\n\n\t\t\t经过起泡排序后产生的数列:\n");
	BubbleSort(&L,&compareCounts[0],&moveCounts[0]);		//对数列使用起泡排序
	PrintData(L);		//显示出排序好的数列
	ResumeData(&L,dataCopy);

	printf("\n\n\t\t\t经过直接插入排序后产生的数列:\n");
	InsertSort(&L,&compareCounts[1],&moveCounts[1]);		//对数列使用插入排序
	PrintData(L);		//显示出排序好的数列
	ResumeData(&L,dataCopy);

	printf("\n\n\t\t\t经过简单选择排序后产生的数列:\n");
	SelectSort(&L,&compareCounts[2],&moveCounts[2]);		//对数列使用简单选择排序
	PrintData(L);		//显示出排序好的数列
	ResumeData(&L,dataCopy);

	printf("\n\n\t\t\t经过快速排序后产生的数列:\n");
	QuickSort(&L,&compareCounts[3],&moveCounts[3]);		//对数列使用快速排序
	PrintData(L);		//显示出排序好的数列
	ResumeData(&L,dataCopy);

	printf("\n\n\t\t\t经过希尔排序后产生的数列:\n");
	ShellSort(&L,increList,6,&compareCounts[4],&moveCounts[4]);		//对数列使用希尔排序
	PrintData(L);		//显示出排序好的数列
	ResumeData(&L,dataCopy);

	printf("\n\n\t\t\t经过堆排序后产生的数列:\n");
	HeapSort(&L,&compareCounts[5],&moveCounts[5]);		//对数列使用堆排序
	PrintData(L);		//显示出排序好的数列
	PrintStatistic(compareCounts,moveCounts);
}



main()	
{
	int i,temp;
	for(i=0;i<5;i++)
	{
		SortCompare();
		printf("\n\t\t请按任意键进行下一组数据的排序对比\n\n");
		temp=getchar();
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -