归并排序 分治法 先分然后合并
网上很多都是 利用等大的数据空间 然后排序
即 时间复杂度 Onlog2n 空间复杂度 O(n)
我自己没事写了一个 大致思路相同
区别是 我采用 元素的移动 没有采用等大的 数据空间
大概是 时间复杂度 Onlog2n 空间复杂度 O(1)
大家可以研究研究 ,欢迎吐槽 哈哈
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/**
归并排序
Onlog2N O(1)
没有采用数组等大空间
author:lb
DATE:2019-08-09
*/
//打印数组
void printArr(int arr[],int len){
for(int i=0;i<len;i++){
printf("%i,",arr[i]);
}
printf("\n");
}
//声明
void mergeArr(int arr[],int start,int len);
//拆分 排序
void mergeSort(int arr[],int start,int len){
if(start <len){
int mid=(start+len)/2;
if((mid-start) >1){ //是否可分割
mergeSort(arr,start,mid);
}
if((len-mid) >1){ //是否可:分割
mergeSort(arr,mid,len);
}
mergeArr(arr,start,len);
}
}
//最小范围内排序
void mergeArr(int arr[],int start,int len){
int mid=(start+len) /2;
int index=start;
int s1=start,e1=mid,s2=mid,e2=len;
int temp1,temp2,s3,s4;
//temp1 始终指向前分区当前比较的元素
//temp2 互换位置用.
//s3 始终指向 前分区 下一个待比较的元素
//s4 始终指向 将被覆盖的元素 容身之地
temp1=arr[index];
s3=s4=mid; //默认 前分区被覆盖的元素 从后分区第一个元素开始保存
printf("开始排序--start=%i,len=%i,s1=%i,e1=%i,s2=%i,e2=%i\n",start,len,s1,e1,s2,e2);
while(s1 <e1 || s2 < e2){
//printf("头元素temp1=%i,s1=%i,s2=%i,s3=%i,s4=%i\n",temp1,s1,s2,s3,s4);
//printArr(arr,len);
if(s1==e1){
arr[index++]=arr[s2++];
}else if(s2==e2){
for(int i=s4;i>s3 && i<s2;i-- ){
arr[i]=arr[i-1];
}
arr[index]=temp1;
printArr(arr,len);
return;
}else{
if(temp1 > arr[s2]){
if(s1 < index){ //存在覆盖
temp2=arr[index];
if(index >=s3){ //后退
for(int i=s4;i>=s3 && i<s2;i-- ){
arr[i]=arr[i-1];
}
s3++;
s4++;
}
arr[index]=arr[s2];
if(index <mid){
arr[s4++]=temp2;
}
index++;
s2++;
}else{
arr[index++]=arr[s2++];
}
}else{
if(s1 <index){//存在覆盖
temp2=arr[index];
int back=1; // 如果后退了就不前进了
if(index >=s3){ //后退
printf("后退s3=%i,s4=%i\n",s3,s4);
for(int i=s4;i>=s3 && i<s2;i--){
arr[i]=arr[i-1];
}
s3++;
s4++;
printf("后退后s3=%i,s4=%i\n",s3,s4);
back=0;
}
arr[index]=temp1;
if(index < mid){
arr[s4++]=temp2;
}
temp1=arr[s3++];
if(back){ //前进
printf("前进s3=%i,s4=%i\n",s3,s4);
for(int i=s3;i<s4;i++ ){
arr[i-1]=arr[i];
}
s4--;
s3--;
printf("前进后s3=%i,s4=%i\n",s3,s4);
}
index++;
s1++;
}else{
arr[index++] =temp1;
temp1=arr[++s1];
}
}
}
printArr(arr,len);
printf("\n");
}
}
//测试
int main(){
//int arr[]={18,25,30,40,45,1,10,41,42,60};
//int arr[]={18,25,60,70,80,1,10,41,42,45};
//int arr[]={46,17, 39, 23, 28, 55, 18, 46,66,45,85,61,1,5,2,9,3,12,15,6,14,16,34,64,85,29,100,11,22,44,33};
//17,18,23,28,39,46,55,1,5,45,46,61,61,85,19,29,3,234,221,234,22
int arr[]={17,18,23,28,39,46,55,1,5,45,46,61,61,85,19,29,3,234,221,234,22};
int len=21;
printArr(arr,len);
printf("排序后------\n");
mergeSort(arr,0,len);
printArr(arr,len);
}
分享到:
相关推荐
归并排序是一种高效的排序算法,基于分治策略。在Java中实现归并排序,我们可以创建一个名为`MergeSort`的类来封装整个过程。归并排序的基本思想是将待排序的序列分成两个或更多的子序列,对每个子序列分别进行排序...
【归并排序】是一种高效的排序算法,其基本思想源于分治法(Divide and Conquer)。归并排序通过不断地将数组划分为较小的子序列,然后对这些子序列进行排序,最后将排序好的子序列合并成一个完整的有序序列。在这个...
### 归并排序算法实现详解 #### 一、引言 归并排序是一种经典的排序算法,采用分治法的思想,将待排序数组分为若干个子序列,这些子序列是已排序的,然后再按照一定的方式合并这些子序列得到最终排序后的数组。...
C#排序算法之归并排序 C#排序算法之归并排序是一种基于分治策略的排序算法,通过将数组分割成两个子数组,递归地对每个子数组进行排序,然后将两个有序的子数组合并成一个有序的数组。下面是对C#实现归并排序的详细...
本文实例为大家分享了C语言实现归并排序的具体代码,供大家参考,具体内容如下 归并排序的基本思想: 将两个及其以上的有序表合并为一张有序表,把待排序序列通过分治法分为若干个有序子序列,然后每两个子序列合并...
归并排序是一种高效的、稳定的排序算法,其核心思想是“分而治之”。在Python中实现归并排序,我们可以分为以下几个步骤来理解: 1. **分割**:首先,我们需要将原始数组不断地分成两半,直到每个子数组只剩下一个...
归并排序是一种高效的排序算法,基于分治策略。在C#中,归并排序可以通过递归、非递归以及自然归并三种方式实现。以下是这三种实现方法的详细解释: 1. **递归归并排序**: 递归归并排序是归并排序最直观的实现...
归并排序(Merge Sort)是一种基于分治策略的高效排序算法。它的基本思想是将待排序的序列分为两部分,分别对这两部分进行排序,然后将排好序的子序列合并成一个完整的有序序列。这一过程可以递归地进行,直到每个子...
**三路归并排序**是一种高效的排序算法,尤其在处理含有大量重复元素的序列时表现优秀。该算法基于归并排序的思想,但将其分为三个部分处理,而不是传统的两个部分。在本文中,我们将深入探讨三路归并排序的原理、...
归并排序是一种分治策略的排序算法,它的基本思想是将大问题分解成小问题来解决。在归并排序中,我们将一个大数组分成两个或更多个小数组,然后对每个小数组进行排序,最后将这些小数组合并成一个大的有序数组。这个...
归并排序是一种基于分治策略的高效排序算法,它的核心思想是将大问题分解成小问题,然后分别解决小问题,最后将小问题的结果合并,得到大问题的解。在这个过程中,归并排序将待排序的序列不断地分成两半,直到每个子...
归并排序是一种基于分治策略的高效排序算法,它的核心思想是将大问题分解成小问题,逐个解决,然后再将结果合并,最终得到整个问题的解决方案。在归并排序中,这一过程主要分为三个步骤:分解、求解和组合。 1. **...
归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"...
归并排序(Merge Sort)是一种经典的分治算法,它将一个数组分成两个子数组,分别对这两个子数组进行排序,然后再将两个已排序的子数组合并成一个完整的有序数组。压缩包文件代码是一个使用JavaScript实现归并排序的...
1,归并排序的概念 1.1,算法介绍 和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(n log n)的时间复杂度。代价是需要额外的内存空间。归并排序是建立在归并操作上的一...
归并排序(Merge Sort)是一种基于分治策略的高效排序算法。它的基本思想是将待排序的元素序列分成两个或更多的子序列,分别对每个子序列进行排序,然后将排好序的子序列合并成一个有序序列。这个过程可以递归进行,...
归并排序是一种基于分治思想的高效排序算法,它的主要特点是将大问题分解为小问题来解决。在Java中实现归并排序,我们可以分别实现递归版和非递归版,这两种方法各有其特点和适用场景。 ### 1. 分治策略 归并排序...
内部排序之归并排序的代码实现,代码风格简单 易于看懂
本文将详细介绍C++中实现的希尔排序、快速排序、堆排序和归并排序这四种经典排序算法。 希尔排序,由Donald Shell于1959年提出,是一种改进的插入排序。它的基本思想是通过设置一个增量序列,将待排序的元素按照...