概念
程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
顾名思义,就是自己调用自己,优点就是减少了代码量,缺点就是绕脑子,还有就是容易造成栈溢出,我简单来举个例子说什么是递归,他是怎么实现的呢?
- 就举个100的累加吧。我们知道sum(100)其实就是sum(99)+99对吧,那么sum(99)是不是又是sum(98)+98,依次类推。。。。。直到sum(2)+2,sum(1)+1。我画个图来简单说明一下。
我们来看看具体实现的代码
public class Recursion {
public static void main(String[] args) {
int sum = 100;
int allsum = getsum(sum);
System.out.println(allsum);
}
private static int getsum(int i) {
// TODO Auto-generated method stub
if(i==1) {//递归结束条件
return i;
}
return getsum(i-1)+i;//一层一层的返回
}
}
接下来我们看看递归和迭代实现的斐波拉契数列有什么区别
递归
public class FIBO {
public static void main(String[] args) {
for(int i=1;i<=10;i++) {
System.out.print(fibo(i)+",");
}
}
private static int fibo(int n) {
// TODO Auto-generated method stub
if(n==1||n==2) {
return 1;
}
return fibo(n-1)+fibo(n-2);
}
}
迭代
/*
* 迭代求fibo
*/
public class FIBO2 {
public static void main(String[] args) {
for (int i = 1; i <= 10; i++) {
System.out.print(fibo(i)+",");
}
}
private static int fibo(int n) {
// TODO Auto-generated method stub
int a = 1;
int b = 1;
int c = 0;
if (n == 1 || n == 2) {
return 1;
} else {
for (int i = 3; i <= n; i++) {
c = a + b;
a = b;
b = c;
}
}
return c;
}
}
递归实现的阶乘
/*
* 递归求N的阶乘
* s4=s3*3;
* s3=s2*2;
* s2=s1*1;
* s1=1
*/
public class JieCheng {
public static void main(String[] args) {
System.out.println(function(4));
}
private static int function(int n) {
// TODO Auto-generated method stub
if(n==1) {
return 1;
}else {
return function(n-1)*n;
}
}
}
是不是代码比迭代少了很多呢?
再看看递归实现的单链表
package p03.递归;
public class DiguiLinkList<E> {
private class Node {
E data;
Node next;
public Node() {
this(null, null);
}
public Node(E data) {
this(data, null);
}
public Node(E data, Node next) {
this.data = data;
this.next = next;
}
}
private int size;
private Node head;
public DiguiLinkList() {
size = 0;
head = new Node();
}
public void add(E e) {// 默认是尾插法
add(head, e);
}
private void add(Node head2, E e) {
// TODO Auto-generated method stub
if (head2.next == null) {
Node n = new Node(e);
n.next = head2.next;
head2.next = n;
head2 = n;
size++;
return;
} else {
add(head2.next, e);
}
}
public void remove() {
remove(head);
size--;
}
private Node remove(DiguiLinkList<E>.Node head2) {
// TODO Auto-generated method stub
if (head2.next == null) {// 当最后一个元素的下一个为空时
// 将当前结点置为空返回给倒数第二个元素
return null;
}
head2.next = remove(head2.next);
return head2;
}
public int getsize() {
return size;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("[");
toString(head.next, sb);
return sb.toString();
}
private void toString(Node node, StringBuilder sb) {
// TODO Auto-generated method stub
if (node == null) {
sb.append("]");
} else {
sb.append(node.data);
toString(node.next, sb);
}
}
public static void main(String[] args) {
DiguiLinkList<Integer> list = new DiguiLinkList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.remove();
System.out.println(list);
System.out.println(list.getsize());
}
}