【数据结构与算法系列】中级篇:赏析《树结构及其算法》与《常用高层数据结构》(Python版)

《树形结构及其算法》

1.二叉树

深度优先搜索(DFS):前、中、后序遍历

广度优先搜索(BFS):层次遍历

迭代与递归写法

from collections import deque



class TreeNode:
    def __init__(self,data,left=None,right=None):
        self.data=data
        self.left=left
        self.right=right


#迭代:o(n),o(n) n:节点个数
def preOrder(root:TreeNode):
    if root is None:
        return []

    res,stack=[],[]
    stack.append(root)
    while len(stack):
        curr=stack.pop()
        res.append(curr.data)

        if curr.right:
            stack.append(curr.right)
        if curr.left:
            stack.append(curr.left)
    return res

#递归:o(n),o(n)(最好o(nlogn))
def preOrderR(root:TreeNode):
    res=[]

    def preOrder(node):
        if node is None:
            return
        res.append(node.data)
        preOrder(node.left)
        preOrder(node.right)
    preOrder(root)
    return res





#迭代:o(n),o(n) n:节点个数
def inOrder(root:TreeNode):
    if root is None:
        return []

    res,stack=[],[]
    curr=root
    while curr or len(stack):
        while curr:
            stack.append(curr)
            curr=curr.left
        node=stack.pop()
        res.append(node.data)
        curr=node.right
    return res

#递归:o(n),o(n)(最好o(nlogn))
def inOrderR(root:TreeNode):

    res = []

    def inOrder(node):
        if node is None:
            return

        inOrder(node.left)
        res.append(node.data)
        inOrder(node.right)

    inOrder(root)
    return res






#迭代:o(n),o(n) n:节点个数
def postOrder(root:TreeNode):
    if root is None:
        return []

    res,stack=[],[]
    #根->右->左
    stack.append(root)
    while len(stack):
        curr=stack.pop()
        res.append(curr.data)

        if curr.left:
            stack.append(curr.left)
        if curr.right:
            stack.append(curr.right)
    #左->右->根
    res.reverse()
    return res

#递归:o(n),o(n)(最好o(nlogn))
def postOrderR(root:TreeNode):

    res=[]
    def postOrder(node):
        if node is None:
            return []
        postOrder(node.left)
        postOrder(node.right)
        res.append(node.data)

    postOrder(root)
    return res




#方法1(一维数组):o(n),o(n)
def levelOrder_1(root:TreeNode):
    if root is None:
        return []
    #队列queue
    res,queue=[],deque()
    queue.append(root)
    while len(queue):
        #key:每轮循环遍历处理一个节点
        curr=queue.popleft()
        res.append(curr.data)
        #将遍历节点的左右子节点入队
        if curr.left:
            queue.append(curr.left)
        if curr.right:
            queue.append(curr.right)

    return res

#方法2(二维数组):o(n),o(n)
def levelOrder_2(root: TreeNode):
    if root is None:
        return []
    # 队列queue
    res,queue=[],deque()
    queue.append(root)
    while len(queue):
        size,level_nodes=len(queue),[]
        #key:每轮循环遍历处理一层节点
        for i in range(size):
            curr=queue.popleft()
            level_nodes.append(curr.data)
            # 将遍历节点的左右子节点入队
            if curr.left:
                queue.append(curr.left)
            if curr.right:
                queue.append(curr.right)
        res.append(level_nodes)
    return res


if __name__=='__main__':
    root=TreeNode(23)
    node1=TreeNode(34)
    node2=TreeNode(21)
    node3=TreeNode(99)
    node4=TreeNode(77)
    node5=TreeNode(90)
    node6=TreeNode(45)
    node7=TreeNode(60)

    root.left=node1
    root.right=node2
    node1.left=node3
    node3.left=node4
    node3.right=node5
    node2.left = node6
    node2.right = node7

    print(preOrder(root))
    print(preOrderR(root))
    print(inOrder(root))
    print(inOrderR(root))
    print(postOrder(root))
    print(postOrderR(root))
    print(levelOrder_1(root))
    print(levelOrder_2(root))

2.普通二叉查找树

迭代写法

class TreeNode:
    def __init__(self, data, left=None, right=None):
        self.data = data
        self.left = left
        self.right = right


class BST:
    def __init__(self, __comp):
        self.root = None
        self.size = 0
        self.__comp = __comp

    def getSize(self):
        return self.size

    def isEmpty(self):
        return self.size == 0

 # 插入:o(logn)
    def add(self, e):
        if self.root is None:
            self.root = TreeNode(e)
        else:
            curr = self.root
            while curr:
                # 比较
                if self.__comp(e, curr.data) == 0:
                    return
                elif self.__comp(e, curr.data) < 0 and not curr.left:
                    curr.left = TreeNode(e)
                    self.size += 1
                    return
                elif self.__comp(e, curr.data) > 0 and not curr.right:
                    curr.right = TreeNode(e)
                    self.size += 1
                    return
                if self.__comp(e, curr.data) < 0:
                    curr = curr.left
                else:
                    curr = curr.right

# 修改o(logn):set(src,target)会破坏二叉搜索树的顺序

#查询
    def contains(self, target):
        node = self.find(target)
        if not node:
            return False
        return True

    #O(logn)
    def find(self, target):
        if not self.root:
            return None
        curr = self.root
        while curr:
            if self.__comp(target, curr.data) == 0:
                return curr
            elif self.__comp(target, curr.data) < 0:
                curr = curr.left
            else:
                curr = curr.right
        return None

    # 中序遍历:方便观察结果,找bug
    def inOrder(self):
        res = []

        def inOrderR(node):
            if not node:
                return []
            inOrderR(node.left)
            res.append(node.data)
            inOrderR(node.right)

        inOrderR(self.root)
        return res

    #O(logn)
    def minValue(self):
        if not self.root:
            raise Exception("tree is null")
        min_node = self.root
        while min_node.left:
            #最深最左
            min_node = min_node.left
        return min_node.data

    #O(logn)
    def maxValue(self):
        if not self.root:
            raise Exception("tree is null")
        max_node = self.root
        while max_node.right:
            #最深最右
            max_node = max_node.right
        return max_node.data

