归并排序(非递归) ----- C语言

原创 2015年11月20日 22:38:20

归并排序(Merge sort,台湾译作:合并排序)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

算法步骤:

1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置

3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

4. 重复步骤3直到某一指针达到序列尾

5. 将另一序列剩下的所有元素直接复制到合并序列尾




以上理论归理论,代码要实现其实还是有难度的,自己搞了很久才基本弄清楚非递归的归并排序的基本思想,查阅许久才看懂代码,自己简单地实现了一下:


#define A_LENGTH 10
#include <stdio.h>
#include <stdlib.h>

int MergeSort(int *a)
{
	int k = 1;/*k用来表示每次k个元素归并*/
	int *temp = (int *)malloc(sizeof(int) * A_LENGTH);
	
	while (k < A_LENGTH)
	{
		//k每次乘以2是遵循1->2->4->8->16的二路归并元素个数的原则
		MergePass(a, temp, k, A_LENGTH);/*先借助辅助空间归并*/
		k *= 2;
		
		MergePass(temp, a, k, A_LENGTH);/*再从辅助空间将排过序的序列归并回原数组*/
		k *= 2;
	}
}


int MergePass(int *S, int *T, int times, int length)
{
	int i = 0, s = times, l;
	
	while ((i + 2*s - 1) < length)
	{
		Merge(S, T, i, i+s-1, i+2*s-1);
		i += 2*s;
	}/*此处的循环用于遍历数组全部元素并依照k(此处为赋值为s)来归并入辅助的数组空间中*/
	
	/*if-else用于处理归并剩下的序列,因为已经不满足(i + 2*s - 1) < length的条件
	* 所以需要修改Merge()函数的下标,而如果满足(i + s - 1) < length即表示
	* i 到 i + s - 1 这段序列为归并的第一段,剩下一段为 i + s 到 length - 1,
	* 而如果不满足if条件则说明剩下序列已经有序,直接循环赋值给目标数组即可
	*/
	if ((i + s - 1) < length)
	{
		Merge(S, T, i, i+s-1, length-1);
	}
	else
	{
		for (l = i; l < length; l++)
		{
			T[l] = S[l];
		}
	}
}


//归并排序最主要实现函数
int Merge(int *S, int *T, int low, int m, int high)
{//j在[m+1,high]区间递增,k用于目标T的下标递增, l是辅助变量
	int j, k, l;
	
	for (k = low, j = m+1;
		low <= m  &&  j <= high;
		k++)
	{
		if (S[low] < S[j])
		{
			T[k] = S[low++];	//此处先执行T[k] = S[low],然后low++;
		}
		else
		{
			T[k] = S[j++];		//同理
		}
	}
	
	//for循环过后,必然有low>m 或者 j>high,故分情况处理
	if (low <= m)
	{
		for (l = 0; l <= m-low; l++)
		{
			T[k+l] = S[low+l];
		}
	}
	
	if (j <= high)
	{
		for (l = 0; l <= high-j; l++)
		{
			T[k+l] = S[j+l];
		}
	}
}


int main()
{
	int i;
	int a[A_LENGTH] = {50, 90, 80, 40, 30,
						120, 150, 200, 70, 60};
			
	printf("Before sorting:");
	for (i = 0; i < A_LENGTH; i++)
	{
		printf("%d -- ", a[i]);
	}
	
	MergeSort(a);
	
	printf("\n\nAfter sorting: ");
	for (i = 0; i < A_LENGTH; i++)
	{
		printf("%d -- ", a[i]);
	}
	return 0;
}






版权声明:本文为 Snow Yong 原创文章,烦请转载注明出处

归并排序非递归算法

归并排序非递归算法 #include #include #define MAX 1000 typedef struct seeqlist { int Array[MAX]; int lengt...
  • u012736084
  • u012736084
  • 2014年02月02日 16:05
  • 1734

C语言 归并排序 非递归

7-18 排序(25 分) 给定N个(长整型范围内的)整数,要求输出从小到大排序后的结果。 本题旨在测试各种不同的排序算法在各种数据情况下的表现。各组测试数据特点如下: ...
  • Cute_jinx
  • Cute_jinx
  • 2017年12月27日 17:33
  • 15

【排序】归并排序(递归和非递归版本)

#include using namespace std; void merge(int* a, int* temp, int begin, int middle, int end){ int i...
  • ruan875417
  • ruan875417
  • 2016年05月14日 13:47
  • 736

归并排序非递归实现C语言

  话说这个东西写到凌晨3点27分,都没有写好.刚才睡醒了写完的.主要遇到的问题就是当数组大小不是2的幂的时候发生的 right_end 越界的时候.我的逻辑起初偏于复杂,后来重新组织逻辑,当发生 r...
  • Golden_Shadow
  • Golden_Shadow
  • 2010年11月21日 13:33
  • 1052

归并排序(非递归算法)

 8645 归并排序(非递归算法) 时间限制:1000MS  内存限制:1000K 题型: 编程题   语言: 无限制   Description 用函数实现归并排序(非递归算法),并...
  • xyh_Adolph
  • xyh_Adolph
  • 2014年06月06日 13:14
  • 920

排序【5】之归并排序的C语言实现

利用递归与分治技术将数据序列划分为越来越小的半子表,再对半子表排序,最后再用递归步骤将排好序的半子表合并成为越来越大的有序序列。 原理如下:对于给定的一组记录,首先将两个相邻的长度为...
  • CYQ0318
  • CYQ0318
  • 2018年01月19日 19:57
  • 16

归并排序非递归写法

void _Merge(int arr[], int* tmp, int begin1, int end1, int begin2, int end2) { int index = begin1; ...
  • LookAtTheStars
  • LookAtTheStars
  • 2016年08月11日 14:36
  • 215

C语言实现快排、归并排序、快排改进算法的递归和非递归算法

其实以上算法的原理都很简单。在本科阶段,我们对这几个算法的基本原理都应该十分熟悉,但对于我,真正落实到是实现这几算法,之前几乎没有试过。现在刚上研一,算法课的第一次作业中,要求我们将这几个算法实现,对...
  • dzyhenry
  • dzyhenry
  • 2012年11月01日 19:43
  • 3312
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:归并排序(非递归) ----- C语言
举报原因:
原因补充:

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