Merge sort algorithm C++ implementation (super detailed analysis!!!)

Table of contents

I. Introduction

(1) Divide and conquer algorithm

(2) Divide and conquer algorithm problem-solving method

    1. Decomposition:

    2. Governance:

    3. Merge

2. Merge sort

1. Problem analysis

2. Algorithm design

    (1) Decomposition:

    (2) Governance:

    (3) Merge:

3. Algorithm analysis

3. AC code

 Fourth, mutual encouragement


I. Introduction

(1) Divide and conquer algorithm

    Merge sort is actually a divide-and-conquer algorithm, so before understanding merge sort, let's take a look at what a divide-and-conquer algorithm is. In algorithm design, we introduce a divide-and-conquer strategy, called divide-and-conquer algorithm, whose essence is to decompose a large-scale problem into several smaller-scale identical sub-problems, and divide and conquer.

(2) Divide and conquer algorithm problem-solving method

    1. Decomposition:

    Decompose the problem to be solved into several smaller, independent sub-problems with the same form as the original problem.

    2. Governance:

    Solve each subproblem. Since each sub-problem has the same form as the original problem, but the scale is smaller, and when the sub-problems are divided into small enough, they can be solved in a simple way.

    3. Merge

    According to the requirements of the original problem, the solutions of the sub-problems are combined layer by layer to form the solution of the original problem.

2. Merge sort

1. Problem analysis

   Merge sort is a relatively stable sorting method. Its basic idea is to decompose the elements to be sorted into two subsequences of approximately equal size. If it is not easy to decompose, continue to decompose the obtained subsequence until the number of elements contained in the subsequence is 1. Because the sequence of individual elements is itself ordered, it can be merged at this time to obtain a complete ordered sequence.

2. Algorithm design

    (1) Decomposition:

    Divide the elements to be sorted into two subsequences of roughly the same size.

    (2) Governance:

    Merge and sort two subsequences.

    (3) Merge:

    Merge the sorted ordered subsequences to obtain the final ordered sequence.

3. Algorithm analysis

    First of all, we first give an unordered sequence (42, 15, 20, 6, 8, 38, 50, 12), and we perform a merge sort sequence, as shown in the flow chart below:

 Step 1: First divide the elements to be sorted into two sequences of roughly the same size.

Step 2: Divide the subsequence into two subsequences of approximately the same size.

Step 3: Go on like this until it is decomposed into one element, at this time the subsequences containing one element are all in order.

Step 4: Perform a merge operation to merge two ordered subsequences into an ordered sequence, and so on until all elements are merged into an ordered sequence.

 For example, below I will illustrate with the sequence (4, 9, 15, 24, 30, 2, 6, 18, 20).

(1) Initialization: i = low, j = mid+1, mid = (low+hight)/2, apply for an auxiliary array b

int* b = new int[hight - low + 1];  //用 new 申请一个辅助函数
	int i = low, j = mid + 1, k = 0;    // k为 b 数组的小标

 (2) Now compare a [i] and b[j], put the smaller element in the b array, and move the corresponding pointer backward until i > mid or j > hight.

while (i <= mid && j <= hight)  
 {
	if (a[i] <= a[j])
	{
		b[k++] = a[i++];  //按从小到大存放在 b 数组里面
	}
	else
	{
		b[k++] = a[j++];
	}
  }

Perform the first comparison a[i]=4 and a[j]=2, put the smaller element 2 into the array b, j++,k++, as shown in the figure below:

 Perform the second comparison a[i]=4 and a[j]=6, put the smaller element 4 into the array b, i++,k++, as shown in the figure below:

 Perform the third comparison a[i]=9 and a[j]=6, put the smaller element 6 into the array b, j++,k++, as shown in the figure below:

 Perform the fourth comparison a[i]=9 and a[j]=18, put the smaller element 9 into the array b, i++,k++, as shown in the figure below:

 Perform the fifth comparison a[i]=15 and a[j]=18, put the smaller element 15 into the array b, i++,k++, as shown in the figure below:

  Perform the sixth comparison a[i]=24 and a[j]=18, put the smaller element 18 into the array b, j++,k++, as shown in the figure below:

 Perform the seventh comparison a[i]=24 and a[j]=20, put the smaller element 20 into the array b, j++,k++, as shown in the figure below:

 At this point, j>hight, the while loop ends, but the remaining elements (i<mid) in the a array can be directly put into the b array. As shown below:

while (i <= mid)  // j 序列结束,将剩余的 i 序列补充在 b 数组中 
	{
		b[k++] = a[i++];
	}
	while (j <= hight)// i 序列结束,将剩余的 j 序列补充在 b 数组中 
	{
		b[k++] = a[j++];
	}

Now assign the elements of the b array to the a array, and then destroy the b array.

for (int i = low; i <= hight; i++)  //将 b 数组的值传递给数组 a
	{
		a[i] = b[k++];
	}
	delete[]b;     // 辅助数组用完后,将其的空间进行释放(销毁)

(3) Merge and sort in the form of recursion

void mergesort(int* a, int low, int hight) //归并排序
{
	if (low < hight)
	{
		int mid = (low + hight) / 2;
		mergesort(a, low, mid);          //对 a[low,mid]进行排序
		mergesort(a, mid + 1, hight);    //对 a[mid+1,hight]进行排序
		merge(a, low, mid, hight);       //进行合并操作
	}
}

3. AC code

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
void merge(int* a, int low, int mid, int hight)  //合并函数
{
	int* b = new int[hight - low + 1];  //用 new 申请一个辅助函数
	int i = low, j = mid + 1, k = 0;    // k为 b 数组的小标
	while (i <= mid && j <= hight)  
	{
		if (a[i] <= a[j])
		{
			b[k++] = a[i++];  //按从小到大存放在 b 数组里面
		}
		else
		{
			b[k++] = a[j++];
		}
	}
	while (i <= mid)  // j 序列结束,将剩余的 i 序列补充在 b 数组中 
	{
		b[k++] = a[i++];
	}
	while (j <= hight)// i 序列结束,将剩余的 j 序列补充在 b 数组中 
	{
		b[k++] = a[j++];
	}
	k = 0;  //从小标为 0 开始传送
	for (int i = low; i <= hight; i++)  //将 b 数组的值传递给数组 a
	{
		a[i] = b[k++];
	}
	delete[]b;     // 辅助数组用完后,将其的空间进行释放(销毁)
}
void mergesort(int* a, int low, int hight) //归并排序
{
	if (low < hight)
	{
		int mid = (low + hight) / 2;
		mergesort(a, low, mid);          //对 a[low,mid]进行排序
		mergesort(a, mid + 1, hight);    //对 a[mid+1,hight]进行排序
		merge(a, low, mid, hight);       //进行合并操作
	}
}
int main()
{
	int n, a[100];
	cout << "请输入数列中的元素个数 n 为:" << endl;
	cin >> n;
	cout << "请依次输入数列中的元素:" << endl;
	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
	}
	mergesort(a, 0, n-1);
	cout << "归并排序结果" << endl;
	for (int i = 0; i < n; i++)
	{
		cout << a[i] << " ";
	}
	cout << endl;
	return 0;
}

 Fourth, mutual encouragement

    The following is my understanding of the divide-and-conquer algorithm: merge sort. If there are friends who do not understand or find problems, please tell them in the comment area. At the same time, I will continue to update my understanding of the divide-and-conquer algorithm. Please continue to pay attention to me. ! ! ! ! ! ! ! !

 

Guess you like

Origin blog.csdn.net/weixin_45031801/article/details/127034720