当前位置:网站首页>C语言学习-20-归并排序
C语言学习-20-归并排序
2022-06-28 15:04:00 【阳光九叶草LXGZXJ】
一、个人理解
实现归并排序,分两步:
1、合并两个有序数组。
2、分治法将无序数组拆分成一个个小的有序数组,再进行排序。
二、实现思路
(1)合并两个有序数组
给两个有序数组,两个数组a,b分别从第一位开始比较,这里以升序为例,可以分为三种情况:
1、a的元素大于b的元素,将b的元素放入新的数组中,且b的索引位进一,a的索引位不变。
2、a的元素小于b的元素,将a的元素放入新的数组中,且a的索引位进一,b的索引位不变。
3、a的元素等于b的元素,将a,b的元素放入新的数组中,且a,b的索引位都进一。
我们还需要思索一下,如果两个数组的长度不相等,是不是就会出现一个数组遍历完了,另一个还没有遍历完,所以在上面的比较结束后,也就是说有一个数组已遍历完,我们只需要另一个数组的剩余元素全部复制到新数组中就OK啦!!!
(2)分治法
这里是为了让归并排序适用于无序数组,我们可以把一个数组从中间一分为二,看左边的数组和右边的数组是否有序,如果是无序的就继续拆分,当两个数组中分别都只有一个元素时,一定是有序的,是不是又想到了递归的思想,对头,递归分为两步,结束标志:数组中只有一个元素时,退出。规则逻辑:数组从中间拆分,将左边的数组和右边的数组分别排序,再将两个数组合并,是不是有一些想法了,希望对大家有帮助!!!
三、实现函数介绍
(1)MergeUnOrderedArray函数:
适用范围:
适用于无序和有序数组。
参数介绍:
参数Array:整型数组。
参数L:数组的起始位置索引号。
参数R:数组的结束位置索引号。
(2)MergeArray函数:
适用范围:
数组例如:{4,5,6,1,2,3},
要求数组中是以一个分割点切割后是两个有序的数组。
参数介绍:
参数Array:整型数组。
参数TopPointIndex:数组的起始位置索引号。
参数BreakPointIndex:分割点的索引号,以上面的数组为例,数值1的索引位3为传入参数。
参数EndPointIndex:某后一个元素的索引位,以上面的数组为例,数值3的索引位5为传入参数。
(3)Merge2SortArray函数:
适用范围:
要求传入两个有序数组,都正序或都倒序。
数组1例如:{4,5,6}
数组2例如:{1,2,3}
参数介绍:
参数Array1:整型数组。
参数ArraySize1:Array1长度。
参数Array2:整型数组。
参数ArraySize2:Array2长度。
四、代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* 实现归并排序,分两步: 1、合并两个有序数组。 2、分治法将无序数组拆分成一个个小的有序数组,再进行排序。 */
void PrintArray(int Array[], int ArraySize);
void MergeArray(int Array[], int TopPointIndex, int BreakPointIndex, int EndPointIndex);
int* Merge2SortArray(int Array1[], int ArraySize1, int Array2[], int ArraySize2);
void MergeUnOrderedArray(int Array[], int L, int R);
int main()
{
//测试Merge2SortArray函数
printf("+++++++++++++++++++++++++++++++\n");
printf("测试Merge2SortArray函数:\n");
int Array1[] = {
1,2,3,4,5,6 };
int Array2[] = {
1,7,8,9 };
int ArraySize1 = sizeof(Array1) / sizeof(int);
int ArraySize2 = sizeof(Array2) / sizeof(int);
PrintArray(Merge2SortArray(Array1, ArraySize1, Array2, ArraySize2), ArraySize1 + ArraySize2);
//测试MergeArray函数
printf("+++++++++++++++++++++++++++++++\n");
printf("测试MergeArray函数:\n");
int ArraySize = ArraySize1 + ArraySize2;
int* Array = (int*)malloc(sizeof(int) * ArraySize);
int i = 0;
int j = 0;
int x = 0;
while (i < ArraySize1)
{
Array[x] = Array1[i];
x++;
i++;
}
while (j < ArraySize2)
{
Array[x] = Array2[j];
x++;
j++;
}
//int Array[] = { 6,7,8,9,1,2,3,4,5,6 };
//PrintArray(Array, ArraySize);
MergeArray(Array, 0, ArraySize1, ArraySize - 1);
PrintArray(Array, ArraySize);
free(Array);
//测试MergeUnOrderedArray函数
printf("+++++++++++++++++++++++++++++++\n");
printf("测试MergeUnOrderedArray函数:\n");
int TestArray[] = {
2,3,5,1,4,5,6,7,9,8 };
int TestArraySize = sizeof(TestArray) / sizeof(int);
//printf("%d\n",TestArraySize);
PrintArray(TestArray, TestArraySize);
MergeUnOrderedArray(TestArray, 0, TestArraySize - 1);
PrintArray(TestArray, TestArraySize);
return 0;
}
/* MergeUnOrderedArray函数: 适用范围: 适用于无序和有序数组。 参数: 参数Array:整型数组。 参数L:数组的起始位置索引号。 参数R:数组的结束位置索引号。 */
void MergeUnOrderedArray(int Array[], int L, int R)
{
if (L == R)
{
return;
}
else
{
int M = (L + R) / 2;
MergeUnOrderedArray(Array, L, M);
MergeUnOrderedArray(Array, M + 1, R);
MergeArray(Array, L, M + 1, R);
}
}
/* MergeArray函数: 适用范围: 数组例如:{4,5,6,1,2,3}, 要求数组中是以一个分割点切割后是两个有序的数组。 参数: 参数Array:整型数组。 参数TopPointIndex:数组的起始位置索引号。 参数BreakPointIndex:分割点的索引号,以上面的数组为例,数值1的索引位3为传入参数。 参数EndPointIndex:某后一个元素的索引位,以上面的数组为例,数值3的索引位5为传入参数。 */
void MergeArray(int Array[], int TopPointIndex, int BreakPointIndex, int EndPointIndex)
{
if (Array == NULL)
{
return;
}
int ArraySize1 = BreakPointIndex - TopPointIndex;
int ArraySize2 = EndPointIndex - BreakPointIndex + 1;
int* Array1 = (int*)malloc(sizeof(int) * ArraySize1);
int* Array2 = (int*)malloc(sizeof(int) * ArraySize2);
int i, j;
int x;
//初始化两个数组
for (x = TopPointIndex, i = 0; i < ArraySize1; i++, x++)
{
Array1[i] = Array[x];
}
for (j = 0; j < ArraySize2; j++, x++)
{
Array2[j] = Array[x];
}
//PrintArray(Array1, ArraySize1);
//PrintArray(Array2, ArraySize2);
memcpy(Array + TopPointIndex, Merge2SortArray(Array1, ArraySize1, Array2, ArraySize2), sizeof(int) * (ArraySize1 + ArraySize2));
//i指向ResArray
//j指向Array
//int* ResArray = Merge2SortArray(Array1, ArraySize1, Array2, ArraySize2);
//for ( i = 0,j = TopPointIndex; i < (ArraySize1 + ArraySize2); i++,j++)
//{
// Array[j] = ResArray[i];
//}
free(Array1);
free(Array2);
}
/* Merge2SortArray函数: 适用范围: 要求传入两个有序数组,都正序或都倒序。 数组1例如:{4,5,6} 数组2例如:{1,2,3} 参数: 参数Array1:整型数组。 参数ArraySize1:Array1长度。 参数Array2:整型数组。 参数ArraySize2:Array2长度。 */
int* Merge2SortArray(int Array1[], int ArraySize1, int Array2[], int ArraySize2)
{
//printf("###########################\n");
//printf("Array1 : ");
//PrintArray(Array1, ArraySize1);
//printf("Array2 : ");
//PrintArray(Array2, ArraySize2);
if (Array1 == NULL || Array2 == NULL)
{
return NULL;
}
int* ResArray = (int*)malloc(sizeof(int) * (ArraySize1 + ArraySize2));
int i = 0;
int j = 0;
int x = 0;
//i指向Array1的起始位置。
//j指向Array2的起始位置。
//x指向ResArray的起始位置。
while ((i < ArraySize1) && (j < ArraySize2))
{
if (Array1[i] < Array2[j])
{
ResArray[x] = Array1[i];
x++;
i++;
}
else if (Array1[i] > Array2[j])
{
ResArray[x] = Array2[j];
x++;
j++;
}
else //数组元素相等
{
ResArray[x] = Array2[j];
x++;
ResArray[x] = Array1[i];
x++;
j++;
i++;
}
}
//如果数组的元素没有全部循环完,跳入此循环。
while (i < ArraySize1)
{
ResArray[x] = Array1[i];
x++;
i++;
}
while (j < ArraySize2)
{
ResArray[x] = Array2[j];
x++;
j++;
}
//printf("ResArray : ");
//PrintArray(ResArray, ArraySize2 + ArraySize1);
return ResArray;
}
void PrintArray(int Array[], int ArraySize)
{
int i;
for (i = 0; i < ArraySize; i++)
{
printf("%d ", Array[i]);
}
printf("\n");
}
五、测试结果
C:\Users\czg>C:\Users\czg\source\repos\x64\Debug\C_TEST.exe
+++++++++++++++++++++++++++++++
测试Merge2SortArray函数:
1 1 2 3 4 5 6 7 8 9
+++++++++++++++++++++++++++++++
测试MergeArray函数:
1 1 2 3 4 5 6 7 8 9
+++++++++++++++++++++++++++++++
测试MergeUnOrderedArray函数:
2 3 5 1 4 5 6 7 9 8
1 2 3 4 5 5 6 7 8 9