#删除
    #O(logn)
    def removeMin(self):
        if not self.root:
            raise Exception("tree is null")
        # 找
        min_node, parent = self.root, None
        while min_node.left:
            parent = min_node
            min_node = min_node.left
        #删
        if not parent:
            #位于根节点处
            self.root = self.root.right
        else:
            #key
            parent.left = min_node.right

        min_node.right = None
        self.size -= 1
        return min_node.data

    # 时间复杂度:O(logn)
    def removeMax(self):
        if not self.root:
            raise Exception("tree is null")
        # 找
        max_node, parent = self.root, None
        while max_node.right:
            parent = max_node
            max_node = max_node.right
        #删
        if not parent:
            #位于根节点处
            self.root = self.root.left
        else:
            parent.right = max_node.left

        max_node.left = None
        self.size -= 1
        return max_node.data

    #优化: O(logn)
    def remove_2(self, e):
        if not self.root:
            return
        #找
        curr, parent = self.root, None
        while curr and self.__comp(e, curr.data) != 0:
            parent = curr
            if self.__comp(e, curr.data) < 0:
                curr = curr.left
            else:
                curr = curr.right
        # 如果没有找到需要删除的元素,则直接返回
        if not curr:
            return

        #情况简化
        if curr.left and curr.right:
            #找右子树最小值
            min_node, min_parent = curr.right, curr
            while min_node.left:
                min_parent = min_node
                min_node = min_node.left
            #覆盖该删除节点值
            curr.data = min_node.data
            #curr变为叶子节点:情况则简化成三种
            curr, parent = min_node, min_parent

        #确定开删节点是仅有一个子树节点还是叶子节点
        if curr.left:
            child = curr.left
            #if parent:
                #curr.left = None
        elif curr.right:
            child = curr.right
            #if parent:
                #curr.right = None
        else:
            child = None

        #开删
        if not parent:
            self.root = child
        elif curr == parent.left:
            parent.left = child
        elif curr == parent.right:
            parent.right = child

        self.size -= 1

    #o(logn)
    def remove_1(self, e):
        if not self.root:
            return

        curr, parent = self.root, None
        # 找
        while curr and self.__comp(e, curr.data) != 0:
            parent = curr
            if self.__comp(e, curr.data) < 0:
                curr = curr.left
            else:
                curr = curr.right

        # 如果没有找到需要删除的元素,则直接返回
        if not curr:
            return

        # 删
        if not curr.left and not curr.right:
            if not parent:
                self.root = None
            elif curr == parent.left:
                parent.left = None
            elif curr == parent.right:
                parent.right = None
        elif curr.left and not curr.right:
            if not parent:
                self.root = curr.left
            elif curr == parent.left:
                parent.left = curr.left
                curr.left = None
            elif curr == parent.right:
                parent.right = curr.left
                curr.left = None
        elif not curr.left and curr.right:
            if not parent:
                self.root = curr.right
            elif curr == parent.left:
                parent.left = curr.right
                curr.right = None
            elif curr == parent.right:
                parent.right = curr.right
                curr.right = None
        elif curr.left and curr.right:
            #找右子树最小值
            min_node, min_parent = curr.right, curr
            while min_node.left:
                min_parent = min_node
                min_node = min_node.left

            ##覆盖该删除节点值
            curr.data = min_node.data

            #覆盖该删除节点值
            # 先拿到要删除 min 节点的右子树
            right = min_node.right
            # bug 修复:这里删除 min 节点,需要区分 min 是父亲节点的右子节点还是左子节点
            # 要删除 min 节点是父亲节点的右子节点
            if min_parent.right == min_node:
                """
                比如我们要删除以下树的节点70
                        33
                     /      \
                   22        66
                           /    \
                         35      70
                                   \
                                    99
                那么这个时候:minParent = 66,min = 70,即 min 是父亲节点的右子节点
                """
                # 将 min 的右子树挂到父亲节点的右子树中
                min_parent.right = right
            else:
                # 要删除 min 节点是父亲节点的左子节点
                """
                比如我们要删除以下树的节点68
                        33
                     /      \
                   22        66
                           /    \
                         35      70
                               /   \
                             68     99
                               \
                                69
                那么这个时候:minParent = 70,min = 68,即 min 是父亲节点的左子节点
                """
                # 将 min 的右子树挂到父亲节点的左子树中
                min_parent.left = right
            # 删掉 min 的右子树,这样可以使得 min 节点从树中断开
            min_node.right = None

        self.size -= 1


if __name__ == '__main__':
    # bst = BST(lambda a, b: a - b)
    bst = BST(lambda a, b: a - b)
    bst.add(33)
    bst.add(22)
    bst.add(66)
    bst.add(12)
    bst.add(35)
    bst.add(70)
    bst.add(34)
    bst.add(50)
    bst.add(68)
    bst.add(99)

    print(bst.inOrder())
    print(bst.contains(34))

    print(bst.minValue())
    print(bst.maxValue())

    print(bst.removeMin())
    print(bst.inOrder())

    print(bst.removeMax())
    print(bst.inOrder())

    bst.remove_1(66)
    bst.remove_2(67)
    print(bst.inOrder())

递归写法

class TreeNode:
    def __init__(self, data, left=None, right=None):
        self.data = data
        self.left = left
        self.right = right

class BSTR:
    def __init__(self,__comp):
        self.root=None
        self.size=0
        self.__comp=__comp

    def getsize(self):
        return self.size
    def isEmpty(self):
        return self.size==0



#插入:o(logn)
    def add(self,e):
        self.root=self.addR(self.root,e)
    #将e插入到以node为根节点的子树中
    #返回插入节点后二叉查找树的根节点
    def addR(self,node,e):
        #终止条件
        if not node:
            self.size+=1
            return TreeNode(e)
        #
        if self.__comp(e,node.data)<0:
            node.left=self.addR(node.left,e)
        elif self.__comp(e,node.data)>0:
            node.right=self.addR(node.right,e)
        # e的父亲节点
        return node


#修改:o(logn):set(src,target)会破坏二叉搜索树的顺序



#查询
    def contains(self,target):
        node=self.find(target)
        if not node:
            return False
        return True
    #o(logn)
    def find(self,target):
        return self.findR(self.root,target)
    def findR(self,node,target):
        #
        if not node:
            return
        #
        if self.__comp(target,node.data)==0:
            return node
        elif self.__comp(target,node.data)<0:
            return self.findR(node.left,target)
        elif self.__comp(target,node.data)>0:
            return self.findR(node.right,target)


    def inOrder(self):
        res=[]

        def inOrderR(node):
            if not node:
                return []
            inOrderR(node.left)
            res.append(node.data)
            inOrderR(node.right)
        inOrderR(self.root)
        return res

    #o(logn)
    def minValue(self):
        if not self.root:
            raise Exception('tree is null')
        return self.minValueR(self.root).data
    def minValueR(self,node):
        #
        if not node.left:
            return node
        #
        return self.minValueR(node.left)

    #o(logn)
    def maxValue(self):
        if not self.root:
            raise Exception('tree is null')
        return self.maxValueR(self.root).data
    def maxValueR(self, node):
        #
        if not node.right:
            return node
        #
        return self.maxValueR(node.right)


#删除
    #O(logn)
    def removeMin(self):
        if not self.root:
            raise Exception('tree is null')

        res=self.minValue()
        self.root=self.removeMinR(self.root)
        return res
    #删除以node为根节点的子树的最小节点
    #返回删除完最小节点的子树的根节点
    def removeMinR(self,node):
        #
        if not node.left:
            right_node=node.right
            node.right=None
            self.size-=1
            return right_node
        #
        node.left=self.removeMinR(node.left)
        return node


    def removeMax(self):
        if not self.root:
            raise Exception('tree is null')

        res=self.maxValue()
        self.root=self.removeMaxR(self.root)
        return res
    #删除以node为根节点的子树的最大节点
    #返回删除完最大节点的子树的根节点
    def removeMaxR(self,node):
        #
        if not node.right:
            left_node=node.left
            node.left=None
            self.size-=1
            return left_node
        #
        node.right=self.removeMaxR(node.right)
        return node




    def remove(self,e):
        self.root=self.removeR(self.root,e)
    def removeR(self,node,e):
        if not node:
            return None
        #找
        if self.__comp(e,node.data)<0:
            node.left=self.removeR(node.left,e)
            return node
        elif self.__comp(e,node.data)>0:
            node.right=self.removeR(node.right,e)
            return node
        #删
        else:
            #情况1
            if not node.left:
                right_node = node.right
                node.right = None
                self.size -= 1
                return right_node
            #情况2
            if not node.right:
                left_node = node.left
                node.left = None
                self.size -= 1
                return left_node
            #情况3(node的left和right都不为空):用‘后继节点’替代
            successor=self.minValueR(node.right)
            #key:right->left
            successor.right=self.removeMinR(node.right)
            successor.left=node.left

            node.left=None
            node.right=None
            return successor

if __name__ == '__main__':
    # bst = BST(lambda a, b: a - b)
    bst = BSTR(lambda a, b: a - b)
    bst.add(33)
    bst.add(22)
    bst.add(66)
    bst.add(12)
    bst.add(35)
    bst.add(70)
    bst.add(34)
    bst.add(50)
    bst.add(68)
    bst.add(99)

    print(bst.inOrder())
    print(bst.contains(34))

    print(bst.minValue())
    print(bst.maxValue())

    print(bst.removeMin())
    print(bst.inOrder())

    print(bst.removeMax())
    print(bst.inOrder())

    bst.remove(66)
    print(bst.inOrder())
    bst.remove(68)
    print(bst.inOrder())

3.AVL树


class TreeNode:
    def __init__(self,data,left=None,right=None,height=1):
        self.data=data
        self.left=left
        self.right=right
        self.height=height

