Java 數(shù)據(jù)結(jié)構(gòu)了解一下

所謂數(shù)據(jù)結(jié)構(gòu)漠烧,就是數(shù)據(jù)組合在一起并進行管理的方式,這些方式有表靡砌、棧和隊列已脓、樹、圖等通殃。數(shù)據(jù)結(jié)構(gòu)除了儲存數(shù)據(jù)還管理著數(shù)據(jù)度液。
算法呢,就是以某種方式得出所需要的一個數(shù)據(jù)或一組數(shù)據(jù)画舌。實現(xiàn)方式可能是計算堕担,或者遍歷等。

*以上僅為個人理解曲聂,有誤請指出霹购。

一、線性表

概念:線性表是最基本朋腋、最簡單齐疙、也是最常用的一種數(shù)據(jù)結(jié)構(gòu)。其中數(shù)據(jù)元素的排列方式是線性的旭咽。

分類:按照元素儲存結(jié)構(gòu)可分為順序表和鏈式表贞奋。

1.1 順序表

元素的存儲空間是連續(xù)的。比如數(shù)組穷绵。

2.2 鏈表:

元素的存儲空間是離散的轿塔、單獨的,元素之間的邏輯順序是通過鏈表中的指針鏈接次序?qū)崿F(xiàn)仲墨。鏈表也分為很多種勾缭,有單鏈表、雙鏈表宗收、循環(huán)鏈表漫拭,本文暫時分析單鏈表。

單鏈表中的數(shù)據(jù)是以結(jié)點來表示混稽,每個結(jié)點的構(gòu)成:元素(數(shù)據(jù))+指針(指示后繼元素的存儲位置),下面來實現(xiàn)單鏈表审胚。

2.2.1 單鏈表的創(chuàng)建和遍歷
public class LinkList {
    // 2.頭結(jié)點和當前結(jié)點
    public Node<String> head;
    public Node<String> current;

    /**
     *  3.添加新結(jié)點
     * @param data 要添加的結(jié)點的數(shù)據(jù)
     */
    public void add(String data){
        if(head == null){// 頭結(jié)點為null匈勋,說明鏈表中沒有元素
            // 創(chuàng)建結(jié)點并把新結(jié)點賦值給當前結(jié)點
            head = new Node<String>(data);
            current = head;
        } else {
            // 創(chuàng)建新節(jié)點賦值給當前結(jié)點的下一個結(jié)點,讓表連起來
            current.next = new Node<String>(data);
            // 當指針向后移動一位膳叨,保證當前結(jié)點指向最新的結(jié)點
            // 這樣再有新數(shù)據(jù)就一直向后鏈接
            current = current.next;
        }
    }

    /**
     * 4.打印單鏈表中所有結(jié)點數(shù)據(jù)
     * @param node 從該結(jié)點開始打印
     */
    public void printLinkList(Node node){
        if(node == null){
            return;
        }
        current = node;
        while (current != null){
            System.out.print(current.data);
            current = current.next;
        }
    }

    // 1.包含兩部分 data(數(shù)據(jù))洽洁,next(下一個結(jié)點指針)
    class Node<E>{
        E data;
        Node<E> next;