边栏推荐
- 猫狗图像数据集上的深度学习模型性能对比
- Q-Tester 3.2:适用于开发、生产和售后的诊断测试软件
- The boss told me three times: low key, low key, low key
- Case driven: a detailed guide from getting started to mastering shell programming
- Functools: high order functions and operations on callable objects (continuous updating ing...)
- What is the renewal fee for PMP certificate?
- Q-tester 3.2: applicable to development, production and after-sales diagnostic test software
- 法兰克福地区目前支持sql了吗?
- 鸟类飞行状态下穿戴式神经信号与行为数据检测记录系统的技术难点总结
- After nearly 20 years of operation, the Mars probe software based on win 98 has been upgraded for the first time
猜你喜欢

腾讯再遭大股东Prosus减持:后者还从京东套现37亿美元

张同学还没学会当主播

Facebook! Adaptive gradient defeats manual parameter adjustment

当下不做元宇宙,就像20年前没买房!

Ding! Techo day Tencent technology open day arrived as scheduled!

币圈大地震:去年赚100万,今年亏500万

美因基因港交所上市:市值43亿港元 IPO被市场忽略

猫狗图像数据集上的深度学习模型性能对比

After QQ was stolen, a large number of users "died"

名创优品通过上市聆讯:寻求双重主要上市 年营收91亿
随机推荐
2022年最新PyCharm激活破解码永久_详细安装教程(适用多版本)
R语言ggplot2可视化:使用patchwork包(直接使用加号+)将一个ggplot2可视化结果和一个plot函数可视化结果横向组合起来形成最终结果图、将两个可视的组合结果对齐
Classmate Zhang hasn't learned to be an anchor yet
[spatial & single cellomics] phase 1: Study on PDAC tumor microenvironment by single cell binding spatial transcriptome
Calculator (force buckle)
R语言ggplot2可视化:使用patchwork包将两个ggplot2可视化结果纵向堆叠起来(stacking)形成组合图、一个可视化结果堆叠在另外一个可视化结果上
[C language] how to implement plural types
第四大运营商,难成「鲶鱼」
不要使用短路逻辑编写 stl sorter 多条件比较
老板嘱咐了三遍:低调、低调、低调
vscode编写markdown文件并生成pdf
5000倍回报,南非报业投资腾讯赚了一个省
利用MySqlBulkLoader实现批量插入数据的示例详解
3. caller service call - dapr
Leetcode (167) -- sum of two numbers II - input ordered array
sent2vec教程
324. 摆动排序 II : 不简单的构造题
vector详解+题目
股票开户优惠链接,我如何才能得到?手机开户是安全么?
halcon 基础总结(一)裁切图片并旋转图像