class AVLTree:
    def __init__(self,__comp):
        self.root=None
        self.size=0
        self.__comp=__comp

    def getSize(self):
        return self.size
    def isEmpty(self):
        return self.size==0


    def getHeight(self,node):
        if not node:
            return 0
        return node.height
    #平衡因子:左右子节点高度差
    def getBalanceFactor(self,node):
        if not node:
            return 0
        return self.getHeight(node.left)-self.getHeight(node.right)


#二叉树判断:增序排列
    def isBST(self):
        res=self.inOrder()
        #
        if len(res)<=1:
            return True
        #
        for i in range(1,len(res)):
            if self.__comp(res[i],res[i-1])<0:
                return False
        return True
#平衡树判断:
    def isBalanced(self):
        return self.isBalancedR(self.root)
    def isBalancedR(self,node):
        #终止条件
        if not node:
            return True
        #递归下去
        balance_factor=self.getBalanceFactor(node)
        if abs(balance_factor)>1:
            return False
        return self.isBalancedR(node.left) and self.isBalancedR(node.right)


#转变平衡的操作:右旋与左旋
    """
     对节点 y 进行向右旋转操作,返回旋转后新的根节点 x
            y                                    x
           / \                                 /   \
          x   T4        向右旋转 (y)          z       y
         / \          --------------->      / \     / \
        z   T3                            T1   T2 T3   T4
       / \
     T1   T2
    """
    def rightRotate(self,y):
        #中介点
        x=y.left
        t3=x.right
        #旋
        x.right=y
        y.left=t3
        #更新节点高度:先y后x-因为y为子节点
        y.height=max(self.getHeight(y.left),self.getHeight(y.right))+1
        x.height=max(self.getHeight(x.left),self.getHeight(x.right))+1
        #返回调整后的根节点
        return x


    """
     对节点y进行向左旋转操作,返回旋转后新的根节点x
        y                             x
      /  \                          /   \
     T4   x      向左旋转 (y)       y     z
         / \   - - - - - - - ->   / \   / \
       T3  z                     T4 T3 T1 T2
          / \
         T1 T2
    """
    def leftRotate(self,y):
        #中介点
        x=y.right
        t3=x.left
        #旋
        x.left=y
        y.right=t3
        #更新节点高度:先y后x-因为y为子节点
        y.height=max(self.getHeight(y.left),self.getHeight(y.right))+1
        x.height=max(self.getHeight(x.left),self.getHeight(x.right))+1
        #返回调整后的根节点
        return x


#插入:o(logn)
    def add(self,e):
        self.root=self.addR(self.root,e)
    #将节点e插入到以node为根节点的子树中
    #返回此根节点
    def addR(self,node,e):
        #终止条件
        if not node:
            self.size-=1
            return TreeNode(e)
        ####################递归###############################

        if self.__comp(e,node.data)<0:
            node.left=self.addR(node.left,e)
        if self.__comp(e,node.data)>0:
            node.right=self.addR(node.right,e)

        #更新高度
        node.height=max(self.getHeight(node.left),self.getHeight(node.right))+1
        #利用平衡因子判断是否平衡,并根据具体情况(四种),利用旋转规整
        balance_factor=self.getBalanceFactor(node)
        #情况1:LL-左子节点增左子节点e
        if balance_factor>1 and self.getBalanceFactor(node.left)>=0:
            return self.rightRotate(node)
        #情况2:RR-右子节点增右子节点e
        if balance_factor<-1 and self.getBalanceFactor(node.right)<=0:
            return self.leftRotate(node)
        #情况3:LR-左子节点增右子节点e
        if balance_factor>1 and self.getBalanceFactor(node.left)<0:
            #先转LL
            node.left=self.leftRotate(node.left)
            return self.rightRotate(node)
        #情况4:RL-右子节点增左子节点e
        if balance_factor<-1 and self.getBalanceFactor(node.right)>0:
            #先转RR
            node.right=self.rightRotate(node.right)
            return self.leftRotate(node)
        return node




#删除:o(logn)
    def minValueR(self, node):
        if not node.left:
            return node
        return self.minValueR(node.left)
    # 删除以  node 为根节点的子树的最小节点
    # 并返回删除完最小节点的子树的根节点
    def removeMinR(self, node):
        if not node.left:
            right_node = node.right
            node.right = None
            self.size -= 1
            return right_node
        left_node = self.removeMinR(node.left)
        node.left = left_node
        return node

    def remove(self,e):
        self.root=self.removeR(self.root,e)
    def removeR(self,node,e):
        #终
        if not node:
            return None
        #####################递归###############################
        #找
        if self.__comp(e,node.data)<0:
            node.left=self.removeR(node.left,e)
            #方便后续更新节点高度与整平衡
            retNode=node
        elif self.__comp(e,node.data)>0:
            node.right=self.removeR(node.right,e)
            retNode=node
        #删
        else:
            if not node.left:
                right_node=node.right
                node.right=None
                self.size-=1
                retNode=right_node
            elif not node.right:
                left_node=node.left
                node.left=None
                self.size-=1
                retNode=left_node
            else:
                #node的左右子节点都不为空
                #利用后继节点
                successor=self.minValueR(node.right)
                successor.right=self.removeMinR(node.right)
                successor.left=node.left

                node.left=None
                node.right=None
                retNode=successor

            #
            if not retNode:
                return None

        # 更新高度
        retNode.height = max(self.getHeight(retNode.left), self.getHeight(retNode.right)) + 1
        # 利用平衡因子判断是否平衡,并根据具体情况(四种),利用旋转规整
        balance_factor = self.getBalanceFactor(retNode)
        # 情况1:LL-左子节点增左子节点e
        if balance_factor > 1 and self.getBalanceFactor(retNode.left) >= 0:
            return self.rightRotate(retNode)
        # 情况2:RR-右子节点增右子节点e
        if balance_factor < -1 and self.getBalanceFactor(retNode.right) <= 0:
            return self.leftRotate(retNode)
        # 情况3:LR-左子节点增右子节点e
        if balance_factor > 1 and self.getBalanceFactor(retNode.left) < 0:
            # 先转LL
            retNode.left = self.leftRotate(retNode.left)
            return self.rightRotate(retNode)
        # 情况4:RL-右子节点增左子节点e
        if balance_factor < -1 and self.getBalanceFactor(retNode.right) > 0:
            # 先转RR
            retNode.right = self.rightRotate(retNode.right)
            return self.leftRotate(retNode)

        return retNode

    # 中序遍历
    def inOrder(self):
        res = []

        def inOrderR(node):
            if not node:
                return []
            inOrderR(node.left)
            res.append(node.data)
            inOrderR(node.right)

        inOrderR(self.root)
        return res
    
 
if __name__ == '__main__':
    avl = AVLTree(lambda x, y: x - y)

    avl.add(9)
    avl.add(10)
    avl.add(11)
    avl.add(13)

    print(avl.isBST())
    print(avl.isBalanced())

4.对比2-3树与红黑树


BLACK=False
RED=True

class TreeNode:
    def __init__(self,data,left=None,right=None,color=RED):
        self.data=data
        self.left=left
        self.right=right
        #颜色
        self.color=color

class RBST:
    def __init__(self,__comp):
        self.root=None
        self.size=0
        self.__comp=__comp

    def getSize(self):
        return self.size
    def isEmpty(self):
        return self.size==0

    #判断节点颜色
    def isRED(self,node):
        #空节点为黑
        if not node:
            return BLACK
        return node.color

    """
        node                    x
        /  \       左旋转      /   \
       T1   x     ------->  node  T3
           / \              /  \
          T2 T3            T1  T2
    """
    def leftRotate(self,node):
        #中介点
        x=node.right
        t2=x.left
        #左旋
        node.right=t2
        x.left=node
        #转色
        x.color=node.color
        node.color=RED

        return x
    """
        node                    x
        /  \       右旋转      /   \
       x   T2     ------->   y   node
      / \                        /  \
     y  T1                      T1  T2
    """
    def rightRotate(self,node):
        #中介点
        x=node.left
        t1=x.right
        #右旋
        node.left=t1
        x.right=node

        x.color=node.color
        node.color=RED
        return x



    #颜色翻转
    def flipColors(self,node):
        node.color=RED
        node.left.color=BLACK
        node.right.color=BLACK

