zoukankan      html  css  js  c++  java
  • hashheap python 实现

    class Node(object):
        """
        the type of class stored in the hashmap, in case there are many same heights
        in the heap, maintain the number
        """
        def __init__(self, id, num):
            self.id = id #id means its id in heap array
            self.num = num #number of same value in this id 处理重复元素
            
    class HashHeap(object):
        def __init__(self, mode):
            self.heap = []
            self.mode = mode
            self.size = 0
            self.hash = {}
        def top(self):
            return self.heap[0] if len(self.heap) > 0 else 0
            
        def isempty(self):
            return len(self.heap) == 0
            
        def _comparesmall(self, a, b): #compare function in different mode
            if a <= b:
                if self.mode == 'min':
                    return True
                else:
                    return False
            else:
                if self.mode == 'min':
                    return False
                else:
                    return True
        def _swap(self, idA, idB): #swap two values in heap, we also need to change
            valA = self.heap[idA]
            valB = self.heap[idB]
            
            numA = self.hash[valA].num
            numB = self.hash[valB].num
            self.hash[valB] = Node(idA, numB)
            self.hash[valA] = Node(idB, numA)
            self.heap[idA], self.heap[idB] = self.heap[idB], self.heap[idA]
        
        def add(self, now):  #the key, height in this place
            self.size += 1
            if self.hash.get(now):
                hashnow = self.hash[now]
                self.hash[now] = Node(hashnow.id, hashnow.num + 1)
            else:
                self.heap.append(now)
                self.hash[now] = Node(len(self.heap) - 1,1)
                self._siftup(len(self.heap) - 1)
                
        def delete(self, now):
            self.size -= 1
            hashnow = self.hash[now]
            id = hashnow.id
            num = hashnow.num
            if num == 1:
                self._swap(id, len(self.heap)-1) #like the common delete operation
                self.hash.pop(now)
                self.heap.pop()
                if len(self.heap) > id:
                    self._siftup(id)
                    self._siftdown(id)
            else:
                self.hash[now] = Node(id, num - 1)
                
        def parent(self, id):
          if id == 0:
            return -1
    
          return (id - 1) / 2
    
        def _siftup(self,id):
            while abs(id -1)/2 < id :  #iterative version
                parentId = (id - 1)/2  #这里非常tricky.
                if self._comparesmall(self.heap[parentId],self.heap[id]):
                    break
                else:
                    self._swap(id, parentId)
                id = parentId
                    
        def _siftdown(self, id): #iterative version
            while 2*id + 1 < len(self.heap):
                l = 2*id + 1
                r = l + 1
                small = id
                if self._comparesmall(self.heap[l], self.heap[id]):
                    small = l
                if r < len(self.heap) and self._comparesmall(self.heap[r], self.heap[small]):
                    small = r
                if small != id:
                    self._swap(id, small)
                else:
                    break
                id = small   

    这个hashheap的实现可以既可以是最大堆,也可以是最小堆,同时因为hash表中存的value是在heap数组中的index和这个key值的数目,所以可以处理重复数字.关键在于siftup和siftdown的非递归实现.siftdown相当于heapify,但是之前只使用过递归版本.

  • 相关阅读:
    epoll精髓【epoll】
    linux下调试core的命令,察看堆栈状态命令 摘录(http://blog.csdn.net/yearn520/article/details/6663265)
    使用epoll 在 linux 上开发高性能应用服务器【epoll】
    linux下epoll如何实现高效处理百万句柄的[转]【epoll】
    log4cplus入门
    非阻塞式服务器和客户端程序(TCP)【简单的原理例子】
    Linux有用的命令记录
    在Linux上的使用开源C++日志库log4cplus
    静态库和动态库的区别
    localtime多线下不安全,localtime_r线程安全
  • 原文地址:https://www.cnblogs.com/sherylwang/p/5652943.html
Copyright © 2011-2022 走看看