算法导论-分治法-合并排序的Python&C++实现

来源:互联网 发布:最优化高级计算方法 编辑:程序博客网 时间:2024/06/05 06:55

分治法的精髓:

--将问题分解为规模更小的子问题;

--将这些规模更小的子问题逐个击破;

--将已解决的子问题合并,最终得出“母”问题的解;

 

分治模式每一层递归的三个步骤:

分解(Divide):将原问题分解成一系列子问题;

解决(Conquer):递归的解各个子问题。若子问题足够小,直接求解;

合并(Combine):将子问题的结果合并成原问题的解。

 


算法C++实现

#include#include//#includeusing namespace std;void Merge(int *A, int p, int q, int r) //合并函数{int n1 = q - p + 1;  // A[p..q]长度int n2 = r - q;   // A[q+1..r]长度int *L = new int[n1 + 1];  //用动态数组存储左边的数int *R = new int[n2 + 1];  //用动态数组存储右边的数for (int i = 1; i <= n1; i++) //把A数组左边的数放入L[]数组{L[i] = A[p + i - 1];}for (int j = 1; j <= n2; j++) //把A数组右边的数放入R[]数组{R[j] = A[q + j];}L[n1 + 1] = R[n2 + 1] = INT_MAX; //定义无穷大int i = 1, j = 1;for (int k = p; k <= r; k++) //小的放左边,大的放右边{if (L[i] <= R[j]){A[k] = L[i];i = i + 1;}else{A[k] = R[j];j = j + 1;}}}void MergeSort(int A[], int p, int r)  //归并排序{if (p < r)  // p:第0个数r:第n-1个数。数组至少两个数据{int q;q = (r + p) / 2;MergeSort(A, p, q); //第0个到第 (r + p) / 2 ,即拆分左半部分 MergeSort(A, q + 1, r);//第(r + p) / 2个到第 r ,即拆分右半部分 Merge(A, p, q, r);  //调用合并函数,从第0个到第n-1个排好 }}int main() {int n;cout << "输入产生的数组个数:";cin >> n;cout << endl;int *A = new int[n];cout << "产生的随机数组为:";srand((unsigned)time(0));for (int i = 0; i < n; i++) {A[i] = (rand() % (100 - 0 + 1)) + 0;cout << A[i] << "  ";}cout << endl;MergeSort(A, 0, n - 1);cout << "排序后的数组为:";for (int j = 0; j

算法Python实现:

def merge(A,p,q,r):  #合并函数    L = A[p : q+1]  #把A[p],...,A[q]依次复制给左子数组L    R = A[q+1 : r+1] #把A[q+1],...,A[r]依次复制给右子数组R    i = j = 0    k = p    while i < len(L) and j < len(R): #将L,R中的记录由小到大的并入A中        if L[i] <= R[j]:            A[k] = L[i]            i += 1        else:            A[k] = R[j]            j += 1        k += 1    while i < len(L): #将L中剩余记录并入A中        A[k] = L[i]   #C++中可以写成A[k++] = L[i++]        i += 1        k += 1    while j < len(R): #将R中剩余记录并入A中        A[k] = R[j]        j += 1        k += 1#Merge Sort , T = O(nlgn)def MergeSort(A,p,r):    if p < r:        q = (p+r) >> 1        MergeSort(A,p,q)        MergeSort(A,q+1,r)        merge(A,p,q,r)def sort(A):    MergeSort(A,0,len(A)-1)    A=[5,7,4,8,11,9,1,2]print('排序前'+str(A))sort(A)print('排序后'+str(A))


简化假定问题的规模是2的幂,这时每个分解步骤将产生规模正好为n/2的两个子序列。这个假设将不会影响结果的增长量级。

当有n>1个元素时,设运行时间为Tn),我们分解运行时间为:


分解:分解步骤仅仅计算数组的中间位置,需要常量时间,时间复杂度为Θ(1);

解决:递归的求解两个规模均为n/2的子问题,将贡献2T(n/2)的运行时间;

合并:之前的分析可知在一个具有n个元素的子数组过程上MERGE需要Θ(n)的时间。

 

由此可得出归并排序最坏情况的运行时间为

n=1时,T(n) = Θ(1)

n>1时,T(n)=2T(n/2)+Θ(n)


经典问题:

二分搜索

大整数乘法

Strassen矩阵乘法

棋盘覆盖

合并排序

快速排序

线性时间选择

最接近点对问题

循环赛日程表

汉诺塔

 

参考文献:

https://baike.baidu.com/item/%E5%88%86%E6%B2%BB%E6%B3%95/2407337?fr=aladdin百科

http://www.cnblogs.com/Amrirey/p/5440788.html编码

http://blog.csdn.net/l597692583/article/details/51131694Python

http://www.cnblogs.com/hhh5460/p/6851013.html经典实现

《算法导论第二版》





















原创粉丝点击