数据结构------归并排序大彻大悟啊!!

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">不得不说,学习真的是一个重复的过程,一个很难得东西,看的多了,也就不难么难了,怕就怕你接触的太晚,没有顿悟的时间。</span>

归并排序:

这个排序的核心思想就是,把一段数字,分割成几小段有序的数列,然后对这几段数据在进行两两合并,这是一个递归的过程。

为什么这么做:

  可能这个时候你心里会想,干嘛这么麻烦,直接分两段,直接两两比较排序,就完了嘛......也许你也想到这了,但是你再接着往下一想,你就发现问题了,如果你合并的不是两段已经排好序的数列,那么你就会无形中比较很多次。

在分析:

下面我们看一下,排好序的两段数字a1,a2,只用每次用1的头,与2的头进行比较,不用循环遍历后面的数字,因为这两个数组都是有序的。

  如果是两段无序列的,那么每次都得用1的头,跟2的所有元素进行比较,太麻烦。。。。。。

下面我们来看归并排序的代码

<pre name="code" class="cpp">/*
归并排序,递归调用
图MergeSort
*/
#include <iostream>
using namespace std;
void mergearry(int arr[],int first,int mid,int last,int temp[]);
void mergesort(int arr[],int first,int last,int temp[]);
void MergeSort(int arr[],int num);

int main()
{
	int arr[] = {10,34,5435,5435,234,2,432,432,44,431};
	int num = sizeof(arr) / sizeof(arr[0]);
	MergeSort(arr,num);
	for(int i = 0;i<num ;i++)
	{
		printf("%d ",arr[i]);
	}
	return 0;
}

void MergeSort(int arr[],int num)                               //单独写这样一个函数,方便递归调用
{
	int *temp = (int *)malloc(sizeof(arr[0])*num);               //分配出辅助数组临时存储的空间
	if(temp == NULL)
		return ;
	mergesort(arr,0,num-1,temp);
}

void mergesort(int arr[],int first,int last,int temp[])         //作用是,分割数组
{
	int mid;
	if(first >= last)
		return ;
	mid = (last + first) /2;
	mergesort(arr,first,mid,temp);							//左边的数据分解,
	mergesort(arr,mid +1 ,last,temp);						//进行右边的数据分解
	mergearry(arr,first,mid,last,temp);
}


void mergearry(int arr[],int first,int mid,int last,int temp[])                    //讲分配好的两段数字,排成有序的一段
{
	int i = first;
	int j = mid + 1;
	int m = mid;
	int n = last;
	int k = 0;

	while(i<= m && j<= n )         //每次都是比较数组的前半部分,存入到辅助数组空间temp
	{
		if(arr[i] < arr[j])
			temp[k++] = arr[i++];
		else
			temp[k++] = arr[j++];
	}
	while(i <= m)                      //当一个数组完了之后,只用把剩下的那个数组接上到temp就可以了
	{
		temp[k++] = arr[i++];
	}
	while(j <= n)
	{
		temp[k++] = arr[j++];
	}
	for(i = 0;i<k;i++)
	{
		arr[first + i] = temp[i];
	}

}





归并排序的效率是比较高的,设数列长为N,将数列分开成小数列一共要logN步,每步都是一个合并有序数列的过程,时间复杂度可以记为O(N),故一共为O(N*logN)。因为归并排序每次都是在相邻的数据中进行操作,所以归并排序在O(N*logN)的几种排序方法(快速排序,归并排序,希尔排序,堆排序)也是效率比较高的。


注:有的书上是在mergearray()合并有序数列时分配临时数组,但是过多的malloc操作会非常费时。因此作了下小小的变化。只在MergeSort()中malloc一个临时数组。后面的操作都共用这一个临时数组。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值