美文网首页
Python实现:链表、队列、堆栈、AVL树、红黑树

Python实现:链表、队列、堆栈、AVL树、红黑树

作者: Alcazar | 来源:发表于2019-11-25 19:55 被阅读0次

    一、链表

    class Node(object):
        def __init__(self, value):
            # 元素域
            self.value = value
            # 链接域
            self.next = None
    
    
    class LinkedListOneway(object):
        def __init__(self, node=None):
            self.__head = node
    
        def __len__(self):
            # 游标,用来遍历链表
            cur = self.__head
            # 记录遍历次数
            count = 0
            # 当前节点为None则说明已经遍历完毕
            while cur:
                count += 1
                cur = cur.next
            return count
    
        def is_empty(self):
            # 头节点不为None则不为空
            return self.__head == None
    
        def add(self, value):
            """
            头插法
            先让新节点的next指向头节点
            再将头节点替换为新节点
            顺序不可错,要先保证原链表的链不断,否则头节点后面的链会丢失
            """
            node = Node(value)
            node.next = self.__head
            self.__head = node
    
        def append(self, value):
            """尾插法"""
            node = Node(value)
            cur = self.__head
            if self.is_empty():
                self.__head = node
            else:
                while cur.next:
                    cur = cur.next
                cur.next = node
    
        def insert(self, pos, value):
            # 应对特殊情况
            if pos <= 0:
                self.add(value)
            elif pos > len(self) - 1:
                self.append(value)
            else:
                node = Node(value)
                prior = self.__head
                count = 0
                # 在插入位置的前一个节点停下
                while count < (pos - 1):
                    prior = prior.next
                    count += 1
                # 先将插入节点与节点后的节点连接,防止链表断掉,先链接后面的,再链接前面的
                node.next = prior.next
                prior.next = node
    
        def remove(self, value):
            cur = self.__head
            prior = None
            while cur:
                if value == cur.value:
                    # 判断此节点是否是头节点
                    if cur == self.__head:
                        self.__head = cur.next
                    else:
                        prior.next = cur.next
                    break
                # 还没找到节点,有继续遍历
                else:
                    prior = cur
                    cur = cur.next
    
        def search(self, value):
            cur = self.__head
            while cur:
                if value == cur.value:
                    return True
                cur = cur.next
            return False
    
        def traverse(self):
            cur = self.__head
            while cur:
                print(cur.value)
                cur = cur.next
    

    二、队列

    class  Queue:
        #初始化队列
        def __init__(self):
            self.items=[]
    
        #加入队列
        def inqueue(self,item):
            self.items.append(item)
        #出队列
        def dequeue(self):
            return self.items.pop(0)
            
        #判断是否为空
        def empty(self):
            return self.size()==0
        #返回长度
        def size(self):
            return len(self.items)
    
    附个实例:约瑟夫斯问题
    #约瑟夫斯问题
    def josephus(namelist, num):
        simqueue = Queue()
        for name in namelist:
            simqueue.inqueue(name)
    
        while simqueue.size() > 1:
            for i in range(num):
                simqueue.inqueue(simqueue.dequeue())
            simqueue.dequeue()
        return simqueue.dequeue()
    
    def josephus(namelist,num):
        squeue = Queue()
        for name in namelist:
            squeue.inqueue(name)
    
        while squeue.size()>1:
            for i in range(num):
                squeue.inqueue(squeue.dequeue())
            squeue.dequeue()
        return squeue.dequeue()
    
    if __name__ == '__main__':
        print(josephus(["Java", "Python", "C++", "C", "PHP", "Html5"], 5))
    
    

    三、堆栈

    # 后进先出
    class Stack():
        def __init__(self,size):
            self.size=size
            self.stack=[]
            self.top = -1
        # 压入数据
        def push(self,x):
            if self.isfull():
                raise eecception("栈满...")
            else:
                self.stack.append(x)
                self.top = self.top + 1
    
        # 弹出数据
        def pop(self):
            if self.isempty():
                raise exception("栈空...")
            else:
                self.top = self.top -1
                self.stack.pop()
    
        def isfull(self):
            return self.top+1 == self.size
    
        def isempty(self):
            return self.top == '-1'
            
        def showStack(self):
            print(self.stack)
     
    if __name__ == "__main__":
        s=Stack(10)
        for i in range(10):
            s.push(i)
        s.showStack()
        for i in range(3):
            s.pop()
        s.showStack()
     
    """
    类中有top属性,用来指示栈的存储情况,初始值为1,一旦插入一个元素,其值加1,利用top的值乐意判定栈是空还是满。
    执行时先将0,1,2,3,4依次入栈,然后删除栈顶的前三个元素
    """
    

    四、AVL树(平衡二叉树)

    详细关于AVL树请阅读:浅谈【树】:红黑树、AVL树、B树、B+树

    class Node(object):
        def __init__(self, key, parent=None, left=None, right=None):
            self.key = key          # 存储的数据
            self.parent = parent    # 父节点
            self.left = left        # 左孩子节点
            self.right = right      # 右孩子节点
            self.bf = 0             # 平衡因子 等于左子树高度减去右子树高度
    
        def l_rotate(self, par, cur):
            """
            左单旋转
            :param par:  平衡因子为2|-2的节点
            :param cur:  作为轴心旋转的节点(平衡因子不为2)
            :return: None
            """
            p = cur.left                    # 辅助引用p指向cur的左节点
            cur.left = par                  # cur的左节点指向par
            par.right = p                   # par的右节点指向cur的左节点
            if p:
                p.parent = par              # cur的左节点不为空时更新该节点的父节点
            if par == self.root:
                self.root = cur             # 判断平衡因子为2的par是否为根
            else:
                if par == par.parent.left:  # 更新par父节点的子节点信息
                    par.parent.left = cur
                else:
                    par.parent.right = cur
            cur.parent = par.parent         # 当前cur的父节点指向原来par的父节点
            par.parent = cur                # par变为cur的左子节点
            cur.bf = par.bf = 0             # 插入操作中, 操作的两个节点旋转后平衡因子恢复为0
    
        def r_rotate(self, par, cur):
            """右单旋转"""
            p = cur.right
            cur.right = par
            par.left = p
            if p:
                p.parent = par
            if par == self.root:
                self.root = cur
            else:
                if par == par.parent.left:
                    par.parent.left = cur
                else:
                    par.parent.right = cur
    
            cur.parent = par.parent         # 更新父节点信息
            par.parent = cur
            cur.bf = par.bf = 0             # 更新平衡因子
    
        def lr_rotate(self, par, cur):
            """左右双旋转"""
            # 先左旋转 cur 和 cur的右子节点
            cur_right = cur.right           # 获得cur的右子节点的引用
            bf = cur_right.bf
            self.l_rotate(cur, cur_right)
            # 继续右旋转
            self.r_rotate(par, cur_right)
            if bf == 0:                     # 根据cur_right的平衡因子更新操作的3个节点
                cur.bf = cur_right.bf = par.bf = 0
            elif bf == -1:
                par.bf = 1
                cur.bf = cur_right.bf = 0
            else:
                cur.bf = -1
                cur_right.bf = par.bf = 0
                
        def rl_rotate(self, par, cur):
            """右左双旋转"""
            # 先右旋转 cur 和 cur的左子节点
            cur_left = cur.left                         # 获得cur的右子节点的引用
            bf = cur_left.bf
            self.r_rotate(cur, cur_left)
            self.l_rotate(par, cur_left)                # 继续右旋转       
            if bf == 0:                                 # 根据cur_left的平衡因子更新操作的3个节点
                cur.bf = cur_left.bf = par.bf = 0
            elif bf == -1:
                cur.bf = 1
                par.bf = cur_left.bf = 0
            else:
                par.bf = -1
                cur_left.bf = cur.bf = 0
                
        def find(self, key):
            """寻找键值"""
            p = self.root
            while p:
                if p.key == key:
                    return p
                if key < p.key:
                    p = p.left
                else:
                    p = p.right
            return None
    

    五、红黑树

    详细关于红黑树请阅读:浅谈【树】:红黑树、AVL树、B树、B+树

    #定义红黑树
    class RBTree(object):
        def __init__(self):
            self.nil = RBTreeNode(0)
            self.root = self.nil
    
    class RBTreeNode(object):
        def __init__(self, x):
            self.key = x
            self.left = None
            self.right = None
            self.parent = None
            self.color = 'black'
            self.size=None
    
    #左旋转
    def LeftRotate( T, x):
        y = x.right
        x.right = y.left
        if y.left != T.nil:
            y.left.parent = x
        y.parent = x.parent
        if x.parent == T.nil:
            T.root = y
        elif x == x.parent.left:
            x.parent.left = y
        else:
            x.parent.right = y
        y.left = x
        x.parent = y
    
    #右旋转
    def RightRotate( T, x):
        y = x.left
        x.left = y.right
        if y.right != T.nil:
            y.right.parent = x
        y.parent = x.parent
        if x.parent == T.nil:
            T.root = y
        elif x == x.parent.right:
            x.parent.right = y
        else:
            x.parent.left = y
        y.right = x
        x.parent = y
    
    #红黑树的插入
    def RBInsert( T, z):
        y = T.nil
        x = T.root
        while x != T.nil:
            y = x
            if z.key < x.key:
                x = x.left
            else:
                x = x.right
        z.parent = y
        if y == T.nil:
            T.root = z
        elif z.key < y.key:
            y.left = z
        else:
            y.right = z
        z.left = T.nil
        z.right = T.nil
        z.color = 'red'
        RBInsertFixup(T, z)
        return z.key, '颜色为', z.color
    
    
    #红黑树的上色
    def RBInsertFixup( T, z):
        while z.parent.color == 'red':
            if z.parent == z.parent.parent.left:
                y = z.parent.parent.right
                if y.color == 'red':
                    z.parent.color = 'black'
                    y.color = 'black'
                    z.parent.parent.color = 'red'
                    z = z.parent.parent
                else:
                    if z == z.parent.right:
                        z = z.parent
                        LeftRotate(T, z)
                    z.parent.color = 'black'
                    z.parent.parent.color = 'red'
                    RightRotate(T,z.parent.parent)
            else:
                y = z.parent.parent.left
                if y.color == 'red':
                    z.parent.color = 'black'
                    y.color = 'black'
                    z.parent.parent.color = 'red'
                    z = z.parent.parent
                else:
                    if z == z.parent.left:
                        z = z.parent
                        RightRotate(T, z)
                    z.parent.color = 'black'
                    z.parent.parent.color = 'red'
                    LeftRotate(T, z.parent.parent)
        T.root.color = 'black'
    
    
    def RBTransplant( T, u, v):
        if u.parent == T.nil:
            T.root = v
        elif u == u.parent.left:
            u.parent.left = v
        else:
            u.parent.right = v
        v.parent = u.parent
    
    
    def RBDelete(T, z):
        y = z
        y_original_color = y.color
        if z.left == T.nil:
            x = z.right
            RBTransplant(T, z, z.right)
        elif z.right == T.nil:
            x = z.left
            RBTransplant(T, z, z.left)
        else:
            y = TreeMinimum(z.right)
            y_original_color = y.color
            x = y.right
            if y.parent == z:
                x.parent = y
            else:
                RBTransplant(T, y, y.right)
                y.right = z.right
                y.right.parent = y
            RBTransplant(T, z, y)
            y.left = z.left
            y.left.parent = y
            y.color = z.color
        if y_original_color == 'black':
            RBDeleteFixup(T, x)
    
    
    #红黑树的删除
    def RBDeleteFixup( T, x):
        while x != T.root and x.color == 'black':
            if x == x.parent.left:
                w = x.parent.right
                if w.color == 'red':
                    w.color = 'black'
                    x.parent.color = 'red'
                    LeftRotate(T, x.parent)
                    w = x.parent.right
                if w.left.color == 'black' and w.right.color == 'black':
                    w.color = 'red'
                    x = x.parent
                else:
                    if w.right.color == 'black':
                        w.left.color = 'black'
                        w.color = 'red'
                        RightRotate(T, w)
                        w = x.parent.right
                    w.color = x.parent.color
                    x.parent.color = 'black'
                    w.right.color = 'black'
                    LeftRotate(T, x.parent)
                    x = T.root
            else:
                w = x.parent.left
                if w.color == 'red':
                    w.color = 'black'
                    x.parent.color = 'red'
                    RightRotate(T, x.parent)
                    w = x.parent.left
                if w.right.color == 'black' and w.left.color == 'black':
                    w.color = 'red'
                    x = x.parent
                else:
                    if w.left.color == 'black':
                        w.right.color = 'black'
                        w.color = 'red'
                        LeftRotate(T, w)
                        w = x.parent.left
                    w.color = x.parent.color
                    x.parent.color = 'black'
                    w.left.color = 'black'
                    RightRotate(T, x.parent)
                    x = T.root
        x.color = 'black'
    
    
    def TreeMinimum( x):
        while x.left != T.nil:
            x = x.left
        return x
    
        
    #中序遍历
    def Midsort(x):
        if x!= None:
            Midsort(x.left)
            if x.key!=0:
                print('key:', x.key,'x.parent',x.parent.key)
            Midsort(x.right)
    
    if __name__ == "__main__":   
        nodes = [11,2,14,1,7,15,5,8,4]
        T = RBTree()
        for node in nodes:
            print('插入数据',RBInsert(T,RBTreeNode(node)))
        print('中序遍历')
        Midsort(T.root)
        RBDelete(T,T.root)
        print('中序遍历')
        Midsort(T.root)
        RBDelete(T,T.root)
        print('中序遍历')
        Midsort(T.root)
    
    

    相关文章

      网友评论

          本文标题:Python实现:链表、队列、堆栈、AVL树、红黑树

          本文链接:https://www.haomeiwen.com/subject/srojwctx.html