归并排序
时间算法度: Θ ( n l g n ) Θ\left(nlgn\right) Θ(nlgn)
该算法主旨:
归并排序算法完全遵照分治模式得三个步骤:
- 分解:分解待排序得 n n n个元素的序列,使其成为各具 n / 2 n/2 n/2个元素的两个子序列。
- 解决:使用归并排序递归地排序两个子序列。
- 合并:合并两个已排序的子序列以产生已排序的答案。
当待排序的序列长度为 1 1 1时,递归"开始回升",因为长度为 1 1 1的序列都已排好序(或者说时不需要排序)
伪代码:
/* ——————————————————————————————————————————————————
* 首先,我们需要一个合并两个序列的函数。
* 它将按照顺序合并两个子序列中的元素。
*
* 这里我们假设这两个需要合并的序列一定是已经排好序的。
* —————————————————————————————————————————————————— */
MERGE(A, front, middle, back)
1 Number_1 = middle - front + 1
2 Number_2 = back - middle
3 声明一个动态数组B,分配内存数量为Number_1
4 声明一个动态数组C,分配内存数量为Number_2
5 for i = 1 to Number_1
6 B[i] = A[i + Front - 1]
7 for i = 1 to Number_2
8 C[i] = A[middle + i]
9 i = 1
10 j = 1
11 for k = front to back
12 if j > Number_2 or i <= Number_1 and B[i] < C[j]
13 A[k] = B[i]
14 i = i + 1
15 else
16 A[k] = C[j]
17 j = j + 1
/* ——————————————————————————————————————————————————
* 我们按照分治法来递归分解序列
* —————————————————————————————————————————————————— */
MERGE-SORT(A, front, back)
1 if back - front == 0
2 return
3 MERGE-SORT(A, front, (back + front) / 2)
4 MERGE-SORT(A, (back + front) / 2 + 1, back)
5 MERGE(A, front, (back + front) / 2, back)
C++代码:
void MERGE(int* A, int front, int middle, int back)
{
int Number_1 = middle - front + 1;
int Number_2 = back - middle;
int* B = new int[Number_1];
int* C = new int[Number_2];
for (int i = 0; i < Number_1; i++)
B[i] = A[front + i];
for (int i = 0; i < Number_2; i++)
C[i] = A[middle + i + 1];
for (int i = 0, j = 0, k = front; k <= back; k++)
{
if (j >= Number_2 || (i < Number_1 && B[i] < C[j]))
{
A[k] = B[i];
i++;
}
else
{
A[k] = C[j];
j++;
}
}
delete[] B, C;
}
void MERGE_SORT(int* A, int front, int back)
{
if (back - front == 0)
return;
MERGE_SORT(A, front, (back + front) / 2);
MERGE_SORT(A, (back + front) / 2 + 1, back);
MERGE(A, front, (back + front) / 2, back);
}
测试代码:
#include <iostream>
constexpr std::size_t N = 10;
// 声明合并函数
void MERGE(int* A, int front, int middle, int back);
// 声明归并算法函数
void MERGE_SORT(int* A, int front, int back);
int main(void)
{
int A[N]{ 3, 2, 5, 3, 7, 1, 8, 0, 9, 4 };
MERGE_SORT(A, 0, N - 1);
for (int a : A)
std::cout << a << " ";
std::cout << std::endl;
return 0;
}
// 定义合并函数
void MERGE(int* A, int front, int middle, int back)
{
int Number_1 = middle - front + 1;
int Number_2 = back - middle;
int* B = new int[Number_1];
int* C = new int[Number_2];
for (int i = 0; i < Number_1; i++)
B[i] = A[front + i];
for (int i = 0; i < Number_2; i++)
C[i] = A[middle + i + 1];
for (int i = 0, j = 0, k = front; k <= back; k++)
{
if (j >= Number_2 || (i < Number_1 && B[i] < C[j]))
{
A[k] = B[i];
i++;
}
else
{
A[k] = C[j];
j++;
}
}
delete[] B, C;
}
// 定义归并算法函数
void MERGE_SORT(int* A, int front, int back)
{
if (back - front == 0)
return;
MERGE_SORT(A, front, (back + front) / 2);
MERGE_SORT(A, (back + front) / 2 + 1, back);
MERGE(A, front, (back + front) / 2, back);
}
/* —————————————————————————————————————————————————————
* 输出结果:
* 0 1 2 3 3 4 5 7 8 9
* —————————————————————————————————————————————————————— */