堆排序,快速排序,归并排序算法比较

快速排序:每次排序将数组分为以某元素为划分点,  大于该元素的值在该元素右边, 小于该元素的值在该元素左边,  以某元素为中心,分别对该元素左边和右边子数组进行快排.每次确定一个元素的位置,  则 使得多个元素有序,  所以称为快排。

  堆排序:  将数组看成完全二叉树的形式,   根节点root与子节点node位置关系是2*root=node或者2*root+1=node,  构建大根堆小根堆( 堆顶记录大于(小于)或等于所有子节点记录  ), 根据性质,每次可将堆的最大值(最小值)找出来并放到指定位置,   再调整堆(除去以排好序的元素), 直到所有元素排好序为止。

归并排序: 利用分治法,   每次将数组一分为二,  生成子数组,  分别对子数组排序,   在对排好序的子数组进行合并,  直到生成 有序的完整数组为止。

三种排序实现。

void Pushdown(int *a, int low, int high)
{
	int i = low, j = 2 * i;
	int temp = a[i];
	while (j <= high)
	{
		if (j<high&&a[j]>a[j + 1])
		{
			j++;
		}
		if (temp>a[j])
		{
			a[i] = a[j];
			i = j;
			j = 2 * i;
		}
		else break;
	}
	a[i] = temp;
}
//堆排序
void HeadSort(int *a, int n)
{
	for (int i = n / 2;i >= 1;i--)
	{
		Pushdown(a, i, n);
	}
	for (int i = n;i >= 2;i--)
	{
		swap(a[1], a[i]);
		Pushdown(a, 1, i - 1);
		break;
	}

}

//快速排序  
void quicksort(int *a,int left, int right)
{
	int i, j, temp, t;
	if (left > right)
	{
		return;
	}
	i = left;
	j = right;
	temp = a[left];
	while (i != j)
	{
		while (a[j] >= temp && i < j)
		{
			j--;
		}
		while (a[i] <= temp && i < j)
		{
			i++;
		}
		if (i < j)
		{
			t = a[i];
			a[i] = a[j];
			a[j] = t;
		}
	}
	a[left] = a[i];
	a[i] = temp;
	quicksort(a,left, i - 1);
	quicksort(a,i + 1, right);
}

//合并排序

void merge(int* a, int l, int m, int h) {
	if (l == h)
		return;

	int* b = (int*)malloc(sizeof(int) * (h - l + 1));
	int i = l, j = m + 1;
	int k = 0;

	while (i <= m && j <= h)
		b[k++] = a[i] > a[j] ? a[j++] : a[i++];

	if (i <= m)
		while (i <= m)
			b[k++] = a[i++];
	if (j <= h)
		while (j <= h)
			b[k++] = a[j++];
	//回写
	i = l;
	k = 0;

	for (; i <= h;)
		a[i++] = b[k++];
}

void mergeSort(int* a, int l, int h) {
	if (l >= h)
		return;
	int m = (h + l) / 2;
	mergeSort(a, l, m);
	mergeSort(a, m + 1, h);
	merge(a, l, m, h);
}

快速排序递归爆栈加上这句:

//这句用于解决C++快速排序递归爆栈问题,加在头文件前面
#pragma comment(linker, "/STACK:1024000000,1024000000")  



100000的数据快排已经炸了QWQ。



猜你喜欢

转载自blog.csdn.net/swust_zeng_zhuo_k/article/details/80138726