参考博客:白话经典算法系列之五 归并排序的实现
参考视频:归并排序
/***********************
* 功能:归并排序
* 作者:khq
* 时间:2020.4.22
************************/
#include<stdio.h>
//方法声明
void merge(int a[],int,int,int);
void mergeSort(int a[],int,int);
void printArr(int a[],int);
int main(void){
int arr[12] = {5,12,9,3,-10,6,-19,15,2,18,-1,-7};
printf("排序前的数组元素:\n");
printArr(arr,12);
mergeSort(arr,0,12);
printf("归并排序后的数组元素:\n");
printArr(arr,12);
return 0;
}
//递归和合并
void mergeSort(int a[],int L,int R){ //L和R都表示下标
if(L == R)
return;
else{
//先递归,不断将序列进行划分
int M = (L+R+1)/2;
mergeSort(a,L,M-1);
mergeSort(a,M,R);
//再合并排序
merge(a,L,M,R);
}
}
//先把一个序列分成两个字序列,然后再合并成一个序列
/*
* L:表示左序列的起点
* M:表示右序列的起点
* R:表示右序列的终点
*/
void merge(int a[],int L,int M,int R){
int LEFT_SIZE = M-L; //左序列的大小
int RIGHT_SIZE = R-M+1; //右序列的大小
int *Left = new int[LEFT_SIZE];
int *Right = new int[RIGHT_SIZE];
//将序列中的元素赋值给左序列
for(int m=0;m<LEFT_SIZE;m++){
Left[m] = a[L+m];
}
//将序列中的元素赋值给右序列
for(int n=0;n<RIGHT_SIZE;n++){
Right[n] = a[M+n];
}
//将左右两个序列的元素一次比较,较小者填入到原序列中
int i=0;
int j=0;
int k=L;
/*
* i:表示左序列的起点
* j:表示右序列的起点
* L:表示原序列的起点
*/
while(i<LEFT_SIZE && j<RIGHT_SIZE){
if(Left[i]<Right[j]){
a[k++] = Left[i++];
}else{
a[k++] = Right[j++];
}
}
//如果某一个子序列访问完了,就将另一个子序列中的元素直接写到原序列中
while(i<LEFT_SIZE){
a[k++] = Left[i++];
}
while(j<RIGHT_SIZE){
a[k++] = Right[j++];
}
delete[] Left;
delete[] Right;
}
void printArr(int a[],int n){
for(int i=0;i<n;i++){
printf("%d ",a[i]);
}
printf("\n");
}
结果显示:
问题总结:VC6.0在定义数组的时候要初始化大小,一般不能传入参数,为解决这一问题,需要使用int *p=new int[ArraySize];
,然后再使用delete[] p
,将用完以后的p删除掉。