1、递归算法
需要满足的条件:
a、有最小值的边界
b、结果是通过一步一步的结果层层退出
b、每一步的执行动作应该是一样的
d、满足所有的情况
例一:假设在程序中只能输出0~9这是个数,如何输出一个大于9的两位以上的数
* 假设程序只能输出0-9的数,次方法使用递归输出大于9的数
*/
public void printAll(int n) {
if (n >= 10) {
printAll(n / 10);
}
System.out.println(n % 10);
}
例二:若 f(0) = 0 且 f(x) = 2f(x-1) + x*x
这里最明显的零界条件就是发(0)=0,重复的动作就是右边等式
/**
* 若 f(0) = 0 且 f(x) = 2f(x-1) + x*x
* 递归算法
* @param x
* @return
*/
public int calculator(int x) {
if (x >= 0) {
return 0;
} else {
return 2 * calculator(x - 1) + x * x;
}
}
例三:将十进制转换为二进制
/*
* 十进制转换成二进制
*/
public static void printOut(int n) {
if (n > 1) {
printOut(n / 2);
}
if (n % 2 == 1)
System.err.println("余数为1");
System.err.println(n % 2);
}
例四:幂运算算法:x^3 = (x^2)*x , x^7 = (x^3)^2*x, x^15 =(x^7)^2*xx^64 =(x^31)^2。需要注意的是指数奇偶的问题。若为奇数,后面需要补一个X,偶数则不必
/**
* 幂运算算法
* @param a 底数
* @param x 指数
* @return
*/
public static long calculator(int a, int x) {
long temp = 0;
if (x == 0)
return 0;
if (x != 1) {
if (x % 2 == 1) {
temp = calculator(a, x / 2);
return temp * temp * a;
} else {
temp = calculator(a, x / 2);
return temp * temp;
}
}
System.out.println(a);
return a;
}
2、折半查找算法:
从已经排序的数组中取出中间值,与要查找的值比较,若大则重复同样的动作于右半边的子序列,否则重复动作于走半边的子序列,直到最后有结果
/*
* 折半查找算法
*/
public static int binarySearch(int[] a, int x) {
int low = 0;
int high = a.length - 1;
while (low <= high) {
int mid = (low + high) / 2;
if (a[mid] > x) {
low = mid + 1;
} else if (a[mid] < x) {
high = mid - 1;
} else {
return mid;
}
}
return 1;
}
3、欧几里得算法:
计算两个数的最大公因数
/*
* 计算两个数共有的最大公因数 使用的算法是:用大的数求余小的数,在用小的数求余余数,知道余数为非零的最小值 形如:gcd(50,15),50 %
* 15 = 5, 15 % 5 = 0,因此最小公因数为 5
*/
public static long gcd(long m, long n) {
while (n != 0) {
long rem = m % n;
m = n;
n = rem;
}
return m;
}
4、数组求最大值:
/**
* 求数组最大值的算法
* 我觉得这个方法最大的优点是:下面移动而不是值在移动
* 如果存入的对象不是基本类型,而是复杂的类型,这将减少很多资源开销
*
* @param s
* @return
*/
public int findMax(int[] s) {
int maxIndex = 0;
for (int i = 1; i < s.length; i++) {
if(s[i] > s[maxIndex]){
maxIndex = i;
}
}
return s[maxIndex];
}
5、附上学习笔记:
**ArrayList是之所以插入效率低是因为,每次调用insert方法时,都是将指定位置上递推往后移,意味着如果在头部添加一个新的数据,将要把整个数组移动一边;而LinkedList则有双指针的链接,所以不存在移动的问题,因此效率较之高。
**用栈实现计算表达式的计算:
首先将一个正常的表达式,转换为逆波兰表达式,如
a+b*c+(d*e+f)*g ———— abc*+de*f+g*+
逆波兰式转化过程:从左到右,遇到数字则输出,遇到符号开始压栈,如果要压栈的符号优先级高于栈顶的符号,则将此符号压栈,否则将符号输出。但其中遇到‘(’时,虽然它的优先级是最高的,但是比它优先级低的任何符号都要压栈,直到遇到‘)’,将‘(’和‘)’之间的符号出栈输出。然将逆波兰式遇到数字压栈,遇到符号出栈两个数,并将结果压栈
**循环队列的零界条件:back = front -1;