第七章第二节(堆排序,归并排序)

堆排序:是利用二叉堆来进行排序的一种算法。在排序时如果是从小到大排序,则建立最大堆。如果是从大到小排序,则建立最大堆。
堆排序的时间效率为O(N logN)
本算法是从大到小排序
排序步骤:
1.将待排序数组建立最大堆
2.将A[0]与数组的最后一个数据进行交换,此时最大的数据就到数组的最后一个单元
3.调整堆结构,继续交换。

归并排序:归并排序:归并排序是以O(N logN)最坏时间运行,而所使用的比较次数几乎是最优的。
归并排序是基于合并以完成排序的表。
该算法是经典的分治策略,将数组中的每一个元素都看作一个以完成排序的表,逐步合并,最终完成排序

堆排序代码

void bulidHeap(int a[],int P,int N) {
	//a为堆数组,P为堆的父亲节点,N为堆的大小
	int Child, i, tmp;
	tmp = a[P];
	for (i = P; i * 2 + 1 < N; i = Child) {	//下滤调整堆结构
		Child = i * 2 + 1;
		if ((Child != N - 1) && a[Child] < a[Child + 1]) {
			Child++;
		}
		if (tmp < a[Child]) {
			a[i] = a[Child];
		}
		else {
			break;
		}
	}
	a[i] = tmp;
}
void HeapSort(int a[],int N) {
	int i, tmp;	
	//初始化堆
	for (i = N / 2; i >= 0; i--) {
		bulidHeap(a, i, N);
	}
	for (i = N - 1; i > 0; i--) {
		//交换堆根节点和尾节点
		tmp = a[i];
		a[i] = a[0];
		a[0] = tmp;
		bulidHeap(a, 0, i);			//已0为根节点调整堆
	}
}

归并排序代码

void MergeSort(int a[],int N) {
	// a为待排序的数组,N为数组规模
	int *tmpArray;
	tmpArray = (int*)malloc(N * sizeof(int));
	//tmpArray是排序过程中产生的中间数组
	if (tmpArray != NULL) {
		Msort(a,tmpArray, 0, N - 1);
		free(tmpArray);
	}
	else {
		printf("空间不足\n");
	}
}
void Msort(int a[], int tmpArray[], int left, int right) {
	//分治归并排序
	//a为待排序数组,tmpArray为中间数组,left为左边开始的第一个数的下标
	//right为最右边最后一个数的下标
	int Center;
	if (left < right) {
		Center = (right + left) / 2;
		//不断缩小问题的规模
		Msort(a,tmpArray,left,Center);
		Msort(a, tmpArray, Center + 1, right);
		Merge(a, tmpArray, left, Center + 1, right);	//合并两个以完成排序的数组
	}
}
void Merge(int a[], int tmpArray[], int Lpos, int Rpos, int RightEnd) {
	//a为待排序数组,tmpArray为中间数组,Lpos为第一个表开始下标,Rpos为第二个表开始的下标
	//rightEnd为第二个表最后一个数字的下标
	int i, tmpPos, Num;
	int LposEnd;
	LposEnd = Rpos - 1;
	tmpPos = Lpos;
	Num = RightEnd - Lpos + 1;
	//第一个表 从Lops到LposEnd,第二个表 从Rpos到RightEnd
	while (Lpos <= LposEnd && Rpos <= RightEnd) {		//两个表中数据都不为空
		if (a[Lpos] <= a[Rpos]) {			//如果第一个表中的数较小,则将数据保存到中间数组
			tmpArray[tmpPos++] = a[Lpos++];
		}
		else {
			tmpArray[tmpPos++] = a[Rpos++];
		}
	}
	while (Lpos <= LposEnd) {		//表1数据不为空
		tmpArray[tmpPos++] = a[Lpos++];
	}
	while (Rpos <= RightEnd) {		//表2数据不为空
		tmpArray[tmpPos++] = a[Rpos++];
	}
	//中间数组将已排序数据写回原来数组
	for (i = 0; i <Num ; i++,RightEnd--) {
		a[RightEnd] = tmpArray[RightEnd];
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值