        public Node(E data) {
            this.data = data;
        }
    }
}
  1. 創(chuàng)建結(jié)點。LinkList 表示單鏈表類菲嘴,內(nèi)部類 Node 表示單鏈表的元素饿自。提供構(gòu)造函數(shù)以便創(chuàng)建結(jié)點汰翠。
  2. 在單鏈表中創(chuàng)建變量頭結(jié)點和當前結(jié)點,頭結(jié)點主要用于記錄首個結(jié)點信息昭雌,當前結(jié)點用于繼續(xù)創(chuàng)建后續(xù)結(jié)點复唤。
  3. 創(chuàng)建結(jié)點的函數(shù):
    如果單鏈表中沒有結(jié)點,則創(chuàng)建結(jié)點傳入數(shù)據(jù)并賦值給頭結(jié)點烛卧。這里頭結(jié)點作為鏈表是否為空的重要屬性佛纫,以及作為遍歷單鏈表所有結(jié)點的起始結(jié)點。
    如果不為空鏈表总放,則創(chuàng)建新結(jié)點并賦值給當前的結(jié)點的下一個結(jié)點呈宇,作為連接用。然后將指針向后移動一位指向最新的結(jié)點局雄,這樣當再添加結(jié)點會賦值給最新的結(jié)點的 next 保證鏈接甥啄。
  4. 單鏈表的遍歷:遍歷的話需要傳遞某個結(jié)點作為參數(shù),并賦值給當前結(jié)點炬搭,如果鏈表存在該結(jié)點則循環(huán)打印結(jié)點數(shù)據(jù)即可型豁。如果想要遍歷所有結(jié)點數(shù)據(jù),就用到變量頭結(jié)點 head 了尚蝌,因為它是作為鏈表的第一個結(jié)點存在的迎变,傳入 head 就可以遍歷所有的結(jié)點了。

測試:

public class Test {
    public static void main(String[] args){
        LinkList linkList = new LinkList();
        // 創(chuàng)建 LinkList 并添加數(shù)據(jù)
        // 這時鏈表為空飘言,第一個元素會作為 head 保存衣形。
        for (int i = 0; i < 10; i++){
            linkList.add("data"+i+"\n");
        }
        // 這時 head 已經(jīng)有數(shù)據(jù)了,執(zhí)行循環(huán)遍歷即可
        linkList.printLinkList(linkList.head);
    }
}

結(jié)果:

遍歷單鏈表

有關(guān)單鏈表的問題還有很多姿鸿,參考:

鏈表面試題Java實現(xiàn)【重要】

相關(guān)問題簡單實現(xiàn):

  • 獲取單鏈表長度:遍歷之...
/**
 * @return 獲取鏈表長度
 */
public int getLinkListLength(){
    if(head == null){
        return 0;
    }
    int length = 0;
    Node node = head;
    while (node != null){
        length++;
        node = node.next;
    }
    return length;
}
  • 反轉(zhuǎn)一個單鏈表
/**
 * 反轉(zhuǎn)鏈表谆吴,循環(huán)不會棧溢出
 * @param node
 * @return
 */
public Node reverseList(Node node){
    if(node == null || node.next == null){
        return node;
    }
    Node current = node;
    Node next = null;
    Node reverseHead = null;
    while (current != null){
        // 1.記錄當前結(jié)點的下一個結(jié)點用于指針后移
        next = current.next;
        // 4.下一輪循環(huán)時,舊的表的下一結(jié)點鏈接到新表頭
        current.next = reverseHead;
        // 2.將當前結(jié)點賦值給新表頭
        reverseHead = current;
        // 3.指針后移
        current = next;
    }
    return reverseHead;
}

這里的思路首先是循環(huán)苛预,然后分別記錄當前結(jié)點句狼、下一個結(jié)點和反轉(zhuǎn)后新鏈表的表頭,接著就是循環(huán)的賦值:

  1. 記錄當前結(jié)點的下一個結(jié)點热某,用于賦值給 current 實現(xiàn)指針后移腻菇。
  2. 將當前結(jié)點賦值給新表頭,循環(huán)賦值不斷替換昔馋,這樣保證舊鏈表的最后一個結(jié)點是反轉(zhuǎn)后鏈表的頭結(jié)點筹吐。
  3. 指針后移,因為現(xiàn)在的 next 已經(jīng)是剛才 current 的下一結(jié)點了秘遏。
  4. 下一輪循環(huán)時丘薛,舊的表的下一結(jié)點鏈接到新表頭:因為第一輪循環(huán) reverseHead 是 null,所以不用理會邦危。到第二個循環(huán)時洋侨,這時的 reverseHead 經(jīng)過第 1 步已經(jīng)有值且值是初始結(jié)點舍扰,將 current.next 也就是第三個結(jié)點指向初始結(jié)點,然后再循環(huán)處理到最后實現(xiàn)反轉(zhuǎn)希坚。
  • 查找單鏈表中間結(jié)點
    一種思路是遍歷獲取鏈表長度再拿中間边苹,這里記錄不允許遍歷的情況:
    /**
     * 查找單鏈表中間
     * @param head
     * @return
     */
    public Node findMidNode(Node head){
        if(head == null){
            return null;
        }
        // 定義兩個
        Node first = head;
        Node second = head;
        // 兩個同時移動,但是一個走一步另一個走兩步
        while (second != null && second.next != null){
            first = first.next;
            second = second.next.next;
        }
        return first;
    }

