實驗二 20162312

實現二叉樹

要求:參考教材p375,完成鏈樹LinkedBinaryTree的實現(getRight,contains,toString,preorder,postorder)用JUnit或本身編寫驅動類對本身實現的LinkedBinaryTree進行測試,提交測試代碼運行截圖,要全屏,包含本身的學號信息,課下把代碼推送到代碼託管平臺.

實驗思路:getright仿照書上getleft格式便可;contains方法調用find方法,返回值則是boolean類型;preorder和postorder方法則和inorder方法有些相似,都是調用BTnode類並遞歸;

實驗截圖:

中序先序序列構造二叉樹

要求:基於LinkedBinaryTree,實現基於(中序,先序)序列構造惟一一棵二㕚樹的功能,好比教材P372,給出HDIBEMJNAFCKGL和ABDHIEJMNCFGKL,構造出附圖中的樹

用JUnit或本身編寫驅動類對本身實現的功能進行測試,提交測試代碼運行截圖,要全屏,包含本身的學號信息html

課下把代碼推送到代碼託管平臺java

實驗思路:將左子樹中的元素的先序表達式放入新的數組

實驗截圖:

決策樹

要求:完成PP16.6,提交測試代碼運行截圖,要全屏,包含本身的學號信息,課下把代碼推送到代碼託管平臺.

實驗思路:主要是改書上的代碼,但要對樹的構造比較清楚,而且本身設定的內容邏輯要和樹的構造相符。

實驗截圖:

表達式樹

要求:完成PP16.8,提交測試代碼運行截圖,要全屏,包含本身的學號信息,課下把代碼推送到代碼託管平臺

實驗思路:沒有完成

二叉查找樹

要求:完成PP17.1,提交測試代碼運行截圖,要全屏,包含本身的學號信息,課下把代碼推送到代碼託管平臺.

實驗思路:很容易補全findMax(),findMin()方法.

實驗截圖:

紅黑樹分析

要求:參考http://www.cnblogs.com/rocedu/p/7483915.html對Java中的紅黑樹(TreeMap,HashMap)進行源碼分析,並在實驗報告中體現分析結果

實驗思路:分析源代碼並上網參考相關資料

什麼是紅黑樹

  • 每一個節點要麼是紅色,要麼是黑色。
  • 根節點必須是黑色
  • 紅色節點不能連續(也便是,紅色節點的孩子和父親都不能是紅色)。
  • 對於每一個節點,從該點至null(樹尾端)的任何路徑,都含有相同個數的黑色節點。

左旋及代碼實現

//Rotate Left
private void rotateLeft(Entry<K,V> p) {
    if (p != null) {
        Entry<K,V> r = p.right;
        p.right = r.left;
        if (r.left != null)
            r.left.parent = p;
        r.parent = p.parent;
        if (p.parent == null)
            root = r;
        else if (p.parent.left == p)
            p.parent.left = r;
        else
            p.parent.right = r;
        r.left = p;
        p.parent = r;
    }
}

右旋及代碼實現

//Rotate Right
private void rotateRight(Entry<K,V> p) {
    if (p != null) {
        Entry<K,V> l = p.left;
        p.left = l.right;
        if (l.right != null) l.right.parent = p;
        l.parent = p.parent;
        if (p.parent == null)
            root = l;
        else if (p.parent.right == p)
            p.parent.right = l;
        else p.parent.left = l;
        l.right = p;
        p.parent = l;
    }
}

方法剖析:

  • 方法get(Object key)方法根據指定的key值返回對應的value,該方法調用了getEntry(Object key)獲得相應的entry,而後返回entry.value。
    所以getEntry()是算法的核心。算法思想是根據key的天然順序(或者比較器順序)對二叉查找樹進行查找,直到找到知足k.compareTo(p.key) == 0的entry。
//getEntry()方法
final Entry<K,V> getEntry(Object key) {
    ......
    if (key == null)//不容許key值爲null
        throw new NullPointerException();
    Comparable<? super K> k = (Comparable<? super K>) key;//使用元素的天然順序
    Entry<K,V> p = root;
    while (p != null) {
        int cmp = k.compareTo(p.key);
        if (cmp < 0)//向左找
            p = p.left;
        else if (cmp > 0)//向右找
            p = p.right;
        else
            return p;
    }
    return null;
}
  • 方法put(K key, V value)方法是將指定的key, value對添加到map裏。該方法首先會對map作一次查找,看是否包含該元組,若是已經包含則直接返回,
    查找過程相似於getEntry()方法;若是沒有找到則會在紅黑樹中插入新的entry,若是插入以後破壞了紅黑樹的約束,還須要進行調整(旋轉,改變某些節點的顏色)。
public V put(K key, V value) {
    ......
    int cmp;
    Entry<K,V> parent;
    if (key == null)
        throw new NullPointerException();
    Comparable<? super K> k = (Comparable<? super K>) key;//使用元素的天然順序
    do {
        parent = t;
        cmp = k.compareTo(t.key);
        if (cmp < 0) t = t.left;//向左找
        else if (cmp > 0) t = t.right;//向右找
        else return t.setValue(value);
    } while (t != null);
    Entry<K,V> e = new Entry<>(key, value, parent);//建立並插入新的entry
    if (cmp < 0) parent.left = e;
    else parent.right = e;
    fixAfterInsertion(e);//調整
    size++;
    return null;
}
  • 方法remove的做用是刪除key值對應的entry,該方法首先經過上文中提到的getEntry(Object key)方法找到key值對應的entry, 而後調用deleteEntry(Entry<K,V> entry)刪除對應的entry。因爲刪除操做會改變紅黑樹的結構,有可能破壞紅黑樹的約束,所以有可能要進行調整。
相關文章
相關標籤/搜索