#插入:o(logn)
    def add(self,e):
        self.root=self.addR(self.root,e)
        #保持根节点为黑
        self.root.color=BLACK
    def addR(self,node,e):
        #终止条件
        if not node:
            self.size+=1
            return TreeNode(e)
        #递归
        if self.__comp(e,node.data)<0:
            node.left=self.addR(node.left,e)
        elif self.__comp(e,node.data)>0:
            node.right=self.addR(node.right,e)
        else:
            return node

        #维护以node为根节点的子树黑平衡
        if self.isRED(node.right) and not self.isRED(node.left):
            node=self.leftRotate(node)
        if self.isRED(node.left) and not self.isRED(node.left.left):
            node=self.rightRotate(node)
        if self.isRED(node.left) and self.isRED(node.right):
            node=self.flipColors(node)

        return node


    # 中序遍历
    def inOrder(self):
        res = []

        def inOrderR(node):
            if not node:
                return []
            inOrderR(node.left)
            res.append(node.data)
            inOrderR(node.right)

        inOrderR(self.root)
        return res

if __name__ == '__main__':
    avl = RBST(lambda x, y: x - y)

    avl.add(9)
    avl.add(10)
    avl.add(11)
    avl.add(13)

    print(avl.inOrder())

《常用高层数据结构》

1.二叉堆

1.1基于单链表实现DataStream

#方法一:
class Node:
    def __init__(self,val,next=None):
        self.val=val
        self.next=next

class DataStream:
    def __init__(self):
        self.dummy_node=Node(-1)

    #o(1)
    def add(self,val):
        new_node=Node(val)
        new_node.next=self.dummy_node.next
        self.dummy_node.next=new_node

    def removeMax(self):
        if not self.dummy_node.next:
            raise Exception('removeMax失败,因为数据流中无元素')
        #遍历链表,找最大值所在节点
        curr=self.dummy_node.next
        max_value_node=curr
        while curr:
            if curr.val>max_value_node.val:
                max_value_node=curr
            curr=curr.next
        #找最大值节点的前一个节点
        curr,max_value_node_prev=self.dummy_node.next,self.dummy_node
        while curr:
            if curr==max_value_node:
                break
            max_value_node_prev=curr
            curr=curr.next
        #删除
        max_value_node_prev.next=max_value_node.next
        max_value_node.next=None

        return max_value_node.val

if __name__=='__main__':
    ds=DataStream()
    ds.add(3)
    print(ds.removeMax())#3
    ds.add(6)
    ds.add(5)
    print(ds.removeMax())#6
    ds.add(2)
    ds.add(1)
    print(ds.removeMax())#5
#方法二:
class Node:
    def __init__(self,val,next=None):
        self.val=val
        self.next=next

class DataStream:
    def __init__(self):
        self.dummy_node=Node(-1)

    #o(1):按头节点值最大存储规则
    def add(self, val):
        #找:第一个比val小的节点
        prev,curr=self.dummy_node,self.dummy_node.next
        while curr:
            if curr.val<val:
                break
            prev=curr
            curr=curr.next
        #将元素添加至该节点前面
        new_node=Node(val,curr)
        prev.next=new_node

    #o(1)
    def removeMax(self):
        if not self.dummy_node.next:
            raise Exception('removeMax失败,因为数据流中无元素')
        #保存需要返回的最大值(头节点值)
        res=self.dummy_node.next.val
        #删除(头节点)
        head=self.dummy_node.next
        self.dummy_node.next=head.next
        head.next=None

        return res


if __name__=='__main__':
    ds=DataStream()
    ds.add(3)
    print(ds.removeMax())#3
    ds.add(6)
    ds.add(5)
    print(ds.removeMax())#6
    ds.add(2)
    ds.add(1)
    print(ds.removeMax())#5

1.2基于二叉堆实现DataStream

class MaxHeap:
    def __init__(self,__comp,data=None):
        self.__comp=__comp
        if not data:
            self.data=[]
        else:
            self.data=data[:]
            for i in range(self.lastNonLeafIndex(),-1,-1):
                self.siftDown(i)

    def size(self):
        return len(self.data)
    def isEmpty(self):
        return len(self.data)==0

    #左孩子节点索引
    def leftChild(self,index):
        return index*2+1
    #右孩子节点索引
    def rightChild(self,index):
        return index*2+2
    #父节点索引
    def parent(self,index):
        if index==0:
            raise Exception('index-0 does not have parent')
        return (index-1)//2

    #最后一个父节点:最后一个叶子结点的父节点
    def lastNonLeafIndex(self):
        #最后一个叶子节点索引
        last_leaf_index=len(self.data)-1
        #转化
        return self.parent(last_leaf_index)

    #上浮保持完全二叉树
    def siftUp(self,index):
        e=self.data[index]

        while index>0:
            parent_node_val=self.data[self.parent(index)]
        #循环比较:小值通过赋值下浮
            if self.__comp(e,parent_node_val)<=0:
                break
            self.data[index]=parent_node_val
            index=self.parent(index)
        #最后’index’处进行赋值
        self.data[index]=e

    #下浮保持完全二叉树
    def siftDown(self,index):
        e=self.data[index]
        while self.leftChild(index)<len(self.data):
            #寻左右子节点中最大值节点
            max_node_index=self.leftChild(index)
            if self.rightChild(index)<len(self.data):
                right_node_val=self.data[self.rightChild(index)]
                left_node_val=self.data[self.leftChild(index)]
                if self.__comp(right_node_val,left_node_val)>0:
                    max_node_index=self.rightChild(index)
        # 循环比较:大值通过赋值上浮
            if self.__comp(e,self.data[max_node_index])>=0:
                break
            self.data[index]=self.data[max_node_index]
            index=max_node_index
        # 最后’index’处进行赋值
        self.data[index]=e


    #o(logn)
    def add(self,e):
        self.data.append(e)
        self.siftUp(len(self.data)-1)



    def findMax(self):
        if self.isEmpty():
            raise Exception('Heap is Empty')
        return self.data[0]
    #o(logn)
    def removeMax(self):
        max_val=self.findMax()
        #最后节点替换为头节点,并删除
        last=self.data[len(self.data)-1]
        self.data[0]=last
        self.data.pop()
        #通过下沉恢复成大顶堆
        if len(self.data)>=1:
            self.siftDown(0)

        return max_val

class DataStream:
    def __init__(self, __comp):
        self.maxHeap = MaxHeap(__comp)

    # 时间复杂度:O(logn)
    def add(self, val):
        self.maxHeap.add(val)

    # O(logn)
    def removeMax(self):
        return self.maxHeap.removeMax()


def sort(data):
    # 1. 建堆,堆化 O(n)
    max_heap = MaxHeap(lambda a, b: a - b, data)

    # 2. 排序
    i, tmp = len(data) - 1, [0] * len(data)

    # O(nlogn)
    while not max_heap.isEmpty():
        tmp[i] = max_heap.removeMax()
        i -= 1

    # 3. 拷贝
    for i in range(len(data)):
        data[i] = tmp[i]

if __name__ == '__main__':
    ds = DataStream(lambda a, b: a - b)
    ds.add(3)
    print(ds.removeMax())  # 打印 3
    ds.add(6)
    ds.add(5)
    print(ds.removeMax())  # 打印 6
    ds.add(2)
    ds.add(1)
    print(ds.removeMax())  # 打印 5
    
    #HeapSort
    data = [15, 17, 19, 13, 22, 16, 28, 30, 42, 66]
    sort(data)
    print(data)

1.3基于二叉堆实现优先队列

在这里插入图片描述