思路是定義兩個結(jié)點吏够,起點一樣勾给,循環(huán)一個走一步一個走兩步,這樣當走的最快的走不下去時第一個就是中間結(jié)點了锅知。

  • 合并兩個有序鏈表播急,合并后依然有序
    例如:
    鏈表1:1 > 2 > 3 > 4
    鏈表2:2 > 3 > 4 > 5
    合并后:1 > 2 > 2 > 3 > 3 > 4 > 4 > 5
/**
 * 合并兩個有序鏈表
 * @param head1 鏈表1 表頭
 * @param head2 鏈表2 表頭
 * @return
 */
public Node mergeList(Node head1,Node head2){
    // 如果兩個鏈表都為 null 返回 null
    if(head1 == null && head2 == null){
        return null;
    }
    // 如果其中一個為 null,返回不為 null 的就是要的表頭了
    if(head1 == null){
        return head2;
    }
    if(head2 == null){
        return head1;
    }

    Node head = null;
    Node current = null;
    // 判斷首位售睹,確認新表頭
    if((int)head1.data < (int)head2.data ){
        head = head1;
        current = head1;
        head1 = head1.next;
    } else {
        head = head2;
        current = head2;
        head2 = head2.next;
    }

    while (head1 != null && head2 != null){
        if((int)head1.data < (int)head2.data){
            current.next = head1; // 循環(huán)比較桩警,把較小的值鏈接到新表后
            current = current.next;// 指針后移
            head1 = head1.next;
        } else {
            current.next = head2;
            current = current.next;
            head2 = head2.next;
        }
    }
    // 經(jīng)過上面循環(huán),head1 還有值說明 head2 循環(huán)完畢
    if(head1 != null){
        // 后面是有序的昌妹,所以只要鏈接到當前結(jié)點即可
        current.next = head1;
    }
    // 同理捶枢,head1 循環(huán)完畢
    if(head2 != null){
        current.next = head2;
    }
    return head;
}

自行理會吧...233333.

二、棧

特點:先進后出(后進先出)飞崖。也就是說烂叔,保存在棧中的元素會像摞書本一樣一個一個壓在棧中,取出來的時候會一本一本拿固歪。

棧模型(圖片來源網(wǎng)絡(luò))

Java Stack 類:

Java Stack

  • push(): 往棧中添加數(shù)據(jù)
  • pop(): 返回棧頂?shù)闹挡h除
  • peek(): 返回棧頂?shù)闹邓饧Γ粍h除
  • search(Object o): 返回元素 o 最后出現(xiàn)下標

一個簡單的基于數(shù)組的實現(xiàn)

public class Stack {
    // 記錄棧頂坐標,同時也可依據(jù)該值獲取棧頂元素
    private int top = -1;
    private Object[] data;

    public Stack(int capacity) throws Exception {
        if(capacity < 0){
            throw new Exception("Illegal capacity:"+capacity);
        }
        data = new Object[capacity];
    }

    public Object push(Object o) throws Exception {
        if(top == data.length - 1){
            throw new Exception("Stack is full!");
        }
        return data[++top] = o;
    }

    public Object pop() throws Exception {
        if(top == -1){
            throw new Exception("Stack is empty!");
        }
        return data[top--];
    }

    public void print(){
        System.out.print("bottom -> top: | ");
        for(int i = 0 ; i <= top ; i++){
            System.out.print(data[i]+" | ");
        }
        System.out.print("\n");
    }
}

一個簡單的基于鏈表的實現(xiàn)

public class LinkedStack {

    private LinkedList linkedList = new LinkedList();

    public void push(Object o){
        linkedList.addFirst(o);
    }

    public Object pop(){
        return linkedList.removeFirst();
    }

}

棧和隊列的面試題Java實現(xiàn)【重要】

三牢裳、隊列

特點:先進先出 即最先放入的元素最先被取出逢防。元素存放時類似棧,按順序排列蒲讯。元素存儲時從隊尾放入忘朝,取出時則先從隊頭出隊。

Queue示意圖(Copy)
隊列的創(chuàng)建:

一般情況下判帮,隊列創(chuàng)建的方式有兩種:

  • 基于數(shù)組創(chuàng)建(順序隊列)
  • 基于鏈表創(chuàng)建(鏈式隊列)

一個簡單的隊列的實現(xiàn):

public class Queue {

    public Node head;
    public Node current;

    /**
     * 與鏈表添加數(shù)據(jù)方式類似
     * @param data 數(shù)據(jù)
     */
    public void addNode(int data){
        if(head == null){
            head = new Node(data);
            current = head;
        } else {
            current = new Node(data);
            current = current.next;
        }
    }

    /**
     * 出隊列永遠都是隊頭的數(shù)據(jù)
     * @return head 的數(shù)據(jù)
     * @throws Exception
     */
    public int pop() throws Exception {
        if(head == null){
            throw new Exception("隊列為空");
        }
        Node node = head; //要出隊的Node
        head = node.next; //指針后移鸭轮,因為頭已經(jīng)出隊
        return node.data;
    }

    class Node{
        Node next;
        int data;
        public Node(int data){
            this.data = data;
        }
    }
}

四汇跨、樹(多數(shù)資料來自百度百科)

??樹狀圖是一種數(shù)據(jù)結(jié)構(gòu)谆刨,它是由n(n>=1)個有限節(jié)點組成一個具有層次關(guān)系的集合鉴逞。把它叫做“樹”是因為它看起來像一棵倒掛的樹,也就是說它是根朝上偎痛,而葉朝下的。它具有以下的特點:
??每個節(jié)點有零個或多個子節(jié)點独郎;沒有父節(jié)點的節(jié)點稱為根節(jié)點踩麦;每一個非根節(jié)點有且只有一個父節(jié)點枚赡;除了根節(jié)點外,每個子節(jié)點可以分為多個不相交的子樹谓谦;

定義:

樹(tree)是包含n(n>0)個結(jié)點的有窮集贫橙,其中:
(1) 每個元素稱為結(jié)點(node);
(2) 有一個特定的結(jié)點被稱為根結(jié)點或樹根(root)反粥。
(3) 除根結(jié)點之外的其余數(shù)據(jù)元素被分為m(m≥0)個互不相交的集合T1卢肃,T2,……Tm-1才顿,其中每一個集合Ti(1<=i<=m)本身也是一棵樹莫湘,被稱作原樹的子樹(subtree)。


相關(guān)概念:
  • 樹的高度/深度郑气,結(jié)點的層次(Level):從根開始定義起幅垮,根為第一層,根的子結(jié)點為第二層尾组。依次類推忙芒,如上圖的樹深度/高度為 4。
  • 森林:m(m>=0)棵互不相交的樹的集合讳侨。
種類:
  • 無序樹:樹中任意節(jié)點的子結(jié)點之間沒有順序關(guān)系呵萨,可以互換,這種樹稱為無序樹,也稱為自由樹;
  • 有序樹:樹中任意節(jié)點的子結(jié)點之間有順序關(guān)系跨跨,這種樹稱為有序樹潮峦;
  • 二叉樹:每個節(jié)點最多含有兩個子樹的樹稱為二叉樹;
  • 完全二叉樹:若設(shè)二叉樹的深度為h歹叮,除第 h 層外跑杭,其它各層 (1~h-1) 的結(jié)點數(shù)都達到最大個數(shù),第 h 層所有的結(jié)點都連續(xù)集中在最左邊咆耿,這就是完全二叉樹德谅。
