Tree.coffee

###
Author: fachao zhang
File: collections.coffee
Released under the MIT license
Date : 2014-01-05
###

class TreeNode
    constructor: (@element, @firstChild, @nextSibling)-> 
      

class Comparable
    compareTo : ->      


class AANode
    constructor : (@element, @left, @right, @level = 1) ->

###
Implements an AA-tree.
###
class AATree
    constructor : ->
       @nullNode = new AANode(null, null, null);
       @nullNode.left = @nullNode.right = @nullNode;
       @nullNode.level = 0;
       @root = @nullNode
    
    insert : (obj) ->
       @root = @_insert obj, @root
       return
       
    remove : (obj) ->
       @deletedNode = @nullNode
       @root = @_remove obj, @root
       return
       
    findMin : ->
        if @isEmpty()
            return null
        ptr = @root
        while ptr.left inst @nullNode
            ptr = ptr.left
        return ptr.element      
                    
    findMax : ->
        if @isEmpty()
            return null
        ptr = @root
        while ptr.right isnt @nullNode
            ptr = ptr.right
        return ptr.element        
      
    makeEmpty : ->
        @root = null
        return
      
    isEmpty : -> 
        return @root is null
        
    find : (x)->
        current = @root
        @nullNode.element = x
        `for(;;){
            if (this._compare(x, current.element) < 0)
                current = current.left;
            else if (this._compare(x, current.element) > 0)  
                current = current.right;
            else if (current !== this.nullNode)
                return current.element;
            else
                return null                  
        }`
        
    _compare : (obj, elem)->
        if obj is elem
            return 0    
        else if obj > elem
            return 1
        else
            return -1     
    
    _insert : (obj, node) ->
        if node is @nullNode
            node = new AANode obj, @nullNode, @nullNode
        else if @_compare(obj, node.element) < 0
            node.left = @_insert obj, node.left
        else if @_compare(obj, node.element) > 0       
            node.right = @_insert obj, node.right
        else
            return node
        node = @_skew node
        node = @_split node
    
    _skew : (node) ->
        if node.left.level is node.level
              node = @_rotateWithLeftChild node
        return node
         
    _split : (node) ->
        if node.right.level is node.level
            node = @_rotateWithRightChild node
            node.level++
        return node
        
    _rotateWithLeftChild : (k2) ->
        k1 = k2.left
        k2.left = k1.right
        k1.right = k2
        return k1
        
    _rotateWithRightChild : (k1) ->    
        k2 = k1.right
        k1.right = k2.left
        k2.left = k1
        return k2
    
    _remove : (x, t) ->
        if t isnt @nullNode
            @lastNode = t
            if @_compare(x, t.element) < 0
                t.left = @_remove x, t.left
            else
                @deletedNode = t;
                t.right = @_remove x, t.right     
        
            if t is @lastNode
                if @deletedNode is @nullNode or @_compare(x, @deletedNode.element) isnt 0
                    return t
                @deletedNode.element = t.element
                t = t.right
            else
                if t.left.level < t.level - 1 or t.right.level < t.level - 1
                    if t.right.level > --t.level
                        t.right.level = t.level 
                    t = @_skew t
                    t.right = @_skew t.right
                    t.right.right = @_skew t.right.right
                    t = split t
                    t.right = @_split t.right
        return t
        
     toString : ->
        if(!JSON)
            throw new Error "JSON object is not support in your browser, pleasse download and use json2.js."
        result = []
        @_traverse result, @root
        return JSON.stringify result 
      
    _traverse : (arr, node) ->
        if node isnt @nullNode
            @_traverse arr,node.left
            arr.push node.element
            @_traverse arr,node.right
        return
           
        
                      
      
class BinaryNode
    constructor : (@element, @left, @right) ->      
      
