python 线性表——双向循环链表

# 实现双向循环链表
# 头指向尾, 尾指向头
# 特点是不用特意用循环去找到尾结点 用 self.__head.pre 可以表示尾结点

class Node(object):
    def __init__(self, item):
        self.elem = item
        self.prev = None
        self.next = None


class DounleCycleLinklist(object):
    def __init__(self, node=None):
        self.__head = node
        if node:
            node.next = self.__head

    def is_empty(self):
        return self.__head is None

    def length(self):
        if self.is_empty():
            return 0
        else:
            cur = self.__head
            cnt = 1
            while cur.next is not self.__head:
                cnt += 1
                cur = cur.next
            return cnt

    def travel(self):
        if self.is_empty():
            return
        else:
            cur = self.__head
            while cur.next is not self.__head:
                print(cur.elem, end=' ')
                cur = cur.next
            print(cur.elem)

    def add(self, item):
        node = Node(item)
        if self.is_empty():
            # 如果是空链表,将_head指向node
            self.__head = node
            # 将node的next指向_head的头节点
            node.next = self.__head
            # node.prev = self._head
            self.__head.prev = node
        else:
            # 尾结点为 self._head.prev
            # 尾结点next指向node
            self.__head.prev.next = node
            # node的prev指向尾结点
            node.prev = self.__head.prev
            # 将node的next指向头节点self._head
            node.next = self.__head
            # 头结点的prev指向node
            self.__head.prev = node
            # 头指针指向node
            self.__head = node

    def append(self, item):
        """尾部添加元素"""
        node = Node(item)
        if self.is_empty():
            # 如果是空链表,将_head指向node
            self.__head = node
        else:
            # 尾部节点为self._head.prev
            # 尾结点的next指向node
            self.__head.prev.next = node
            # node的prev指向尾结点
            node.prev = self.__head.prev

        # 将node的next指向头节点self._head
        node.next = self.__head
        # 头指针指向node
        self.__head.prev = node

    def insert(self, pos, item):
        node = Node(item)
        if pos <= 0:
            self.add(item)
        elif pos > (self.length() - 1):
            self.append(item)
        else:
            cur = self.__head
            cnt = 1
            while cnt is not pos:
                cnt += 1
                cur = cur.next
            # 循环结束后 cur 指向 pos-1
            node.prev = cur
            node.next = cur.next
            cur.next.prev = node
            cur.next = node

    def remove(self, item):
        """删除一个节点"""
        # 若链表为空,则直接返回
        if self.is_empty():
            return 0
        # 将cur指向头节点
        cur = self.__head
        # 若头节点的元素就是要查找的元素item
        if cur.elem == item:
            # 如果链表不止一个节点
            if cur.next != self.__head:
                # 尾节点为self._head.prev
                # 尾节点的next指向self._head.next
                self.__head.prev.next = self.__head.next
                # self._head.next为新头节点,其prev指向尾结点
                self.__head.next.prev = self.__head.prev
                # 头指针指向新节点
                self.__head = self.__head.next
            else:
                # 链表只有一个节点
                self.__head = None
        else:
            pre = self.__head
            # 第一个节点不是要删除的
            while cur.next is not self.__head:
                # 找到了要删除的元素
                if cur.elem == item:
                    # 删除
                    cur.prev.next = cur.next
                    cur.next.prev = cur.prev
                    return
                else:
                    cur = cur.next
            # cur 指向尾节点
            if cur.elem == item:
                # 尾部删除
                self.__head.prev = cur.prev
                cur.prev.next = self.__head

    def search(self, item):
        if self.is_empty():
            return False
        cur = self.__head
        res = False
        while cur.next is not self.__head :
            if cur.elem == item:
                res = True
                break
            else:
                cur = cur.next
        # 退出循环时 cur 指向尾结点, 但是没有经过判断
        if cur.elem == item:
            # 判断尾结点是否对应 item
            res = True
        return res


if __name__ == '__main__':
    dcll = DounleCycleLinklist()
    print(dcll.is_empty())
    print(dcll.length())
    dcll.append(3)
    dcll.append(4)
    dcll.travel()
    dcll.add(2)
    dcll.add(1)
    dcll.add(0)
    dcll.append(4)
    dcll.append(5)
    dcll.travel()
    dcll.insert(-1, -1)
    dcll.insert(100, 7)
    dcll.travel()
    print(dcll.length())
    dcll.insert(8, 6)
    dcll.travel()
    dcll.remove(7)
    dcll.travel()
    dcll.remove(-1)
    dcll.travel()
    dcll.insert(3, 3)
    dcll.remove(3)
    dcll.remove(4)
    dcll.travel()
    print(dcll.search(2))
    print(dcll.search(-1))
    print(dcll.search(0))
    print(dcll.search(6))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江某指点迷津

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值