class MaxHeap:
    def __init__(self,__comp,data=None):
        self.__comp=__comp
        if not data:
            self.data=[]
        else:
            self.data=data[:]
            for i in range(self.lastNonLeafIndex(),-1,-1):
                self.siftDown(i)

    def size(self):
        return len(self.data)
    def isEmpty(self):
        return len(self.data)==0

    #左孩子节点索引
    def leftChild(self,index):
        return index*2+1
    #右孩子节点索引
    def rightChild(self,index):
        return index*2+2
    #父节点索引
    def parent(self,index):
        if index==0:
            raise Exception('index-0 does not have parent')
        return (index-1)//2

    #最后一个父节点:最后一个叶子结点的父节点
    def lastNonLeafIndex(self):
        #最后一个叶子节点索引
        last_leaf_index=len(self.data)-1
        #转化
        return self.parent(last_leaf_index)

    #上浮保持完全二叉树
    def siftUp(self,index):
        e=self.data[index]

        while index>0:
            parent_node_val=self.data[self.parent(index)]
        #循环比较:小值通过赋值下浮
            if self.__comp(e,parent_node_val)<=0:
                break
            self.data[index]=parent_node_val
            index=self.parent(index)
        #最后’index’处进行赋值
        self.data[index]=e

    #下浮保持完全二叉树
    def siftDown(self,index):
        e=self.data[index]
        while self.leftChild(index)<len(self.data):
            #寻左右子节点中最大值节点
            max_node_index=self.leftChild(index)
            if self.rightChild(index)<len(self.data):
                right_node_val=self.data[self.rightChild(index)]
                left_node_val=self.data[self.leftChild(index)]
                if self.__comp(right_node_val,left_node_val)>0:
                    max_node_index=self.rightChild(index)
        # 循环比较:大值通过赋值上浮
            if self.__comp(e,self.data[max_node_index])>=0:
                break
            self.data[index]=self.data[max_node_index]
            index=max_node_index
        # 最后’index’处进行赋值
        self.data[index]=e


    #o(logn)
    def add(self,e):
        self.data.append(e)
        self.siftUp(len(self.data)-1)



    def findMax(self):
        if self.isEmpty():
            raise Exception('Heap is Empty')
        return self.data[0]
    #o(logn)
    def removeMax(self):
        max_val=self.findMax()
        #最后节点替换为头节点,并删除
        last=self.data[len(self.data)-1]
        self.data[0]=last
        self.data.pop()
        #通过下沉恢复成大顶堆
        if len(self.data)>=1:
            self.siftDown(0)

        return max_val



class PriorityQueue:
    def __init__(self,__comp):
        self.maxHeap=MaxHeap(__comp)

    def getsize(self):
        return self.maxHeap.size()
    def isEmpty(self):
        return self.maxHeap.isEmpty()

    def enqueue(self,e):
        self.maxHeap.add(e)
    def dequeue(self):
        return self.maxHeap.removeMax()

    def getFront(self):
        return self.maxHeap.findMax()

if __name__ == '__main__':
    ds = PriorityQueue(lambda a, b: a - b)
    ds.enqueue(3)
    print(ds.dequeue())  # 打印 3
    ds.enqueue(6)
    ds.enqueue(5)
    print(ds.dequeue())  # 打印 6
    ds.enqueue(2)
    ds.enqueue(1)
    print(ds.dequeue())  # 打印 5

2.Set

2.1数组set

class ArraySet:
    def __init__(self):
        self.data=[]

    def size(self):
        return len(self.data)
    def isEmpty(self):
        return len(self.data)==0

    #o(1)
    def add(self,e):
        if self.data.count(e)==0:
            self.data.append(e)
    def remove(self,e):
        if self.data.count(e)>0:
            self.data.remove(e)

    def contain(self,e):
        return self.data.count(e)>0

    def toString(self):
        return "ArraySet[ data = {} ]".format(self.data)


if __name__=='__main__':
    set1=ArraySet()
    set1.add(2)
    set1.add(4)
    set1.add(1)
    print(set1.toString())

    set1.add(2)
    print(set1.toString())

    print(set1.contain(4))

    set1.remove(1)
    print(set1.toString())

2.2链表set

class Node:
    def __init__(self, e, next=None):
        self.e = e
        self.next = next

    def toString(self):
        return str(self.e)


class LinkedList:
    def __init__(self):
        self.dummyHead = Node(-1)
        self.size = 0

    def getSize(self):
        return self.size

    def isEmpty(self):
        return self.size == 0

    """
        查询操作
    """
    # 查询指定索引的节点的值
    # 时间复杂度: O(n)
    def get(self, index):
        if index < 0 or index >= self.getSize():
            raise Exception("get failed, require index >= 0 && index < size")

        curr = self.dummyHead.next
        for i in range(0, index):
            curr = curr.next

        return curr.e

    # 时间复杂度: O(1)
    def getFirst(self):
        return self.get(0)

    def getLast(self):
        return self.get(self.size - 1)

    """
        修改操作
    """
    # 修改指定索引的节点元素
    # 时间复杂度: O(n)
    def set(self, index, e):
        if index < 0 or index >= self.getSize():
            raise Exception("set failed, require index >= 0 && index < size")

        curr = self.dummyHead.next
        for i in range(0, index):
            curr = curr.next

        curr.e = e

    """
        新增操作
    """
    # 在指定索引的位置插入新的节点
    # 时间复杂度: O(n)
    def add(self, index, e):
        if index < 0 or index > self.getSize():
            raise Exception("add failed, require index >= 0 && index < size")

        prev = self.dummyHead
        for i in range(0, index):
            prev = prev.next

        prev.next = Node(e, prev.next)
        self.size += 1

    # 在链表表头新增节点
    # 时间复杂度: O(1)
    def addFirst(self, e):
        self.add(0, e)

    # 在链表表尾新增节点
    # 时间复杂度: O(n)
    def addLast(self, e):
        self.add(self.size, e)

    """
        删除操作
    """
    # 删除指定索引的节点,并返回删除的节点的值
    # 时间复杂度: O(n)
    def remove(self, index):
        if index < 0 or index >= self.getSize():
            raise Exception("remove failed, require index >= 0 && index < size")

        prev = self.dummyHead
        for i in range(0, index):
            prev = prev.next

        del_node = prev.next
        prev.next = del_node.next
        del_node.next = None

        self.size -= 1
        return del_node.e

    # 时间复杂度: O(1)
    def removeFirst(self):
        return self.remove(0)

    # 时间复杂度: O(n)
    def removeLast(self):
        return self.remove(self.size - 1)

    # 删除第一个值等于 e 的节点
    # 时间复杂度: O(n)
    def removeElement(self, e):
        if self.dummyHead.next is None:
            raise Exception("removeElement failed, LinkedList is Empty")
        prev, curr = self.dummyHead, self.dummyHead.next
        while curr:
            if curr.e == e:
                break
            prev = curr
            curr = curr.next
        # bug 修复,需要先判断 curr
        # 如果 curr 为 None 的话,说明链表中不存在值等于 e 的节点
        if curr:
            prev.next = curr.next
            curr.next = None

    # 判断链表中是否存在指定元素
    # 时间复杂度: O(n)
    def contains(self, e):
        curr = self.dummyHead.next
        while curr:
            if curr.e == e:
                return True
            curr = curr.next
        return False

    def toString(self):
        res = ""
        curr = self.dummyHead.next
        while curr:
            res += curr.toString() + "=>"
            curr = curr.next
        res += "null"
        return res


class LinkedListSet:
    def __init__(self):
        self.data=LinkedList()

    def size(self):
        return self.data.getSize()
    def isEmpty(self):
        return self.data.isEmpty()

    def add(self,e):
        if not self.data.contains(e):
            self.data.addFirst(e)
    def remove(self,e):
        if self.data.contains(e):
            self.data.removeElement(e)

    def contains(self,e):
        return self.data.contains(e)


    def toString(self):
        return 'LinkedListSet[ data={} ]'.format(self.data.toString())