完全二叉樹
  • 滿二叉樹:除最后一層無任何子節(jié)點外,每一層上的所有結(jié)點都有兩個子結(jié)點二叉樹萨螺。也就是說窄做,如果一個二叉樹的層數(shù)為K,且結(jié)點總數(shù)是(2^k) -1 慰技,則它就是滿二叉樹椭盏。
各種樹
  • 哈夫曼樹:給定n個權(quán)值作為n個葉子結(jié)點,構(gòu)造一棵二叉樹吻商,若帶權(quán)路徑長度達到最小掏颊,稱這樣的二叉樹為最優(yōu)二叉樹,也稱為哈夫曼樹(Huffman Tree)。哈夫曼樹是帶權(quán)路徑長度最短的樹乌叶,權(quán)值較大的結(jié)點離根較近盆偿。

二叉樹

二叉樹的結(jié)點:
class TreeNode<E>{
    E data;
    TreeNode left;
    TreeNode right;

    public TreeNode(E data){
        this.data = data;
    }
}
二叉樹的創(chuàng)建:
private List<TreeNode> datas;//存儲所有的節(jié)點
public TreeNode root;//根節(jié)點

public BinaryTree(){
}

public void createTree(Object[] objs){
    datas = new ArrayList<>();
    for (Object object : objs) {
        datas.add(new TreeNode(object));
    }
    root=datas.get(0);//將第一個元素作為根節(jié)點
    for(int i = 0; i < objs.length/2; i++){
        datas.get(i).left = datas.get(i*2+1);
        if(i*2+2 < datas.size()){// 避免下標越界
            datas.get(i).right = datas.get(i*2+2);
        }
    }
}
二叉樹的遍歷:

二叉樹的遍歷方式有很多,如果限制了從左到右的方式准浴,主要可以分為四種:

  1. 前序/先序遍歷
    先訪問根結(jié)點事扭,然后前序遍歷左子樹,再前序遍歷右子樹乐横。
//前序/先序遍歷
public void preorder(TreeNode<E> root){
    if(root == null){
        return;
    }
    System.out.print(root.data+"");
    preorder(root.left);
    preorder(root.right);
}
  1. 中序遍歷
//中序遍歷
public void inorder(TreeNode<E> root){
    if(root == null){
        return;
    }
    inorder(root.left);
    System.out.print(root.data+"");
    inorder(root.right);
}
  1. 后序遍歷
//后序遍歷
public void postorder(TreeNode<E> root) {
    if (root == null){
        return;
    }
    postorder(root.left);
    postorder(root.right);
    System.out.println(root.data + " ");
}

三種遍歷方式都用到了遞歸求橄,從代碼上看區(qū)別就是打印數(shù)據(jù)的位置。

二叉樹的高度:

同樣是利用遞歸以及左右子結(jié)點判斷逐漸增加高度葡公。

public int height(TreeNode root) {
    if (root == null)
        return 0;// 遞歸結(jié)束:空樹高度為0
    else {
        int i = height(root.left);
        int j = height(root.right);
        return (i < j) ? (j + 1) : (i + 1);
    }
}
二叉樹的結(jié)點數(shù)量:
public int size(TreeNode root) {
    if (root == null) {
        return 0;
    } else {
        return 1 + size(root.left) + size(root.right);
    }
}
二叉樹的結(jié)點插入:
public String insert(int value) {
    String error = null;

    TreeNode node = new TreeNode(value);
    if (root == null) {
        root = node;
        root.left  = null;
        root.right = null;
    } else {
        TreeNode current = root;
        TreeNode parent = null;
        while (true) {
            if (value < (int)current.data) {
                parent = current;
                current = current.left;
                if (current == null) {
                    parent.left = node;
                    break;
                }
            } else if (value > (int)current.data) {
                parent = current;
                current = current.right;
                if (current == null) {
                    parent.right = node;
                    break;
                }
            } else {
                error = "having same value in binary tree";
                System.out.print(error);
            }
        } // end of while
    }
    return error;
}
二叉樹的結(jié)點刪除:
/**
 * 刪除結(jié)點
 * @param value
 * @return
 */
