数据结构排序算法

原创 2013年12月05日 09:55:10
//头文件
#include"stdio.h"
#include"stdlib.h"

#define Max 100         //假设文件长度

typedef struct{         //定义记录类型
    int key;            //关键字项
}RecType;

typedef RecType SeqList[Max+1]; //SeqList为顺序表,表中第0个元素作为哨兵

int n;                 //顺序表实际的长度

//==========直接插入排序法======
void InsertSort(SeqList R)
{       //对顺序表R中的记录R[1‥n]按递增序进行插入排序
    int i,j;
    for(i=2;i<=n;i++)      //依次插入R[2],……,R[n]
	  if(R[i].key<R[i-1].key)
	  {                        //若R[i].key大于等于有序区中所有的keys,则R[i]留在原位 
		  R[0]=R[i];j=i-1;        //R[0]是R[i]的副本 	 
		  do {              //从右向左在有序区R[1‥i-1]中查找R[i]	的位置 		
			  R[j+1]=R[j];      //将关键字大于R[i].key的记录后移 	
			  j--; 	    }
		  while(R[0].key<R[j].key);   //当R[i].key≥R[j].key 是终止
	    R[j+1]=R[0];                //R[i]插入到正确的位置上
	}//endif
 }

//==========冒泡排序======= 
typedef enum{FALSE,TRUE} Boolean;  //FALSE为0,TRUE为1
void BubbleSort(SeqList R) {             //自下向上扫描对R做冒泡排序
    int i,j;     
	Boolean exchange;     //交换标志  
	for(i=1;i<n;i++) {    //最多做n-1趟排序
	exchange=FALSE;       //本趟排序开始前,交换标志应为假
	for(j=n-1;j>=i;j--)       //对当前无序区R[i‥n] 自下向上扫描
	    if(R[j+1].key<R[j].key){    //两两比较,满足条件交换记录
		R[0]=R[j+1];            //R[0]不是哨兵,仅做暂存单元
		R[j+1]=R[j];
		R[j]=R[0];
		exchange=TRUE;         //发生了交换,故将交换标志置为真
	    }
	if(! exchange)           //本趟排序未发生交换,提前终止算法
	    return;
    }//	endfor(为循环)
}

//1.========一次划分函数=====
int Partition(SeqList R,int i,int j)
{      //   对R[i‥j]做一次划分,并返回基准记录的位置
    RecType pivot=R[i];       //用第一个记录作为基准
    while(i<j) {              //从区间两端交替向中间扫描,直到i=j
 		while(i<j &&R[j].key>=pivot.key)   //基准记录pivot相当与在位置i上
		    j--;      //从右向左扫描,查找第一个关键字小于pivot.key的记录R[j]
		if(i<j)   //若找到的R[j].key < pivot.key,则
	    		R[i++]=R[j];  //交换R[i]和R[j],交换后i指针加1
		while(i<j &&R[i].key<=pivot.key)       //基准记录pivot相当与在位置j上
	    		i++;     //从左向右扫描,查找第一个关键字小于pivot.key的记录R[i]
		if(i<j)   //若找到的R[i].key > pivot.key,则
	    		R[j--]=R[i]; //交换R[i]和R[j],交换后j指针减1
    }
    R[i]=pivot;    //此时,i=j,基准记录已被最后定位
    return i;      //返回基准记录的位置
}

//2.=====快速排序===========
void QuickSort(SeqList R,int low,int high)
{                 //R[low..high]快速排序
    int pivotpos;            //划分后基准记录的位置
    if(low<high) {           //仅当区间长度大于1时才排序
	pivotpos=Partition(R,low,high);  //对R[low..high]做一次划分,得到基准记录的位置
	QuickSort(R,low,pivotpos-1);       //对左区间递归排序
	QuickSort(R,pivotpos+1,high);      //对右区间递归排序
    }
}

//======直接选择排序========
void SelectSort(SeqList R)
{
    int i,j,k;
    for(i=1;i<n;i++){         //做第i趟排序(1≤i≤n-1)
	k=i;
		for(j=i+1;j<=n;j++)  //在当前无序区R[i‥n]中选key最小的记录R[k]
	   		if(R[j].key<R[k].key)
				k=j;         //k记下目前找到的最小关键字所在的位置
		if(k!=i) {  //       //交换R[i]和R[k]
	   		R[0]=R[i];R[i]=R[k];R[k]=R[0];
		} //endif
    } //endfor
}

