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;