归并排序(递归和非递归)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lingling_nice/article/details/80955007

归并排序主要讲二路归并排序

二路归并排序的基本思想:

     设数组a中存放了n个数据元素,初始时把他们看成是n个长度为1的有序子数组,然后从第一个子数组开始,把相邻的子数组进行两两合并,的到n/2的整数上界个长度为2的新的有序子数组(当n为奇数时最后一个新的有序子数组的长度为1);对这些新的有序子数组在两两归并;如此重复,直到得到一个长度为n的有序数组为止。

归并排序的过程图:

归并排序的完整代码(非递归):

#include<iostream>
#include<malloc.h>
using namespace std;
 void meger(int *arr,int len,int gap)
{
	int *buff=(int*)malloc(sizeof(int)*len);//设置一个临时的buff
	if(buff==NULL)
	{
		exit(0);
	}
	int i=0;
	int low1=0;
	int high1=low1+gap-1;
	int low2=high1+1;
	int high2=(low2+gap-1)  < len ? (low2+gap-1) : (len-1);//当第二段的数据小于len时,就用第二段的数据

	while(low2<len) //第二段有数据时候,第二段有数据才能进行归并
	{
		while(low1<=high1 && low2<= high2)
		{
			if(arr[low1]<=arr[low2])
			{
				buff[i++]=arr[low1++];
			}
			else if(arr[low1]>arr[low2])
			{
				buff[i++]=arr[low2++];
			}
		}
		while(low1<=high1)//第一段中有剩余,一定不要忘记写等号
		{
			buff[i++]=arr[low1++];
		}
		while(low2<=high2)//第二段中有剩余,不要忘记写等号
		{
			buff[i++]=arr[low2++];
		}
		low1=high2+1;
		high1=low1+gap-1;
		low2=high1+1;
		high2=(low2+gap-1) <len ? (low2+gap-1) : (len-1)  ;
	}
	while(low1<len)//只有第一段,没有第二段
	{
	   buff[i++]=arr[low1++];
	}
	for(int j=0;j<len;++j)
	{
		arr[j]=buff[j];//把数据拷贝过来
	}
	free(buff);
}

void merger_sort(int *arr,int len)
{
	for(int gap=1;gap<len;gap*=2)//把带排序的数组进行排序
	{
		meger(arr,len,gap);
	}
}
int main()
{
	int arr[]={12,56,89,45,1,46};
	int len=sizeof(arr)/sizeof(arr[0]);
	merger_sort(arr,len);
	for(int i=0;i<len;i++)
	{
		cout<<arr[i]<<"  ";
	}
	cout<<endl;
}

归并排序的代码(递归):

#include<iostream>
#include<malloc.h>
using namespace std;
#define  maxsize   10

void megering(int *left,int left_size,int *right,int right_size)
{
	int i=0;
	int j=0;
	int k=0;
	int temp[maxsize];//用来存储排序的数据
	while(i<left_size && j<right_size)
	{
		if(left[i]<=right[j])//左边数据《 右边的数据
		{
			temp[k++]=left[i++];//就把左边的数据存储到temp数组中
		}
		else
		{
			temp[k++]=right[j++];//右边的数据小,就存储右边的数据
		}
	}
	while(i<left_size)//左边的数据有剩余,直接把左边的数据拷贝到temp数组中
	{
		temp[k++]=left[i++];
	}
	while(j<right_size)//右边的数据有剩余,就把右边的数据拷贝到temp数组中
	{
		temp[k++]=right[j++];
	}
	for(int m=0;m<(left_size+right_size);++m)
	{
		left[m]=temp[m];//最后的结果存在left数组中
	}
}
void meger_sort(int *arr,int len)
{
	if(len>1)//递归调用的出口
	{
		int *left=arr;//left指向数组的首地址
		int left_size=len/2;//len/2代表的是数组一半的数据,left_size代表的是左半部分的数据个数
		int *right=arr+len/2;//right指向的是右边部分的首元素
		int right_size=len-left_size;//右边部分元素的个数
		
		meger_sort(left,left_size);//划分左边,递归左半部分,即左边一直分,直达只有一个元素
		meger_sort(right,right_size);//划分右边,递归右半部分,即右边一直分,直到只有一个元素

		megering(left,left_size,right,right_size);//归并
	}
}
int main()
{
	int arr[]={1,8,4,50,4};
	int len=sizeof(arr)/sizeof(arr[0]);
	meger_sort(arr,len);
	for(int i=0;i<len;i++)
	{
		cout<<arr[i]<<"  ";
	}
	cout<<endl;
}

猜你喜欢

转载自blog.csdn.net/lingling_nice/article/details/80955007