//==========大根堆调整函数=======
void Heapify(SeqList R,int low,int high)
{     // 将R[low..high]调整为大根堆,除R[low]外,其余结点均满足堆性质
    int large;        //large指向调整结点的左、右孩子结点中关键字较大者
    RecType temp=R[low]; //暂存调整结点
    for(large=2*low; large<=high;large*=2){  //R[low]是当前调整结点
      //若large>high,则表示R[low]是叶子,调整结束;否则先令large指向R[low]的左孩子
		if(large<high && R[large].key<R[large+1].key)
	    		large++; //若R[low]的右孩子存在且关键字大于左兄弟,则令large指向它
        //现在R[large]是调整结点R[low]的左右孩子结点中关键字较大者
	if(temp.key>=R[large].key)  //temp始终对应R[low]
		    break;  //当前调整结点不小于其孩子结点的关键字,结束调整
		R[low]=R[large];  //相当于交换了R[low]和R[large]
		low=large;  //令low指向新的调整结点,相当于temp已筛下到large的位置
   }
   R[low]=temp;   //将被调整结点放入最终位置上
}

//==========构造大根堆==========
void BuildHeap(SeqList R)
{       //将初始文件R[1..n]构造为堆
    int i;
    for(i=n/2;i>0;i--)
	Heapify(R,i,n);      //将R[i..n]调整为大根堆
}

//==========堆排序===========
void HeapSort(SeqList R)
{               //对R[1..n]进行堆排序,不妨用R[0]做暂存单元
    int i;
    BuildHeap(R);  //将R[1..n]构造为初始大根堆
    for(i=n;i>1;i--){      //对当前无序区R[1..i]进行堆排序,共做n-1趟。
	R[0]=R[1]; R[1]=R[i];R[i]=R[0];     //将堆顶和堆中最后一个记录交换
		Heapify(R,1,i-1);   //将R[1..i-1]重新调整为堆,仅有R[1]可能违反堆性质。
    }
}

//=====将两个有序的子序列R[low..m]和R[m+1..high]归并成有序的序列R[low..high]==
void Merge(SeqList R,int low,int m,int high)
{ 
    int i=low,j=m+1,p=0; //置初始值
    RecType *R1;   //R1为局部量
    R1=(RecType *)malloc((high-low+1)*sizeof(RecType)); //申请空间
    while(i<=m && j<=high)      //两个子序列非空时取其小者输出到R1[p]上
	R1[p++]=(R[i].key<=R[j].key)? R[i++]:R[j++];
    while(i<=m)    //若第一个子序列非空,则复制剩余记录到R1
		R1[p++]=R[i++];
    while(j<=high)     //若第二个子序列非空,则复制剩余记录到R1中
	R1[p++]=R[j++];
    for(p=0,i=low;i<=high;p++,i++)
	R[i]=R1[p];    //归并完成后将结果复制回R[low..high]
}

//=========对R[1..n]做一趟归并排序========
void MergePass(SeqList R,int length)
{ 
    int i;
    for(i=1;i+2*length-1<=n;i=i+2*length)
		Merge(R,i,i+length-1,i+2*length-1); //归并长度为length的两个相邻的子序列
    if(i+length-1<n)   //尚有一个子序列,其中后一个长度小于length
		Merge(R,i,i+length-1,n);  //归并最后两个子序列
        //注意:若i≤n且i+length-1≥n时,则剩余一个子序列轮空,无须归并
}

//========== 自底向上对R[1..n]做二路归并排序===============
void MergeSort(SeqList R)
{
    int length;
    for(length=1;length<n;length*=2)     //做[lgn]趟排序
	MergePass(R,length);     //有序长度≥n时终止
}

//==========输入顺序表========
void input_int(SeqList R)
{           
    int i;
    printf("\n--请输入需要的数据个数:");
    scanf("%d",&n);
    printf("\n--请输入 %d 个数据:\n",n);
    for(i=1;i<=n;i++)
	scanf("%d",&R[i].key);
}
//==========输出顺序表========
void output_int(SeqList R)
{
    int i;
	printf("---------------------------------\n");
    for(i=1;i<=n;i++)
    printf("%d  ",R[i].key);
}

//主菜单
void menu(SeqList R)
{
	int choice = 0;
	printf("******** 简单排序 ****************\n");
    printf("1:--直接插入排序\n");
    printf("2:--冒泡排序\n");
    printf("3:--快速排序\n");
    printf("4:--直接选择排序\n");
    printf("5:--堆排序\n");
    printf("6:--归并排序\n");
    printf("7:--退出\n");
    printf("*********************************\n");
	printf("--请输入操作数:");
	scanf("%d",&choice);
    switch (choice){
	case 1: system("CLS");
		    InsertSort(R); 
			printf("\n--直接插入排序结果如下:\n");
		    output_int(R);
		    printf("\n\n--按任意键返回--\n");
			getchar();getchar();
			system("CLS");
			menu(R);//值为1,直接插入排序
	case 2: system("CLS");
		    BubbleSort(R);
			printf("\n--冒泡排序排序结果如下:\n");
		    output_int(R);
			printf("\n\n--按任意键返回--\n");
			getchar();getchar();
			system("CLS");
			menu(R);       //值为2,冒泡法排序
	case 3: system("CLS");
		    QuickSort(R,1,n);			
			printf("\n--快速排序结果如下:\n");
		    output_int(R);
			printf("\n\n--按任意键返回--\n");
			getchar();getchar();
			system("CLS");
			menu(R);    //值为3,快速排序
	case 4: system("CLS");
		    SelectSort(R); 		
			printf("\n--直接选择排序结果如下:\n");
		    output_int(R);
			printf("\n\n--按任意键返回--\n");
			getchar();getchar();
			system("CLS");
			menu(R);       //值为4,直接选择排序
	case 5: system("CLS");
		    HeapSort(R);
			printf("\n--堆排序结果如下:\n");
		    output_int(R);
			printf("\n\n--按任意键返回--\n");
			getchar();getchar();
			system("CLS");
			menu(R);         //值为5,堆排序
	case 6: system("CLS");
		    MergeSort(R); 
			printf("\n--归并排序结果如下:\n");
		    output_int(R);
			printf("\n\n--按任意键返回--\n");
			getchar();getchar();
			system("CLS");
			menu(R);//值为6,归并排序
	case 7: system("CLS");printf("\n--退出排序--\n");exit(0);                    //值为7,结束程序
    }
}
//主函数
#include "WW.h"
void main()
{
    SeqList R;
    input_int(R);
	system("CLS");
	menu(R);
}


南邮数据结构实验四----各种内排序算法的实现及性能比较

一、 实验目的和要求 内容: 验证教材的各种内排序算法。分析各种排序算法的时间复杂度。 要求: 使用随机数产生器产生大数据集合,运行上述各种排序算法,使用系统时钟测量各算法所需的实际时间,并进...
  • zl1085372438
  • zl1085372438
  • 2017年01月23日 16:58
  • 517

各种排序算法性能之间的比较

今天总结一下各种常见的排序算法的时间性能、空间性能以及适用的场景。 排序法 平均时间 最坏时间 最好时间 稳定性 额外空间 备注 冒泡法 O(n*n) O(n*n) O(n) 稳定 O(...
  • liushaheliusha
  • liushaheliusha
  • 2015年07月23日 15:09
  • 340

南邮数据结构实验1 顺序表操作

实验内容和提示: 1.在顺序表类SeqList中增加成员函数void Reverse(),实现顺序表的逆置。 2.在顺序表类SeqList中增加成员函数bool DeleteX(const T &...
  • Tc_To_Top
  • Tc_To_Top
  • 2014年09月23日 00:10
  • 3452

【数据结构排序算法系列】数据结构八大排序算法

排序算法在计算机应用中随处可见,如Windows操作系统的文件管理中会自动对用户创建的文件按照一定的规则排序(这个规则用户可以自定义,默认按照文件名排序)因此熟练掌握各种排序算法是非常重要的,本博客将...
  • htq__
  • htq__
  • 2016年03月25日 22:36
  • 94214

【数据结构】几种常见的排序算法

一、排序算法的分类     下图是我掌握的一些排序算法,我将他们做了分类,当然,排序算法远不止这些。 本篇博客主要记录插入,选择,以及交换排序的冒泡排序,因为快排和归并算法相对复杂,所以,...
  • pointer_y
  • pointer_y
  • 2016年11月26日 23:06
  • 1389

数据结构与算法--查找与排序(一)

Top 线性查找二分查找冒泡排序插入排序选择排序快速排序归并排序 1 线性查找 1.1 问题 线性查找,又称为顺序查找,是指在所有给定的值中从一端开始逐个检查每个元素是否为要查...
  • opera95
  • opera95
  • 2016年04月22日 08:30
  • 2746

数据结构与算法之排序算法---简单选择排序

数据结构与算法之排序算法—简单选择排序 简单选择排序的基本思想 完整实现代码 复杂度分析 2016年10月18日15:54:57 by:piaxiaohui简单排序的基本思想...
  • u010548437
  • u010548437
  • 2016年10月18日 16:28
  • 974

数据结构-排序算法原理和Python实现

排序算法概览 插入排序 直接插入排序 希尔排序 交换排序 冒泡排序 快速排序 选择排序 简单选择排序 堆排序 归并排序 基数排序 有些时候看懂了,不一定会写,不妨自己写一遍代码看看会有什么收获。排序算...
  • shine19930820
  • shine19930820
  • 2017年04月09日 22:30
  • 547

数据结构与算法分析-排序

作者:xiabodan 出处:http://blog.csdn.net/xiabodan  排序算法(Sorting Algorithm)是计算机算法的一个组成部分。也是程序=算法+数据结构中的一部...
  • xiabodan
  • xiabodan
  • 2015年06月04日 14:39
  • 1436

数据结构之排序算法(二)-冒泡排序及改进

冒泡排序算法需要遍历几次数组。每次遍历都要比较连续相邻的元素,如果某一对相邻元素是降序,则互换它们的值,否则,保持不变。由于较小的值像“气泡”一样逐渐浮想顶部,而较大的值沉向底部,所以叫冒泡排序。 ...
  • tuke_tuke
  • tuke_tuke
  • 2015年12月21日 15:10
  • 2059
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:数据结构排序算法
举报原因:
原因补充:

(最多只允许输入30个字)