您的位置:首页 > 理论基础 > 数据结构算法

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

2015-10-08 16:23 281 查看
<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一个临时数组。后面的操作都共用这一个临时数组。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: