ProDeveloperTutorial.com

教程和编程解决方案
菜单
  • Shell脚本
  • 系统设计
  • Linux系统编程
  • 4g LTE
  • 编码问题
  • C
  • C ++
  • DSA
  • GIT

排序算法4:合并排序

前开发者教程 2019年4月19日

合并排序介绍

合并排序基于分而治之。

以下是基本步骤,之后我们将研究实现。

划分: 将数组分成两半。如果数组具有n个元素,则在第一级将其除以n / 2。然后将那些2数组再次除以2。继续直到只有单个元素。

征服: 递归对数组的左部分和数组的右部分排序。

结合: 将数组的左侧部分和数组的右侧部分合并为单个排序的数组。

下图是对数组[40、10、5、20、15、34、7、9]执行的合并排序的图像

划分:

因为我们有8个元素,所以中间元素将是5。因此,我们将数组分为2部分。如果您观察代码,则对数组进行划分后,将递归调用子数组的左侧部分,直到其被排序为止,然后再调用子数组的右侧部分。

请记住,我们将跟踪算法的工作方式。

首先,它将如下分割数组的左部分:

合并排序

再说一次,我们有4个元素,中间元素是2,再次除以数组的左部分,如下所示:

合并排序

同样,我们有2个元素将其划分,如下所示:

合并排序

完成左侧部分后,我们向上移动1级并将右侧部分划分如下:

合并排序

现在左侧和右侧部分已经划分,我们将它们组合成一个排序的数组,如下所示:

合并排序

现在,我们如下所示拆分子数组的右侧部分:

合并排序

再次我们如下分割数组:

合并排序

然后我们将它们合并如下:

合并排序

然后,我们对整个子数组进行排序和合并,如下所示:

合并排序

同样,我们对右子数组也做同样的事情。在为右子数组执行操作时,我们再次选择右子数组的左侧部分并执行类似的操作。完整的递归树如下所示:

合并排序

 

下面我提到了如何进行分而治之的步骤。

合并排序

 

执行合并排序的步骤:

要执行合并排序,我们需要3个元素:

1.要排序的数组。
2.最低索引。
3.最高索引。

我们需要最低和最高索引来计算索引的中间部分,并将数组分为两部分,以后可以合并。

算法MergeSort(array,low,high)

If (low < high)
	 mid <- (low + high) /2	  			// To divide the array into left and right array.
	MergeSort(array, low, mid) 			// Sort left array.
	MergeSort(array, mid + 1, high) 		// Sort right array.
	MergeSortedArray (a, low, mid, high) 	// Merge the sorted left and right array



使用C语言合并排序实现:

#include<stdio.h>

void print_array(int array[], int length)
{
	int index = 0;

	printf("The sorted array is \n");

	for(index = 0 ; index < length ; index++)
	{
		printf("%d\n",array[index] );
	}
}

void  merge_sorted_array( int array[], int low, int mid_index, int high)
{
	int temp_array [100];

	int i = low;
	int j = mid_index + 1 ;
	int k = low;

	while (i <= mid_index && j <= high)
	{
		if(array[i] < array [j])
		{
			temp_array [k] = array[i];
			i++;
			k++;
		}
		else
		{
			temp_array [k] = array[j];
			j++;
			k++;
		}
	}

	//copy the left part of the array to temp_array

	while(i <= mid_index)
	{
		temp_array [k] = array[i];

		k++;
		i++;
	}


	//copy the right part of the array to temp_array

	while(j <= high)
	{
		temp_array [k] = array[j];

		k++;
		j++;
	}

	//copy the tem_array to original array

	for(i =0 ; i <= high; i++)
	{
		array[i] = temp_array[i];
	}

}


void merge_sort (int array[], int low, int high)
{
	int mid_index = 0;
	if (low < high)
	{
		mid_index = (low + high) / 2;
		merge_sort(array, low, mid_index);
		merge_sort(array, mid_index + 1, high);
		merge_sorted_array(array, low, mid_index, high);
	}
}

