将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破, 分而治之
divide-and-conquer(P)
{
if ( | P | <= n0) adhoc(P); //解决小规模的问题
divide P into smaller subinstances P1,P2,...,Pk;//分解问题
for (i=1,i<=k,i++)
yi=divide-and-conquer(Pi); //递归的解各子问题
return merge(y1,...,yk); //将各子问题的解合并为原问题的解
}
将待排序元素分成大小大致相同的2个子集合,分别对2个子集合进行排序,最终将排好序的子集合合并成为所要求的排好序的集合。
public static void mergeSort(Comparable a[], int left, int right)
{
if (left<right)
{//至少有2个元素
int i=(left+right)/2; //取中点
mergeSort(a, left, i);
mergeSort(a, i+1, right);
merge(a, b, left, i, right); //合并到数组b
copy(a, b, left, right); //复制回数组a
}
}
T(n)=Θ(nlogn) 渐进意义下的最优算法
给已排好序的n个元素中寻找特定元素x
A和B的乘积矩阵C中的元素C[i,j]定义为
传统方法:O(n3)【计算时,三个for循环】
为了降低时间复杂度,必须减少乘法的次数
请设计一个有效的算法,可以进行两个n位大整数的乘法运算
为了降低时间复杂度,必须减少乘法的次数 XY = ac 2n + (ad+bc) 2n/2 + bd
1,查找数组a[n]中的最大元素,至少需要多少次比较? 2,查找数组a[n]中的最大和最小元素,用最少的元素比较次数。 3,查找数组a[n]中的第k小的元素(k相对于n比较小); 4,查找数组a[n]中的中位数(序号为n/2);
设计算法,找出数组a[n]的中位数。 设计算法,找出数组a[n]中序为k的数。 设计算法,输出数组a[n]中所有序为奇数的数。 设计算法,计算序列a[n]中的逆序数
4.要拼一个1×7长方形,可用的纸片有以下规格:1×1, 1×2, 1×3,共有______种拼法? == 解:f(n) = f(n-1)+f(n-2)+f(n-3) 1,2,4,7,13,24,44==
如果再合并排序算法的分割步中,将数组a[0:n-1]划分为⌊√n⌋个子数组,每个子数组中有O(√n)个元素。然后递归地对子数组进行排序,最后将所得到的个排好序的子数组合并成所要求的排好序的数组。以上排序算法的平均时间复杂度是多少? Θ(√n*log√n)
low和high是索引
void QuickSort ( SqList &L, int low, int high ){
//在序列lowhigh 中递归地进行快速排序
if ( low < high) {
int p= Partition (L, low, high); //p作为中间值索引进行划分
QuickSort ( L, low, p-1 ); //对左序列递归处理
QuickSort ( L, p+1, high); //对右序列递归处理
}
}
int Partition ( SqList &L, int low, int high ) {
pivotkey = L.r[low].key; //基准对象关键字【找第一个数字】
while(low<high){
👇这个while先把所有小于基准的放左边
while(low<high && L.r[high].key >= pivotkey) high--;//如果大于基准值则high--,换下一个比较
L.r[low] L.r[high]; //小于基准对象的移到区间的左侧
👇这个while再把所有大于基准的放右边
while(low<high&& L.r[low].key <= pivotkey) low++;
L.r[high] L.r[low] ; //大于基准对象的移到区间的右侧
}
return low;
}
Partition函数作用:通过基准将数组分成两部分,小于基准的在基准左边,大于则在右边。Partition时间复杂度Θ(n)
平均时间复杂度Θ(n*logn) 最坏时间复杂度O(n2) 平均空间复杂度O(logn),logn次都需要一个空间存基准
可基于快速排序中的划分算法Partition (int a[], int low, int high)完成查找数组a[low:high]中第k小的元素的算法,其中,1≤k≤high-low+1。
int Search ( int a[], int low, int high, int k ) {
//在a[low:high]中查找第k小的元素
if (low==high) return a[low];
int p = Partition(a, low, high);
int t = p-low+1;
if(k<=t) return Search(a, low, p, k );
else return Search(a, p+1, high, k-p );
平均时间复杂度情况下,是Θ(n) 最坏时间复杂度O(n2)
2-8, 2-9, 2-15, 2-16, 2-28