C语言归并排序递归与非递归模板

这个我是拿来理解和背诵的,选自于胡凡的《算法笔记》。归并排序是一种nlogn的时间复杂度算法,不断地利用空间倒腾去完成,一般也用在排序算法上。

递归版本

将array数组当前区间[left,right]进行归并排序
void mergeSort(int A[],int left,int right) {
    if(left<right) {
        int mid = (left+right)/2;
        mergeSort(A,left,mid);
        mergeSort(A,mid+1,right);
        merge(A,left,mid,mid+1,right);

    }

}
void merge(int A[],int L1,int R1,int L2,int R2){
    int i = L1,j = L2;//i指向A[L1],j指向A[l2]
    int temp[maxn],index = 0;//temp临时存放合并后的数组,index为其下标
    while(i<=R1&& j<=R2){
        if(A[i] <= A[j]){ //如果A[i] <= A[j]
            temp[index++] = A[i++]; //将A[i] 加入序列temp
        }else{ //如果A[i] > A[j]
            temp[index++] = A[j++]; //将A[j] 加入序列temp
        }
    }
    while(i<=R1) temp[index++] = A[i++];
    while(j<=R2) temp[index++] = A[j++];
    for(i=0;i<index;i++){
        A[L1+i] = temp[i];//将合并后的序列赋值回数组A

    }
}



int main()
{
    int A[5] ={3,2,1,5,0};
    mergeSort(A,sizeof(A)/sizeof(int));
    for(int i =0;i<5;i++)
        printf("%d ",A[i]);
    return 0;
}

非递归版本

void merge(int A[],int L1,int R1,int L2,int R2){
    int i = L1,j = L2;//i指向A[L1],j指向A[l2]
    int temp[maxn],index = 0;//temp临时存放合并后的数组,index为其下标
    while(i<=R1&& j<=R2){
        if(A[i] <= A[j]){ //如果A[i] <= A[j]
            temp[index++] = A[i++]; //将A[i] 加入序列temp
        }else{ //如果A[i] > A[j]
            temp[index++] = A[j++]; //将A[j] 加入序列temp
        }
    }
    while(i<=R1) temp[index++] = A[i++];
    while(j<=R2) temp[index++] = A[j++];
    for(i=0;i<index;i++){
        A[L1+i] = temp[i];//将合并后的序列赋值回数组A

    }
}


void mergeSort(int A[],int n){
    //step为组内元素个数,step/2为左子区间元素个数,注意等号可以不取
    for(int step =2;step/2<n;step*=2){
        //每step个元素一组,组内前step/2和后step/2个元素进行合并
        for(int i=0;i<=n;i+=step){
            int mid = i + step /2-1;
            if(mid+1<=n) {
                //左子区间为[i,mid],右子区间[mid+1,min(i+step-1),n];
                merge(A,i,mid,mid+1,min(i+step-1,n));
            }
        }
    }

}

下面给出题目中只要求给出归并排序每一趟结束时的序列,那么完全可以使用merge函数。

void mergeSort(int A[], int n){
    //step为组内元素个数,step/2为左子区间元素个数,注意等号可以不取
    for(int step = 2;step/2 <= n;step*=2){
        //每step一个元素一组,组内[i,min(i+step,n+1)]进行排序
        for(int i=0;i<=n;i+=step) {
            sort(A+i,A+min(i+step,n+1));
        }
    }
}

你可能感兴趣的:(考研C集,c语言,排序算法,算法)