1、二分查找
(1)、二分查找递归实现
#include<stdio.h>
#define NOT_FOUND -1;
int binSearch(int *a, int head, int tail, int key);
int binSearch(int *a, int head, int tail, int key){
int middle;
if(head <= tail){
middle = (head + tail)/2;
if(key == a[middle]){
return middle;
}
if(key < a[middle]){
return binSearch(a, head, middle-1, key);
}
if(key > a[middle]){
return binSearch(a, middle+1, tail, key);
}
}
return NOT_FOUND;
}
void main(void){
int a[] = {2, 3, 4, 6, 8, 10};
int count = sizeof(a)/sizeof(int);
int index;
int number;
printf("请输入要查找的数字: ");
scanf("%d", &number);
index = binSearch(a, 0, count-1, number);
printf("%d\n", index);
}(2)、结果截图
(3)、二分查找非递归实现
#include<stdio.h>
#define NOT_FOUND -1
int binSearch(int *a, int count, int key);
int binSearch(int *a, int count, int key){
int head = 0;
int tail = count-1;
int middle = (head+tail)/2;
while(head <= tail){ //有可能head和tail到达了同一个数字;
if(key < a[middle]){
tail = middle-1;
}else if(key > a[middle]){
head = middle+1;
}else{
return middle;
}
middle = (head+tail)/2;
}
return NOT_FOUND;
}
void main(void){
int a[] = {1, 3, 6, 8, 9, 10};
int count = sizeof(a)/sizeof(int);
int number;
int index;
printf("请输入要查找的数字:");
scanf("%d", &number);
index = binSearch(a, count, number);
printf("%d\n", index);
}(4)、结果截图
(5)、算法分析
时间复杂度为:O(logn);
2、乘方问题,给你一个数X,然后在给你一个正整数n,计算x的n次方?
时间复杂度为:O(n);
怎么用分治法,在非线性时间内解决这个问题?
分解为2个子问题是完全一样的,所以时间复杂度为:O(logn);
3、斐波那契数列:输入n,求第n项?
(1)、递归代码实现
#include<stdio.h>
int fibonacci(int n);
int fibonacci(int n){
if(n <= 0){
return 0;
}
if(n == 1){
return 1;
}
return fibonacci(n-1)+fibonacci(n-2);
}
void main(void){
int number;
int value;
printf("请输入斐波那契数:");
scanf("%d", &number);
value = fibonacci(number);
printf("%d\n", value);
}算法分析:
这就是一个递归树,处理相同的子问题,用的分治策略,在递归树上好多都是重复计算的;
时间复杂度(指数级):
(2)、非递归算法
#include<stdio.h>
int fibonacci(int n);
int fibonacci(int n){
int firstNumber = 0;
int secondNumber = 1;
int finNumber;
int i = 2;
if(n == 1){
return firstNumber;
}
if(n == 2){
return secondNumber;
}
for(i = 3; i <= n; i++){
finNumber = firstNumber + secondNumber;
firstNumber = secondNumber;
secondNumber = finNumber;
}
return finNumber;
}
void main(void){
int number;
int value;
printf("请输入第几个斐波那契数:");
scanf("%d", &number);
value = fibonacci(number);
printf("%d\n", value);
}算法分析:
时间复杂度:O(n);
(3)、公式法
算法分析:
这种方法在实际上不能实现,浮点数包含在内,取整将得不到正确答案;
(4)、平方递归算法
矩阵相乘法:
证明:
算法分析:
时间复杂度为:O(logn);
4、NxN矩阵乘法,具体描述为(矩阵乘法的顺序是不可以交换的):
(1)、用上面的这个公式实现算法,嵌套三层for循环;
时间复杂度为:O(n^3);
(2)、矩阵分块
r = ae+bg、s = af+bh、t = ce+dg、u = cf+dh;
将A、B矩阵共分为a、b、c、d、e、f、g、h一共8块,在递归的计算乘积,
一共需要8次n/2乘n/2矩阵的递归乘积;
时间复杂度为:O(n^log2(8)) = O(n^3);
(3)、Strassen(斯特拉森)算法:
在上面的矩阵分块的基础上写出以下式子:
只用7次递归乘法,所有时间复杂度:O(n^log2(7)) = O(n^2.81);
矩阵相乘目前最好的算法时间复杂度大约是:O(n^2.376);
5、将完全二叉树布局到电路网格上,要求占的面积要最少(包围的树形面积)?
(1)常规的放置方案:
树高log(n),宽为n,所以面积为:nlog(n);
(2)、可以变换树的图形,从宽度上着手;
树的网格布局一个好方法,也是分治法思想的一个应用。
H布局
即高和宽放的都是一样多的,完全树的L(n) = O(根号n),所以面积最小为:n;
本文出自 “wait0804” 博客,请务必保留此出处http://wait0804.blog.51cto.com/11586096/1898633
原文地址:http://wait0804.blog.51cto.com/11586096/1898633