public boolean delete(int value) {
    TreeNode current = root;    //需要刪除的節(jié)點
    TreeNode parent = null;     //需要刪除的節(jié)點的父節(jié)點
    boolean isLeftChild = true;   //需要刪除的節(jié)點是否父節(jié)點的左子樹

    while (true) {
        if (value == (int)current.data) {
            break;
        } else if (value < (int)current.data) {
            isLeftChild = true;
            parent = current;
            current = current.left;
        } else {
            isLeftChild = false;
            parent = current;
            current = current.right;
        }

        //找不到需要刪除的節(jié)點罐农,直接返回
        if (current == null)
            return false;
    }

    //分情況考慮
    //1、需要刪除的節(jié)點為葉子節(jié)點
    if (current.left == null && current.right == null) {
        //如果該葉節(jié)點為根節(jié)點匾南,將根節(jié)點置為null
        if (current == root) {
            root = null;
        } else {
            //如果該葉節(jié)點是父節(jié)點的左子節(jié)點啃匿,將父節(jié)點的左子節(jié)點置為null
            if (isLeftChild) {
                parent.left  = null;
            } else { //如果該葉節(jié)點是父節(jié)點的右子節(jié)點,將父節(jié)點的右子節(jié)點置為null
                parent.right = null;
            }
        }
    }
    //2蛆楞、需要刪除的節(jié)點有一個子節(jié)點溯乒,且該子節(jié)點為左子節(jié)點
    else if (current.right == null) {
        //如果該節(jié)點為根節(jié)點,將根節(jié)點的左子節(jié)點變?yōu)楦?jié)點
        if (current == root) {
            root = current.left;
        } else {
            //如果該節(jié)點是父節(jié)點的左子節(jié)點豹爹,將該節(jié)點的左子節(jié)點變?yōu)楦腹?jié)點的左子節(jié)點
            if (isLeftChild) {
                parent.left = current.left;
            } else {  //如果該節(jié)點是父節(jié)點的右子節(jié)點裆悄,將該節(jié)點的左子節(jié)點變?yōu)楦腹?jié)點的右子節(jié)點
                parent.right = current.left;
            }
        }
    }
    //2、需要刪除的節(jié)點有一個子節(jié)點臂聋,且該子節(jié)點為右子節(jié)點
    else if (current.left == null) {
        //如果該節(jié)點為根節(jié)點光稼,將根節(jié)點的右子節(jié)點變?yōu)楦?jié)點
        if (current == root) {
            root = current.right;
        } else {
            //如果該節(jié)點是父節(jié)點的左子節(jié)點,將該節(jié)點的右子節(jié)點變?yōu)楦腹?jié)點的左子節(jié)點
            if (isLeftChild) {
                parent.left = current.right;
            } else {  //如果該節(jié)點是父節(jié)點的右子節(jié)點孩等,將該節(jié)點的右子節(jié)點變?yōu)楦腹?jié)點的右子節(jié)點
                parent.right = current.right;
            }
        }
    }
    //3艾君、需要刪除的節(jié)點有兩個子節(jié)點,需要尋找該節(jié)點的后續(xù)節(jié)點替代刪除節(jié)點
    else {
        TreeNode successor = getSuccessor(current);
        //如果該節(jié)點為根節(jié)點肄方,將后繼節(jié)點變?yōu)楦?jié)點冰垄,并將根節(jié)點的左子節(jié)點變?yōu)楹罄^節(jié)點的左子節(jié)點
        if (current == root) {
            root = successor;
        } else {
            //如果該節(jié)點是父節(jié)點的左子節(jié)點,將該節(jié)點的后繼節(jié)點變?yōu)楦腹?jié)點的左子節(jié)點
            if (isLeftChild) {
                parent.left = successor;
            } else {  //如果該節(jié)點是父節(jié)點的右子節(jié)點权她,將該節(jié)點的后繼節(jié)點變?yōu)楦腹?jié)點的右子節(jié)點
                parent.right = successor;
            }
        }
    }
    current = null;
    return true;
}