int main()
{
	int length = 0;
	int array[100];
	int index = 0;

	printf("Enter the length of the array\n");
	scanf("%d", &length);

	printf("Enter the array elements of length %d\n", length);

	for (index = 0; index < length; ++index)
	{
		scanf("%d", &array[index]);
	}

	merge_sort(array, 0, length - 1 );

	print_array(array, length);


}

输出:

Enter the length of the array
5
Enter the array elements of length 5
5
4
3
2
1
The sorted array is
1
2
3
4
5

最坏情况下的运行时间,用于“合并”排序:

Total time taken for merge sort = Time taken to sort left half + Time taken to sort left half +Time taken to merge left and right half.

T(n) = T (n/2) + T (n/2) + n
     = 2 T(n/2) + n ------> Equation 1

Now we need to calculate the time taken for T(n/2). Replace n with n/2 in equation 1.

T(n/2) = 2 * T(n/2/2) + n/2
       = 2T(n/2^2) + n/2 -------> Equation 2.

Now replace the value of n/2 from equation 2 to equation 1.

T(n) = 2 { 2T(n/2) + n/2) + n
     =2^2 T(n/2^2) + n + n 
     =2^2 * T (n/4) + 2n ----> Equation 3.

Now we need to find the value for T(n/4). Hence replace n with n/4 in equation 1, we get
T(n/4) = 2 T(n/8) + n/4.

Now replace the value of T(n/4) with the result above.

T(n) = 2^2 { 2T (n/8) + n/4)} + 2n
     = 2^3 * T(n/2^3) + n + 2n. [here 4 and n/4 cancels each other giving us “n”].
     = 2^3 * T(n/8) + 3n ----> Equation 4

Now again we need to calculate the value of T(n/8), by replacing in equation 1, and replacing in equation 4 we get:
     =2^4 * T (n/2^4) + 4n

Similarly, for T(n/2^4) we get
     = 2^5 * T(n/2^5) + 5n

Hence for ith value, we can write as:
T(n) = 2^i * T (n/2^i) + i*n ---> Equation 5

Once we recursively start to get the value of T(n/2^i), it will be reduced to 1.
Hence 
    n/2^i = 1
    n = 2^i  --->Equation 6
    i = log n ---> Equation 7
Now substitute equation 6 and 7 in 5 we get:

T(n) = n*T(1) + log n * n
	= n + n log n
	=O(n log n)

因此,在最坏的情况下,将进行合并排序 O(n log n) 时间。

进一步阅读:

AJ关于DS和算法的权威指南。单击此处以学习算法和数据结构教程的完整列表。 85多个章节可供学习。

 

该网站上可用的教程列表:

C编程20+章C ++编程80+章
100多个编码问题数据结构和算法85+章
系统设计20+章Shell脚本编写12章
4g LTE 60+章节最常见的编码问题
5G NR 50+章Linux系统编程20+章
分享
电子邮件
鸣叫
领英
Reddit
绊倒
Pinterest的
上一篇文章
下一篇

关于作者

前开发者教程

每天我们都会讨论竞争性编程问题,请加入我们的网站:   电报频道

ProDeveloperTutorial.com

教程和编程解决方案
版权© 2020 ProDeveloperTutorial.com
从以下课程获得热门课程: 教育性的

  • <pre id="TkTiuc5" class="TUKnF5R"><acronym id="g2qeG1N" class="g4Ky7SI"><span id="o69UKgj"></span></acronym></pre>

    <cite class="Hcr7QG5"><embed class="AmxNPY6"></embed></cite>




          <caption id="YKDX0MF" class="YNoyfOv"><tfoot id="shdlRJ3"></tfoot></caption>



            <span id="jCyQ7pY"></span>

            <aside id="dScqnlb"><datalist class="kHIvof4"><strong class="Wcfr3Yp"></strong></datalist></aside>