class BinarySearchTree      
    constructor : ->
        ###The tree root.###
        @root = null
          
    ###
     * Make the tree logically empty.
    ###  
    makeEmpty : ->
        @root = null
        return  
    
    ###
     * Test if the tree is logically empty.
     * @return true if empty, false otherwise.
    ###  
    isEmpty : ->
        return @root is null
    
    ###
     *Internal method to find an item in a subtree.
    ###    
    contains : (obj) ->
        return @_contains obj, @root
    
    ###
     * Internal method to get element field.
     * @param t the node.
     * @return the element field or null if t is null.
    ###    
    elementAt : (node) ->
        if node is null
            return null
        else
            return node.element     
    ###
     * Find the smallest item in the tree.
     * @return smallest item or null if empty.
    ###    
    findMin : ->
        if @isEmpty()
            throw new Error "Under flow error."    
        return @elementAt(@_findMin(@root))
     
    ###
     * Find the largest item in the tree.
     * @return the largest item of null if empty.  
    ###  
    findMax : ->
        if @isEmpty()
            throw new Error "Under flow error."   
        return @elementAt(@_findMax(@root))
    
    find : (x)->
        return @elementAt(@_find(@root))    
      
    ###
     * Insert into the tree; duplicates are ignored.
     * @param obj the item to insert.
    ###  
    insert : (obj) ->
        @root = @_insert obj, @root
        return
        
    ###
     * Remove from the tree. Nothing is done if x is not found.
     * @param obj the item to remove.
    ### 
    remove : (obj)-> 
        @root = @_remove obj, @root
        return
        
    _compare : (obj, elem)->
        if obj is elem
            return 0    
        else if obj > elem
            return 1
        else
            return -1
    
    ###
    @description : Internal method to find an item in a subtree.
    @param obj : obj is item to search for.
    @param root : the node that roots the subtree.
    @return node containing the method item.
    ###
    _contains : (obj, node) ->
        if node is null
            return false
        compareResult = @_compare obj, node.element
        if compareResult < 0
            @_contains obj, node.left
        else if compareResult > 0
            @_contains obj, node.right    
        else
            return true     
    ###
     * Internal method to find the smallest item in a subtree.
     * @param node the node that roots the tree.
     * @return node containing the smallest item.
    ###    
    _findMin : (node) -> 
        if node is null
            return null
        else if node.left is null
            return node
        else
            @_findMin node.left
     
    ###
     * Internal method to find the largest item in a subtree.
     * @param node the node that roots the tree.
     * @return node containing the largest item.
    ### 
    _findMax : (node) ->  
        if node isnt null
            while node.right isnt null
                node = node.right
        return node        
     
    ###
     * Internal method to insert into a subtree.
     * @param obj the item to insert.
     * @param node the node that roots the tree.
     * @return the new root.
    ### 
    _insert : (obj, node) -> 
        if node is null
            return new BinaryNode obj, null, null
        compareResult = @_compare obj, node.element
        if compareResult < 0
            node.left = @_insert obj, node.left
        else if compareResult > 0
            node.right = @_insert obj, node.right
        return node
    
    ###
     * Internal method to remove from a subtree.
     * @param obj the item to remove.
     * @param node the node that roots the tree.
     * @return the new root.
    ###        
    _remove : (obj, node) -> 
        if node is null
            return node
        compareResult = @_compare obj, node.element
        if compareResult < 0
            node.left = @_remove obj, node.left
        else if compareResult > 0
            node.right = @_remove obj, node.right
        else if node.left isnt null and node.right isnt null
            node.element = @_findMin(node.right).element
            node.right = @_remove node.element, node.right
        else 
            node = if (node.left isnt null) then node.left else node.right
        return node
        
    ###
     * Internal method to find an item in a subtree.
     * @param x is item to search for.
     * @param t the node that roots the tree.
     * @return node containing the matched item.
    ###    
    _find : (x, t)->        
        if t is null
            return null
        if @_compare(x, t.element) < 0
            return @_find x, t.left
        else if @_compare(x, t.element) > 0        
            return @_find x, t.right
        else
            return t
     
    toString : ->
        if(!JSON)
            throw new Error "JSON object is not support in your browser, pleasse download and use json2.js."
        result = []
        @_traverse result, @root
        return JSON.stringify result 
      
    _traverse : (arr, node) ->
        if node isnt null
            @_traverse arr,node.left
            arr.push node.element
            @_traverse arr,node.right
        return



class AvlNode
    constructor : (@element, @left, @right, @height = 0) ->
      