if __name__ == '__main__':
    set1 = LinkedListSet()
    set1.add(2)
    set1.add(4)
    set1.add(1)

    print(set1.toString())

    set1.add(2)
    print(set1.toString())

    print(set1.contains(4))

    set1.remove(1)
    print(set1.toString())

2.3二叉搜索树set

class TreeNode:
    def __init__(self, data, left=None, right=None):
        self.data = data
        self.left = left
        self.right = right


class BST:
    def __init__(self, __comp):
        self.root = None
        self.size = 0
        self.__comp = __comp

    def getSize(self):
        return self.size

    def isEmpty(self):
        return self.size == 0

 # 插入:o(logn)
    def add(self, e):
        if self.root is None:
            self.root = TreeNode(e)
        else:
            curr = self.root
            while curr:
                # 比较
                if self.__comp(e, curr.data) == 0:
                    return
                elif self.__comp(e, curr.data) < 0 and not curr.left:
                    curr.left = TreeNode(e)
                    self.size += 1
                    return
                elif self.__comp(e, curr.data) > 0 and not curr.right:
                    curr.right = TreeNode(e)
                    self.size += 1
                    return
                if self.__comp(e, curr.data) < 0:
                    curr = curr.left
                else:
                    curr = curr.right

# 修改o(logn):set(src,target)会破坏二叉搜索树的顺序

#查询
    def contains(self, target):
        node = self.find(target)
        if not node:
            return False
        return True

    #O(logn)
    def find(self, target):
        if not self.root:
            return None
        curr = self.root
        while curr:
            if self.__comp(target, curr.data) == 0:
                return curr
            elif self.__comp(target, curr.data) < 0:
                curr = curr.left
            else:
                curr = curr.right
        return None

    # 中序遍历:方便观察结果,找bug
    def inOrder(self):
        res = []

        def inOrderR(node):
            if not node:
                return []
            inOrderR(node.left)
            res.append(node.data)
            inOrderR(node.right)

        inOrderR(self.root)
        return res

    #O(logn)
    def minValue(self):
        if not self.root:
            raise Exception("tree is null")
        min_node = self.root
        while min_node.left:
            #最深最左
            min_node = min_node.left
        return min_node.data

    #O(logn)
    def maxValue(self):
        if not self.root:
            raise Exception("tree is null")
        max_node = self.root
        while max_node.right:
            #最深最右
            max_node = max_node.right
        return max_node.data

#删除
    #O(logn)
    def removeMin(self):
        if not self.root:
            raise Exception("tree is null")
        # 找
        min_node, parent = self.root, None
        while min_node.left:
            parent = min_node
            min_node = min_node.left
        #删
        if not parent:
            #位于根节点处
            self.root = self.root.right
        else:
            #key
            parent.left = min_node.right

        min_node.right = None
        self.size -= 1
        return min_node.data

    # 时间复杂度:O(logn)
    def removeMax(self):
        if not self.root:
            raise Exception("tree is null")
        # 找
        max_node, parent = self.root, None
        while max_node.right:
            parent = max_node
            max_node = max_node.right
        #删
        if not parent:
            #位于根节点处
            self.root = self.root.left
        else:
            parent.right = max_node.left

        max_node.left = None
        self.size -= 1
        return max_node.data

    #优化: O(logn)
    def remove_2(self, e):
        if not self.root:
            return
        #找
        curr, parent = self.root, None
        while curr and self.__comp(e, curr.data) != 0:
            parent = curr
            if self.__comp(e, curr.data) < 0:
                curr = curr.left
            else:
                curr = curr.right
        # 如果没有找到需要删除的元素,则直接返回
        if not curr:
            return

        #情况简化
        if curr.left and curr.right:
            #找右子树最小值
            min_node, min_parent = curr.right, curr
            while min_node.left:
                min_parent = min_node
                min_node = min_node.left
            #覆盖该删除节点值
            curr.data = min_node.data
            #curr变为叶子节点:情况则简化成三种
            curr, parent = min_node, min_parent

        #确定开删节点是仅有一个子树节点还是叶子节点
        if curr.left:
            child = curr.left
            # if parent:
            #     curr.left = None
        elif curr.right:
            child = curr.right
            # if parent:
            #     curr.right = None
        else:
            child = None

        #开删
        if not parent:
            self.root = child
        elif curr == parent.left:
            parent.left = child
        elif curr == parent.right:
            parent.right = child

        self.size -= 1

    #o(logn)
    def remove_1(self, e):
        if not self.root:
            return

        curr, parent = self.root, None
        # 找
        while curr and self.__comp(e, curr.data) != 0:
            parent = curr
            if self.__comp(e, curr.data) < 0:
                curr = curr.left
            else:
                curr = curr.right

        # 如果没有找到需要删除的元素,则直接返回
        if not curr:
            return

        # 删
        if not curr.left and not curr.right:
            if not parent:
                self.root = None
            elif curr == parent.left:
                parent.left = None
            elif curr == parent.right:
                parent.right = None
        elif curr.left and not curr.right:
            if not parent:
                self.root = curr.left
            elif curr == parent.left:
                parent.left = curr.left
                curr.left = None
            elif curr == parent.right:
                parent.right = curr.left
                curr.left = None
        elif not curr.left and curr.right:
            if not parent:
                self.root = curr.right
            elif curr == parent.left:
                parent.left = curr.right
                curr.right = None
            elif curr == parent.right:
                parent.right = curr.right
                curr.right = None
        elif curr.left and curr.right:
            #找右子树最小值
            min_node, min_parent = curr.right, curr
            while min_node.left:
                min_parent = min_node
                min_node = min_node.left

            ##覆盖该删除节点值
            curr.data = min_node.data

            #覆盖该删除节点值
            # 先拿到要删除 min 节点的右子树
            right = min_node.right
            # bug 修复:这里删除 min 节点,需要区分 min 是父亲节点的右子节点还是左子节点
            # 要删除 min 节点是父亲节点的右子节点
            if min_parent.right == min_node:
                """
                比如我们要删除以下树的节点70
                        33
                     /      \
                   22        66
                           /    \
                         35      70
                                   \
                                    99
                那么这个时候:minParent = 66,min = 70,即 min 是父亲节点的右子节点
                """
                # 将 min 的右子树挂到父亲节点的右子树中
                min_parent.right = right
            else:
                # 要删除 min 节点是父亲节点的左子节点
                """
                比如我们要删除以下树的节点68
                        33
                     /      \
                   22        66
                           /    \
                         35      70
                               /   \
                             68     99
                               \
                                69
                那么这个时候:minParent = 70,min = 68,即 min 是父亲节点的左子节点
                """
                # 将 min 的右子树挂到父亲节点的左子树中
                min_parent.left = right
            # 删掉 min 的右子树,这样可以使得 min 节点从树中断开
            min_node.right = None

        self.size -= 1

class BSTSet:
    def __init__(self, __comp):
        self.bst = BST(__comp)

    def size(self):
        return self.bst.getSize()

    def isEmpty(self):
        return self.bst.isEmpty()

    def add(self, e):
        self.bst.add(e)

    def remove(self, e):
        self.bst.remove_1(e)

    def contains(self, e):
        return self.bst.contains(e)

    def toString(self):
        return "BSTSet[ data = {} ]".format(self.bst.inOrder())


if __name__ == '__main__':
    set1 = BSTSet(lambda a, b: a - b)
    set1.add(2)
    set1.add(4)
    set1.add(1)

    print(set1.toString())

    set1.add(2)
    print(set1.toString())

    print(set1.contains(4))

    set1.remove(1)
    print(set1.toString())

2.4HashSet

#基本实现

