1. 程式人生 > >歸併排序(視訊+詳解+程式碼)

歸併排序(視訊+詳解+程式碼)

歸併排序

概述:歸併排序(MERGE-SORT)是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱為二路歸併

歸併過程為:比較a[i]a[j]的大小,若a[i]≤a[j],則將第一個有序表中的元素a[i]複製到r[k]中,並令ik分別加上1;否則將第二個有序表中的元素a[j]複製到r[k]中,並令jk分別加上1,如此迴圈下去,直到其中一個有序表取完,然後再將另一個有序表中剩餘的元素複製到r中從下標

k到下標t的單元。歸併排序的演算法我們通常用遞迴實現,先把待排序區間[s,t]以中點二分,接著把左邊子區間排序,再把右邊子區間排序,最後把左區間和右區間用一次歸併操作合併成有序的區間[s,t]

歸併操作

歸併操作(merge),也叫歸併演算法,指的是將兩個順序序列合併成一個順序序列的方法。

如 設有數列{62021003013881}

初始狀態:6,202,100,301,38,81

第一次歸併後:{6,202},{100,301},{8,38},{1},比較次數:3

第二次歸併後:{6,100,202,301}{1,8,38},比較次數:4

第三次歸併後:{1,6,8,38,100,202,301},比較次數:

4

總的比較次數為:3+4+4=11,

逆序數為14

演算法描述

歸併操作的工作原理如下:

第一步:申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合併後的序列

第二步:設定兩個指標,最初位置分別為兩個已經排序序列的起始位置

第三步:比較兩個指標所指向的元素,選擇相對小的元素放入到合併空間,並移動指標到下一位置

重複步驟3直到某一指標超出序列尾

將另一序列剩下的所有元素直接複製到合併序列尾

程式碼:

#include<stdio.h>
void merge_sort(int *a,int *b,int x,int y)
{
	if(y-x>1)
	{
		int m=x+(y-x)/2;//中間點的座標 
		int p=x,q=m,i=x;
		merge_sort(a,b,x,m);
		merge_sort(a,b,m,y);
		while(p<=m||q<y)
		{
			if(q>=y||(p<m&&a[p]<=a[q]))
			b[i++]=a[p++];//從左半陣列複製到臨時空間
			else b[i++]=a[q++];// 從右半陣列複製到臨時空間
		}
		for(i=x;i<y;i++)
		a[i]=b[i]; 
	}
}
int main()
{
	int b[100],a[100],n;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	scanf("%d",&a[i]);
	int mid=n/2;
	merge_sort(a,b,0,n); 
	for(int i=0;i<n;i++)
	printf("%d ",a[i]);
	return 0;
}