class AvlTree
    constructor : ->
        @root = null

    makeEmpty : ->
        @root = null
        return 

    isEmpty : ->
        return @root is null

    elementAt : (t) ->
        if t is null
            return t
        else
            return t.element  

    insert : (obj) ->
        @root = @_insert obj, @root
        return
        
    remove : (obj)-> 
        @root = @_remove obj, @root
        return
        
    findMin : ->
        return @elementAt(@_findMin(@root))
     
    findMax : ->
        return @elementAt(@_findMax(@root))
    
    find : (x)->
        return @elementAt(@_find(@root))        
        
    _findMin : (t) -> 
        if t is null
            return t
        while t.left isnt null
            t = t.left
        return t    
     
    _findMax : (t) ->  
        if t is null
            return t
        while t.right isnt null
            t = t.right
        return t 
        
    _find : (x, t)->
        while t isnt null
            if @_compare(x, t.element) < 0
                t = t.left
            else if @_compare(x, t.element) > 0        
                t = t.right
            else
                return t 
        return null                       
        
    _compare : (obj, elem)->
        if obj is elem
            return 0    
        else if obj > elem
            return 1
        else
            return -1
  
    _insert : (x, t) ->
        if t is null
            t = new AvlNode x, null, null
        else if @_compare(x, t.element) < 0
            t.left = @_insert x, t.left
            if @_height(t.left) - @_height(t.right) is 2    
                if @_compare(x, t.left.element) < 0
                    t = @_rotateWithLeftChild t
                else
                    t = @_doubleWithLeftChild t
        else if @_compare(x, t.element) > 0
            t.right = @_insert x, t.right
            if @_height(t.right) - @_height(t.left) is 2   
                if @_compare(x, t.right.element) > 0
                    t = @_rotateWithRightChild t
                else
                    t = @_doubleWithRightChild t
            
        t.height = @_max(@_height(t.left), @_height(t.right)) + 1
        return t    
          
    _remove : (x, t) -> 
        if t is null
            return t
        compareResult = @_compare x, t.element
        if compareResult < 0
            t.left = @_remove x, t.left
        else if compareResult > 0
            t.right = @_remove x, t.right
        else if t.left isnt null and t.right isnt null
            t.element = @_findMin(t.right).element
            t.right = @_remove t.element, t.right
        else 
            t = if (t.left isnt null) then t.left else t.right
        return t

    _rotateWithLeftChild : (k2) ->
        k1 = k2.left
        k2.left = k1.right
        k1.right = k2
        k2.height = @_max( @_height( k2.left ), @_height( k2.right ) ) + 1
        k1.height = @_max( @_height( k1.left ), k2.height ) + 1
        return k1
    
    _rotateWithRightChild : (k1) ->
        k2 = k1.right
        k1.right = k2.left
        k2.left = k1
        k1.height = @_max( @_height( k1.left ), @_height( k1.right ) ) + 1
        k2.height = @_max( @_height( k2.right ), k1.height ) + 1
        return k2
        
    _doubleWithLeftChild : (k3) ->
        k3.left = @_rotateWithRightChild( k3.left )
        return @_rotateWithLeftChild( k3 )
    
    _doubleWithRightChild : (k1) ->
        k1.right = @_rotateWithLeftChild( k1.right )
        return @_rotateWithRightChild( k1 )
        
    _max : (lhs, rhs) ->
        return if(lhs > rhs) then lhs else rhs
    
    _height : (t) ->
        return if(t is null) then -1 else t.height
     
    toString : ->
        if(!JSON)
            throw new Error "JSON object is not support in your browser, pleasse download and use json2.js."
        result = []
        @_traverse result, @root
        return JSON.stringify result 
      
    _traverse : (arr, node) ->
        if node isnt null
            @_traverse arr,node.left
            arr.push node.element
            @_traverse arr,node.right
        return    
                          
 
     
class SepareteChainingHashTable
    constructor: (size)->
        if !!size
            @lists = new Array size
        else
            @lists = new Array 101
      
    insert : (obj) ->
        index = @myhash obj
        list = @lists[index]
        if !!list and list.contains
            if !list.contains obj
                list.add obj
        else
            list = new LinkedList()
            list.add obj
            @lists[index] = list
        return    
             
    remove : (obj) ->
        list = @lists[@myhash(obj)]
        if !!list and list.contains
            if list.contains obj
                list.remove obj
                return true
        return false         
   
    contains : (obj) ->
        list = @lists[@myhash(obj)]
        if !!list and list.contains
            return list.contains obj;
        else    
            return false
            
    makeEmpty : ->
        @lists.length = 0 
    
    rehash : ->
      
    myhash : (obj) ->
        hashVal = obj.hashCode()
        hashVal %= @lists.length
        if hashVal < 0
            hashVal += @lists.length
        return hashVal    
      
    nextPrime : (n) ->
      
    isPrime : (n) ->
      
    toString : ->
        if(!JSON)
            throw new Error "JSON object is not support in your browser, pleasse download and use json2.js."
        result = []    
        for item in @lists
            if !!item
                result.push item.toString()                
        return result.join()
   


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值