[算法天天练] 归并排序

要实现归并排序递归方法:

第一步:先将原来的数据表分成排好序的子表,然后调用合并函数对子表进行归并,使之成为有序表

例如有如下向量:

⑴    ⑵   ⑶   ⑷   ⑸   ⑹   ⑺    ⑻   ⑼    ⑽   ⑾
25, 10, 7, 19, 3, 48, 12, 17, 56, 30, 21
                    /         25,10,7,19,3        48,12,17,56,30,21
         /   \                         /    25,10    7,19,3     48,12,17    56,30,21
 /      \       /  \           /   \           /   25      10   7    19,3    ...    ...       ...    ...

归并算法的划分子表和归并子表与原数据序列次序无关,因此算法的最坏情况,最坏情况和平均情况时间复杂度是一样的

#include <stdio.h>
#include <stdlib.h>

void Merge(int arr[], int beg, int mid, int end)
{
	int i = beg;
	int j = mid + 1;
	int p = 0;

	int *ipa;
	ipa = (int*)malloc((end-beg+1) * sizeof(int));
	if(!ipa) return;

	while(i <= mid && j <= end)
	{
 		//ipa[p++] = (arr[i]<=arr[j])?arr[i++]:arr[j++];
 		if(arr[i] <= arr[j])
 		{
 			ipa[p] = arr[i];
 			p++;
 			i++;
		}
		else
		{
			ipa[p] = arr[j];
			p++;
			j++;
		}
	}	

	while(i<=mid)
	{
		ipa[p++] = arr[i++];
	}

	while(j<=end)
	{
		ipa[p++] = arr[j++];
	}

	for(p=0, i=beg; i<=end; p++, i++)
	{
		arr[i] = ipa[p];
	}
}

void MergeSort(int arr[], int beg, int end)
{
	int mid;
	if(beg < end)
	{
		mid = (beg + end)/2;
		MergeSort(arr, beg, mid);
		MergeSort(arr, mid+1, end);
		Merge(arr, beg, mid, end);
	}
}

int main()
{
	int a[9] = {7,10,48,25,12,17,21,48,30};

	printf("Before Merge Sort:\n");

	for(int i=0; i<9; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");

	printf("After Merge Sort:\n");
	MergeSort(a, 0, 8);
	for(int i=0; i<9; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");

	return 0;
}

参考:http://jillzhang.cnblogs.com/

http://blog.csdn.net/cwj649956781/article/details/7409635

时间: 2024-10-13 10:24:04

[算法天天练] 归并排序的相关文章

[转][算法天天练]堆与堆排序

堆排序与快速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法.学习堆排序前,先讲解下什么是数据结构中的二叉堆. 二叉堆的定义 二叉堆是完全二叉树或者是近似完全二叉树. 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值. 2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆). 当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆.当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆.下图展示一个最小堆: 由于其它几

[算法天天练]冒泡排序

/* * 冒泡排序 * 核心原来:每次比较两个相邻的元素,如果它们的顺序不符合要求就把它们交换 * 每趟只能确定一个数归位 * 冒泡算法的时间复杂度为O(N*N),除了名字有点儿意思外,确实效率不高 */ void BubbleSort(int array[], int length) { int tmp; for(i=0; i<length-1; i++) { for(j=0; j<length-i-1; j++)// 这里是冒泡的核心,手动画图一目了然 { if(array[j]>a

[算法天天练]快速排序

快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常被采用,作为面试题来考试. 该方法的基本思想是: 1.先从数列中取出一个数作为基准数. 2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边. 3.再对左右区间重复第二步,直到各区间只有一个数. 以一个数组作为示例,取区间第一个数为基准数. 0 1 2 3 4 5 6 7 8 9 72 6 57 88 60 42 83 73 48 85 初始时,i = 0;  j = 9;   X = a[i]

[算法天天练]选择排序

选择排序 #include <iostream> using namespace std; void SelectSort(int data[], int ilen) { int temp; int iIndex = 0; for(int i=0; i<ilen-1; i++) { iIndex = i; for(int j=i+1; j<ilen; j++) { if(data[j]<data[iIndex]) { iIndex = j; } } if(iIndex !=

[算法天天练]插入排序算法

#include <stdio.h> void show(int arr[], int length) { for(int i=0; i<length; i++) { printf("%d ", arr[i]); } printf("\n"); } void s_insert(int arr[], int length) { if(length < 0) return ; for(int i=1; i<length; i++) { in

[算法天天练] - C语言实现约瑟夫环(2)

Linux下 #include <stdlib.h>#include <stdio.h> int main(){ int n,m,i,s = 0; printf("Entr N, M = "); scanf("%d%d", &n, &m); for(i=2; i<=n; i++) { s = (s+m) % i; } printf("\n the winner is %d\n", s+1);}

[算法天天练]选择排序法

#include<stdio.h> void show(int arr[], int length) { for(int i=0; i<length; i++) { printf("%d ", arr[i]); } printf("\n"); } void _swap(int *a, int *b) { int tmp = *a; *a = *b; *b = tmp; } void SelectSort(int arr[], int length)

[算法天天练]递归查找和非递归查找

//Data为要查找的数组,x为待查找数据值,beg为查找范围起始,last为查找范围终止 //非递归法 int BiSearch(int data[], const int x, int beg, int last) { int mid;//中间位置 if (beg > last) { return -1; } while(beg <= last) { mid = (beg + last) / 2; if (x == data[mid] ) { return mid; } else if (

[算法天天练]桶排序

[问题]:如果有一组数据a[]={0,9,2,3,4,5,3,5,2,8},对它进行从小到大的顺序排列 #include <stdio.h> void BucketSort() { int i, j; int a[] = {0,9,2,3,4,5,3,5,2,8}; int b[10] = {0}; int iaSize = sizeof(a)/sizeof(int); int ibSize = sizeof(b)/sizeof(int); for(i=0; i<iaSize; i++)