class HashSet:
    def __init__(self,__hash):
        self.data=[None]*10
        self.__size=0
        self.__hash=__hash

    #e对应hash值
    def hash(self,e,length):
        return abs(self.__hash(e))%length

    def size(self):
        return self.__size
    def isEmpty(self):
        return self.__size==0

    def add(self,e):
        index=self.hash(e,len(self.data))
        if not self.data[index]:
            self.data[index]=e
            self.__size+=1
            #扩容
            if self.__size==len(self.data):
                self.resize(2*len(self.data))
    def resize(self,newCapacity):
        new_data=[None]*newCapacity
        for i in range(len(self.data)):
            if self.data[i]:
                new_index=self.hash(self.data[i],newCapacity)
                new_data[new_index]=self.data[i]
            self.data=new_data


    def remove(self,e):
        index=self.hash(e,len(self.data))
        if self.data[index]:
            self.data[index]=None
            self.__size-=1


    def contains(self,e):
        index=self.hash(e,len(self.data))
        return self.data[index]!=None

    def toString(self):
        return 'HashSet [data = {} ]'.format(self.data)

if __name__ == '__main__':
    set1 = HashSet(lambda a: a)
    set1.add(2)
    set1.add(4)
    set1.add(1)

    print(set1.toString())

    set1.add(2)
    print(set1.toString())

    print(set1.contains(4))

    set1.remove(1)
    print(set1.toString())

#解决Hash冲突:基于开放寻址

class Item:
    def __init__(self,data):
        self.data=data
        self.is_deleted=False

    def toString(self):
        return str(self.data)



class HashSet:
    def __init__(self,__hash,__equal):
        self.items=[None]*10
        self.__size=0
        self.__hash=__hash
        self.__equal=__equal

        #记录删除元素个数
        self.delete_count=0
        #扩展因子
        self.loadFactor=0.75

    def hash(self,e,length):
        return abs(self.__hash(e))%length

    def size(self):
        return self.__size
    def isEmpty(self):
        return self.__size==0



    def add(self,e):
        index=self.hash(e,len(self.items))
#若已存在且为e,直接返回
        if self.items[index] and self.__equal(e, self.items[index]):
            return

# 辅助变量
        add_index,is_first=index,True
        #找:等于null或已删除的第一个元素
        while self.items[index] and not self.items[index].is_deleted:
            if (not self.items[index] or self.items[index].is_deleted) and is_first:
                add_index,is_first=index,False
            index+=1
            index=index%len(self.items)

#找到:add_index为null或已删除元素
        #若为已删除元素,通过add后,count-=1
        if self.items[add_index] and self.items[add_index].is_deleted:
            self.delete_count-=1
        #
        self.items[add_index] = Item(e)
        self.__size += 1

#扩容
        if self.__size>=len(self.items)*self.loadFactor:
            self.resize(2*len(self.items))

    def resize(self,newCapacity):
        new_data=[None]*newCapacity
        for i in range(len(self.items)):
            if self.items[i] and not self.items[i].is_deleted:
                new_index=self.hash(self.items[i],newCapacity)
                new_data[new_index]=self.items[i]
            self.items=new_data
            #清理标记删除元素
            self.delete_count=0


    def remove(self,e):
        index=self.hash(e,len(self.items))
#找:等于e或null的元素
        while self.items[index] and not self.__equal(e,self.items[index].data):
            index+=1
            index=index%len(self.items)
        if self.items[index]:
            self.items[index].is_deleted=True
            self.__size-=1
            self.delete_count+=1
#删除标记太多,缩容
        if self.delete_count+self.__size>=len(self.items)*self.loadFactor:
            self.resize(len(self.items))




    def contains(self,e):
        index=self.hash(e,len(self.items))
        #找
        while self.items[index] and not self.__equal(e,self.items[index].data):
            index+=1
            index=index%len(self.items)
        #找到
        return self.items[index] and not self.items[index].is_deleted

    def toString(self):
        res=''
        for data in self.items:
            if data and not data.is_deleted:
                res+=data.toString()+','
        return res

if __name__=='__main__':
    set1 = HashSet(lambda a: a, lambda a, b: a == b)
    set1.add(2)
    set1.add(4)
    set1.add(1)

    print(set1.toString())

    set1.add(2)
    print(set1.toString())

    print(set1.contains(4))

    set1.remove(1)
    print(set1.toString())

        #找到

#解决Hash冲突:基于链表:

class Node:
    def __init__(self,val,next=None):
        self.val=val
        self.next=next

    def toString(self):
        return str(self.val)


class HashSet:
    def __init__(self,__hash,__equal):
        self.data=[None]*10
        self.__size=0
        self.__hash=__hash
        self.__equal=__equal
        self.loadFactor=0.75

    def hash(self,e,length):
        return abs(self.__hash(e))%length

    def size(self):
        return self.__size
    def isEmpty(self):
        return self.__size==0



    def add(self,e):
        index=self.hash(e,len(self.data))
        #
        if not self.data[index]:
            self.data[index]=Node(e)
            self.__size+=1
        #
        prev,curr=None,self.data[index]
        while curr:
            if self.__equal(e,curr.val):
                return
            prev=curr
            curr=curr.next
        prev.next=Node(e)
        self.__size+=1
        #扩容
        if self.__size==len(self.data)*self.loadFactor:
            self.resize(2*len(self.data))
    def resize(self,newCapacity):
        new_data=[None]*newCapacity
        for i in range(len(self.data)):
            curr=self.data[i]
            while curr:
                e=curr.val
                new_index = self.hash(e, newCapacity)
                # 通过数组属性,定位
                head = new_data[new_index]

                # 通过链表属性,扩链
                if not head:
                    new_data[new_index] = Node(e)
                else:
                    new_data[new_index] = Node(e)
                    new_data[new_index].next = head
                curr = curr.next
        self.data=new_data


    def remove(self,e):
        index=self.hash(e,len(self.data))
        #
        if not self.data[index]:
            return
        #
        prev,curr=None,self.data[index]
        while curr:
            if self.__equal(e,curr.val):
                if not prev:
                    #e为头节点
                    self.data[index]=curr.next
                else:
                    prev.next=curr.next
                    curr.next=None
                self.__size-=1
                break
            prev=curr
            curr=curr.next

    def contains(self,e):
        index=self.hash(e,len(self.data))
        if not self.data[index]:
            return False

        curr=self.data[index]
        while curr:
            if self.__equal(e,curr.val):
                return True
            curr=curr.next
        return False

    def toString(self):
        res=''
        for node in self.data:
            while node:
                res+=node.toString()+'=>'
                node=node.next
        return res


if __name__ == '__main__':
    set1 = HashSet(lambda a: a, lambda a, b: a == b)
    set1.add(2)
    set1.add(4)
    set1.add(1)

    print(set1.toString())

    set1.add(2)
    print(set1.toString())

    print(set1.contains(4))

    set1.remove(1)
    print(set1.toString())

3.Map

#链表Map

class Node:
    def __init__(self,key=None,value=None,next=None):
        self.key=key
        self.value=value
        self.next=next

    def toString(self):
        return str(self.key)+'->'+str(self.value)


class LinkedListMap:
    def __init__(self,__equal):
        self.dummyHead=Node()
        self.__size=0
        self.__equal=__equal

    def size(self):
        return self.__size
    def isEmpty(self):
        return self.__size==0


    def add(self,key,value):
        curr=self.getNode(key)
        #
        if not curr:
            self.dummyHead.next=Node(key,value,self.dummyHead.next)
            self.__size+=1
        else:
            curr.value=value
    def getNode(self,key):
        curr=self.dummyHead.next
        while curr:
            if self.__equal(key,curr.key):
                break
            curr=curr.next
        return curr





    def remove(self,key):
        #定位
        prev,curr=self.dummyHead,self.dummyHead.next
        while curr:
            if self.__equal(key,curr.key):
                break
            prev=curr
            curr=curr.next
        #删
        if curr:
            prev.next=curr.next
            curr.next=None
            self.__size-=1
            return curr.value
        return None



    def set(self,key,new_value):
        curr=self.getNode(key)
        if curr:
            curr.value=new_value
        else:
            raise Exception('没有对应的key:{}'.format(key))
    def get(self,key):
        node=self.getNode(key)
        return node.value if node else None
    def containsKey(self,key):
        node=self.getNode(key)
        return node!=None

