Mike-Zhu / note

note
3 stars 1 forks source link

loserTree #1

Open Mike-Zhu opened 5 years ago

Mike-Zhu commented 5 years ago
class LoserTree {
    constructor(branches) {
        this.branches = branches
        this.len = branches.length
        this.tree = Array(this.len)
        this.nodes = {}
        this.create()
    }
    merge() {
        var top
        let ret = null, cur = ret
        while ((top = this.get(this.tree[0])) !== null && !!top) {
            if (ret === null) {
                ret = {
                    val: top.val,
                    next: null
                }
                cur = ret
            } else {
                cur.next = {
                    val: top.val,
                    next: null
                }
                cur = cur.next
            }
            this.put(this.tree[0])
            this.adjust(this.tree[0])
        }
        return ret
    }
    create() {
        var size = this.len,
            winner = 0
        // 为叶子节点赋值
        for (var i = 0; i < size; i++) {
            this.nodes[i] = this.branches[i]
        }
        for (var i = 0; i < size; i++) {
            if (this.beat(i, winner)) {
                winner = i
            }
        }
        this.tree.fill(winner)
        // 从后向前依次调整非叶子节点
        for (var i = size - 1; i >= 0; i--)
            this.adjust(i);
    }
    adjust(index) {
        var size = this.len,
            t = this.except(size + index, 2)
        while (t > 0) {
            //新插入的index与树中的值相比较
            //比较parent,胜者继续比较,败者留在这里
            let isIndexLose = this.beat(this.tree[t], index)
            if (isIndexLose) {
                var temp = this.tree[t]
                this.tree[t] = index;
                index = temp
            }
            t = this.except(t, 2)
        }
        this.tree[0] = index
    }
    put(index) {
        let branch = this.nodes[index]
        this.nodes[index] = branch && branch.next ? branch.next : null
    }
    get(index) {
        return this.nodes[index]
    }
    beat(index1, index2) {
        var t1 = this.get(index1)
        var t2 = this.get(index2)
        if (t1 == null)
            return false;
        if (t2 == null)
            return true;
        // 这里, 当叶节点数据相等时比较分支索引是为了实现排序算法的稳定性
        let n = t1.val - t2.val
        if (n === 0) {
            return index1 < index2
        }//index1 < index2 为胜
        return n < 0
    }
    except(num, se) {
        return parseInt(num / se, 10)
    }
}

TEST

var node1 = new ListNode(1)
node1.next = new ListNode(4)
node1.next.next = new ListNode(5)

var node2 = new ListNode(1)
node2.next = new ListNode(3)
node2.next.next = new ListNode(4)

var node3 = new ListNode(2)
node3.next = new ListNode(6)
var temp1 = new LoserTree([node1, node2, node3])
function ListNode(val) {
    this.val = val;
    this.next = null;
}