/**
 *
 * 得到后繼節(jié)點虹茶,即刪除節(jié)點的左后代
 */
private TreeNode getSuccessor(TreeNode delNode) {
    TreeNode successor = delNode;
    TreeNode successorParent = null;
    TreeNode current = delNode.right;

    while (current != null) {
        successorParent = successor;
        successor = current;
        current = current.left;
    }

    //如果后繼節(jié)點不是刪除節(jié)點的右子節(jié)點時,
    if (successor != delNode.right) {
        //要將后繼節(jié)點的右子節(jié)點指向后繼結(jié)點父節(jié)點的左子節(jié)點隅要,
        successorParent.left = successor.right;
        //并將刪除節(jié)點的右子節(jié)點指向后繼結(jié)點的右子節(jié)點
        successor.right = delNode.right;
    }
    //任何情況下蝴罪,都需要將刪除節(jié)點的左子節(jié)點指向后繼節(jié)點的左子節(jié)點
    successor.left = delNode.left;

    return successor;
}
測試:
public static void main(String[] args){

    BinaryTree binTree=new BinaryTree();
    Object[] objs={0,1,2,3,4,5,6,7,8,9};
    binTree.createTree(objs);
    binTree.insert(10);
    binTree.preorder(binTree.root);
//        binTree.inorder(binTree.root);
//        binTree.postorder(binTree.root);
//        System.out.print(binTree.height(binTree.root)+" ");
}

關(guān)于二叉樹更多資料:

二叉樹的java實現(xiàn)
二叉樹之Java實現(xiàn)二叉樹基本操作

五、圖

暫時還沒有用到圖步清,等到用到的時候再來復習要门。

六、排序

有空記得自己實現(xiàn)。

必須知道的八大種排序算法【java實現(xiàn)】(一) 冒泡排序暂衡、快速排序

其它比較好的文章:

Android程序員面試會遇到的算法(part 1 關(guān)于二叉樹的那點事) 附Offer情況
那些年询微,我們被問到的數(shù)據(jù)結(jié)構(gòu)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末崖瞭,一起剝皮案震驚了整個濱河市狂巢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌书聚,老刑警劉巖唧领,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異雌续,居然都是意外死亡斩个,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門驯杜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來受啥,“玉大人,你說我怎么就攤上這事鸽心」鼍郑” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵顽频,是天一觀的道長藤肢。 經(jīng)常有香客問我,道長糯景,這世上最難降的妖魔是什么嘁圈? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮蟀淮,結(jié)果婚禮上最住,老公的妹妹穿的比我還像新娘。我一直安慰自己怠惶,他們只是感情好涨缚,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著甚疟,像睡著了一般仗岖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上览妖,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天轧拄,我揣著相機與錄音,去河邊找鬼讽膏。 笑死檩电,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播俐末,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼料按,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了卓箫?” 一聲冷哼從身側(cè)響起载矿,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎烹卒,沒想到半個月后闷盔,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡旅急,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年逢勾,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片藐吮。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡溺拱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出谣辞,到底是詐尸還是另有隱情迫摔,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布潦闲,位于F島的核電站攒菠,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏歉闰。R本人自食惡果不足惜辖众,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望和敬。 院中可真熱鬧凹炸,春花似錦、人聲如沸昼弟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽舱痘。三九已至变骡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間芭逝,已是汗流浹背塌碌。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留旬盯,地道東北人台妆。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓翎猛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親接剩。 傳聞我的和親對象是個殘疾皇子切厘,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355