#二叉搜索树Map

class TreeNode:
    def __init__(self,key,value,left=None,right=None):
        self.key=key
        self.value=value
        self.left=left
        self.right=right

class BSTMap:
    def __init__(self,__comp):
        self.root=None
        self.__size=0
        self.__comp=__comp

    def size(self):
        return self.__size
    def isEmpty(self):
        return self.__size==0


    #o(logn)
    def add(self,key,value):
        self.root=self.addR(self.root,key,value)
    def addR(self,node,key,value):
        #终止条件
        if not node:
            self.__size+=1
            return TreeNode(key,value)

        #递归
        if self.__comp(key,node.key)<0:
            node.left=self.addR(node.left,key,value)
        elif self.__comp(key,node.key)>0:
            node.right=self.addR(node.right,key,value)
        return node


    #o(logn)
    def remove(self,key):
        node=self.getR(self.root,key)
        #
        if not node:
            return None
        #
        if self.__comp(key,node.key)<0:
            node.left=self.removeR(node.left,key)
            return node
        elif self.__comp(key,node.key)>0:
            node.right=self.removeR(node.right,key)
        else:
            #找到:删除节点为node
            #情况一
            if not node.left:
                #
                right_node=node.right
                #
                node.right=None
                self.__size-=1
                return right_node
            #情况2
            if not node.right:
                #
                left_node=node.left
                #
                node.left=None
                self.__size-=1
                return left_node
            #情况3
            successor=self.minValueR(node.right)
                #注意次序
            successor.right=self.removeMinR(node.right)
            successor.left=node.left

            node.left=None
            node.right=None
            return successor


    def minValueR(self, node):
        if not node.left:
            return node
        return self.minValueR(node.left)
    # 删除以  node 为根节点的子树的最小节点
    # 并返回删除完最小节点的子树的根节点
    def removeMinR(self, node):
        if not node.left:
            right_node = node.right
            node.right = None
            self.size -= 1
            return right_node
        left_root = self.removeMinR(node.left)
        node.left = left_root
        return node





    def set(self,key,new_value):
        node=self.getR(self.root,key)
        #
        if not node:
            raise Exception('没有对应的key:{}'.format(key))
        #
        node.value=new_value

    def get(self,key):
        node=self.getR(self.root,key)
        return node.value if node else None
    def getR(self,node,key):
        if not node:
            return None

        if self.__comp(key,node.key)==0:
            return node
        elif self.__comp(key,node.key)<0:
            return self.getR(node.left,key)
        else:
            return self.getR(node.right,key)

    def contains(self,key):
        node=self.getR(self.root,key)
        return node!=None

#HashMap

class Node:
    def __init__(self,key=None,value=None,next=None):
        self.key=key
        self.value=value
        self.next=next

    def toString(self):
        return str(self.key)+'->'+str(self.value)

class HashMap:
    def __init__(self,__hash,__equal,initCapacity=25,loadFactor=0.75):
        self.data=[None]*initCapacity
        self.__size=0
        self.__hash=__hash
        self.__equal=__equal
        self.loadFactor=loadFactor

    #key->索引
    def hash(self,key,length):
        return abs(self.__hash(key))%length

    def size(self):
        return self.__size
    def isEmpty(self):
        return self.__size

    def add(self,key,value):
        #目:'数组'属性位置
        index=self.hash(key,len(self.data))
        #目:链表属性位置
        curr=self.getNode(key,index)

        if not curr:
            self.data[index]=Node(key,value,self.data[index])
            self.__size+=1
            #扩容
            if self.__size>=len(self.data)*self.loadFactor:
                self.resize(2*len(self.data))
        else:
            curr.value=value
    def getNode(self,key,index):
        curr=self.data[index]
        while curr:
            if self.__equal(key,curr.key):
                break
            curr=curr.next
        return curr
    def resize(self,new_capacity):
        new_data=[None]*new_capacity
        for i in range(len(self.data)):
            curr=self.data[i]
            while curr:
                #'数组'属性定位
                key=curr.key
                new_index=self.hash(key,new_capacity)
                head=new_data[new_index]
                #链表属性扩容
                if not head:
                    new_data[new_index] = Node(key, curr.value)
                else:
                    new_data[new_index] = Node(key, curr.value)
                    new_data[new_index].next=head
                curr=curr.next
        self.data=new_data




    def remove(self,key):
        index=self.hash(key,len(self.data))
        #
        if not self.data[index]:
            return None
        #
        prev,curr=None,self.data[index]
        while curr:
            if self.__equal(key,curr.key):
                #删头
                if not prev:
                    self.data[index]=curr.next
                else:
                    prev.next=curr.next
                curr.next=None
                self.__size -= 1
                return curr.value
            prev=curr
            curr=curr.next
        return None






    def set(self,key,new_value):
        index=self.hash(key,len(self.data))
        node=self.getNode(key,index)
        if node:
            node.value=new_value
        else:
            raise Exception("没有对应的 key :{}".format(key))
    def get(self,key):
        index = self.hash(key, len(self.data))
        node = self.getNode(key, index)
        return node.value if node else None
    def containkey(self,key):
        index = self.hash(key, len(self.data))
        node = self.getNode(key, index)
        return node!=None

4.跳表

import random

MAX_LEVEL=16

class Node:
    def __init__(self,data):
        self.data=data
        #key:在每一层维护索引节点
        self.nextNodes=[None]*MAX_LEVEL
        self.maxIndexLevel=0


class SkipList:
    def __init__(self,__comp):
        #记录当前跳表最大高度(包含原始链表层)
        self.levelCount=1
        self.dummyHead=Node(-1)
        self.__comp=__comp

    def contains(self,e):
        return self.get(e)
    def get(self,e):
        curr=self.dummyHead
        for i in range(self.levelCount-1,-1,-1):
            while curr.nextNodes[i] and self.__comp(curr.nextNodes[i].data,e)<0:
                curr=curr.nextNodes[i].data
        if curr.nextNodes[0] and self.__comp(curr.nextNodes[0].data,e)==0:
            return curr.nextNodes[0]
        return None


    #目:一层add后,维护上层索引(<=MAX_LEVEL)
    def randomLevel(self):
        level=1
        for i in range(1,MAX_LEVEL):
            if random.randint(0,MAX_LEVEL)%2==1:
                level+=1
        return level

    def add(self,e):
        level=self.randomLevel() if self.dummyHead.nextNodes[0] else 1
        #在各维护层中建立初始化虚拟头节点
        prevNodes=[None]*level
        for i in range(level):
            prevNodes[i]=self.dummyHead

        #找
        #定位于插入节点的前一个节点prev,并赋予prevNodes
        prev=self.dummyHead
        for i in range(self.levelCount-1,-1,-1):
            while prev.nextNodes[i] and self.__comp(prev.nextNodes[i].data,e)<0:
                prev=prev.nextNodes[i]
            if i<level:
                prevNodes[i]=prev
        #添
        #维护各层
        new_node=Node(e)
         #调整属性
        new_node.maxIndexLevel=level
        for i in range(level):
            new_node.nextNodes[i]=prev.nextNodes[i]
            prev.nextNodes[i]=new_node
        #更新链表高度
        if self.levelCount<level:
            self.levelCount=level



    def remove(self,e):
        prevNodes=[None]*self.levelCount
        #找
        prev=self.dummyHead
        for i in range(self.levelCount-1,-1,-1):
            while prev.nextNodes[i] and self.__comp(prev.nextNodes[i].data,e)<0:
                prev=prev.nextNodes[i]
            prevNodes[i]=prev
        #删
        if prev.nextNodes[0] and self.__comp(prev.nextNodes[0].data,e)==0:
            for i in range(self.levelCount-1,-1,-1):
                del_node=prevNodes[i].nextNodes[i]
                if del_node and self.__comp(del_node.data,e)==0:
                    prevNodes[i].nextNodes[i]=del_node.nextNodes[i]
                    del_node.nextNodes[i]=None
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值