1. 程式人生 > >Java複習之遞迴+連結串列

Java複習之遞迴+連結串列

這篇部落格主要是複習Java中遞迴和連結串列的相關知識。

(1)連結串列資料結構
連結串列是一種常見的基礎的資料結構是一種線性表,但是不會按線性的順序儲存資料,而是在每一個節點裡存著到下一個節點的指標,也就是說倆連結串列並不會向陣列那樣存在索引的概念,我們要取某一個節點的資料,則需要從根節點開始,一個個找過去。

連結串列可以看作有兩部分組成,一部分是資料,另一部分就是指向下一個節點的引用。
(2)遞迴演算法
遞迴演算法是一種直接或者間接呼叫自身演算法的過程。在計算機程式設計中遞迴演算法對解決一大類問題是十分有效的,它往往使演算法的描述簡潔而且易於理解。

遞迴需要注意的問題:
(1)遞迴必須要有出口


(2)遞迴的次數過多有可能會造成佔記憶體溢位

使用遞迴實現階乘:

public class RecursionDemo {
    public static void main(String args[])
    {
        System.out.println(factorial(5));
        System.out.println(factoria2(5));
    }
    //使用迴圈首先階乘
    public static int factorial( int num)
    {
        //do-while迴圈
        int sum = num;
        int
i=num-1; do{ sum *=i; i--; }while(i>1); return sum; } //使用遞迴實現階乘 public static int factoria2(int num) { if(num==1) return 1; return num * factoria2(num-1); } }

著重演練一下遞迴的呼叫的過程,假設當num=5的時候

第一次返回:5 * factoria2(4)

此時factoria2(4)再次呼叫函式factoria2()函式,此時返回

4 * factoria2(3)

此時factoria2(3)再次呼叫函式factoria2()函式,此時返回

3 * factoria2(2)

此時factoria2(2)再次呼叫函式factoria2()函式,此時返回

2 * factoria2(1)

此時factoria2(1)再次呼叫函式factoria2()函式,此時返回
1

然後再一步步退回去

factoria2(1) ==1 –>factoria2(2)==2

–>factoria2(3)==6 –>factoria2(4)==24

–>factoria2(5)==5*factoria2(4)=120

這就是遞迴的過程,先從原點走到出口,然後從出口在走到遠點,得出最後的結果。

連結串列增刪Demo:

public class LinkListDemo {
    public static void main(String args[])
    {
        NodeManager nm = new NodeManager();
        //同一個物件
        nm.addNode("節點1");
        nm.addNode("節點2");
        nm.addNode("節點3");
        nm.addNode("節點4");
        nm.addNode("節點5");
        nm.printNode();
        nm.delNode("節點3");
        nm.printNode();
    }
}

//連結串列節點的管理
class NodeManager{
    private Node root;//根節點
    //新增節點,主要是對於根節點,其餘節點遞迴使用節點的新增方法
    public void addNode(String name)
    {
        //如果根節點為空,那麼新增的就是根節點
        if(root == null)
        {
            root = new Node(name);
        }
        else
        {
            root.add(name);
        }
    }

    //刪除節點
    public void delNode(String name)
    {
        if(root!=null)
        {
            if(root.name.equals(name))
            {
                root = root.next;
            }
            else
            {
                root.del(name);
            }
        }
    }

    //輸出所有節點
    public void printNode()
    {
        if (root!=null)
        {
            System.out.print(root.name);
            root.print();
            System.out.println();
        }
    }

 //定義一個節點內部類
    class Node{
      String name;
     //表示節點之間的關係,自己的型別作為自己的屬性,表示下一個節點物件
     private Node next;
     public Node(String name)
     {
         this.name=name;
     }

     //新增節點
     public void add(String name)
     {
         if(this.next==null)
         {
             this.next=new Node(name);
         }
         else
         {
             //從這裡進入了遞迴
             this.next.add(name);
         }
     }

     //刪除節點
     public void del(String name)
     {
        if(this.next!=null)
        {
            if(this.next.name.equals(name)){
                this.next=this.next.next;
            }else
            {
                this.next.del(name);
            }
        }
     }

     //輸出所有節點
     public void print(){
        if(this.next!=null)
        {
            System.out.print("-->"+this.next.name);
            this.next.print();//遞迴
        }
     }
 }
}