Python 实现·数据结构与算法之单向循环链表

南风以南 2020/6/30 6:26:22

单向循环链表定义单向循环链表(Single Cycle Linked List)是单链表的一个变形,将链表中最后一个节点的next域不再为None,而是指向链表的头节点。节点示意图单向循环链表示意图单向循环链表的基本操作is_empty() 判断链表是否为空length 链表长度travel() 遍历整个链表,…

单向循环链表定义

单向循环链表(Single Cycle Linked List)是单链表的一个变形,将链表中最后一个节点的next域不再为None,而是指向链表的头节点。

节点示意图

节点示意图

单向循环链表示意图

单向循环链表示意图

单向循环链表的基本操作

  • is_empty() 判断链表是否为空
  • length 链表长度
  • travel() 遍历整个链表,打印元素
  • add(item) 在链表头部添加元素
  • append(item) 在链表尾部添加元素
  • insert(pos, item) 在指定位置插入元素
  • remove(item) 删除元素
  • clear() 清空链表
  • is_contain(item) 判断元素是否存在

Python代码实现

# 节点的代码实现

class Node(object):
    """节点"""
    def __init__(self, item):
        self.item = item
        self.next = None
复制代码
# 单向循环链表代码实现

class SingleCycleLinkList(object):
    """单向循环链表"""
    def __init__(self):
        self._head = None

    def is_empty(self):
        """判断链表是否为空"""
        return self._head is None

    @property
    def length(self):
        """返回链表的长度"""
        # 如果链表为空,返回长度0
        if self.is_empty():
            return 0
        count = 1
        cur = self._head
        while cur.next != self._head:
            count += 1
            cur = cur.next
        return count

    def travel(self):
        """遍历链表"""
        if self.is_empty():
            return
        cur = self._head
        print(cur.item)
        while cur.next != self._head:
            cur = cur.next
            print(cur.item)
        print("")


    def add(self, item):
        """头部添加节点"""
        node = Node(item)
        if self.is_empty():
            self._head = node
            node.next = self._head
        else:
            #添加的节点指向_head
            node.next = self._head
            # 移到链表尾部,将尾部节点的next指向node
            cur = self._head
            while cur.next != self._head:
                cur = cur.next
            cur.next = node
            #_head指向添加node的
            self._head = node

    def append(self, item):
        """尾部添加节点"""
        node = Node(item)
        if self.is_empty():
            self._head = node
            node.next = self._head
        else:
            # 移到链表尾部
            cur = self._head
            while cur.next != self._head:
                cur = cur.next
            # 将尾节点指向node
            cur.next = node
            # 将node指向头节点_head
            node.next = self._head

    def insert(self, pos, item):
        """在指定位置添加节点"""
        if pos <= 0:
            self.add(item)
        elif pos > (self.length-1):
            self.append(item)
        else:
            node = Node(item)
            cur = self._head
            count = 0
            # 移动到指定位置的前一个位置
            while count < (pos-1):
                count += 1
                cur = cur.next
            node.next = cur.next
            cur.next = node

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

    def is_contain(self, item):
        """查找节点是否存在"""
        if self.is_empty():
            return False
        cur = self._head
        if cur.item == item:
            return True
        while cur.next != self._head:
            cur = cur.next
            if cur.item == item:
                return True
        return False
    
    def __len__(self):
        """可以使用len()方法获取链表长度"""
        return self.length
    
    def __iter__(self):
        """可使用循环遍历链表里的元素"""
        if self.is_empty():
            return
        cur = self._head
        yield cur.item
        while cur.next != self._head:
            cur = cur.next
            yield  cur.item
            
    def __contains__(self, item):
        """可以使用in进行判断是否在链表中"""
        if self.is_empty():
            return False
        cur = self._head
        if cur.item == item:
            return True
        while cur.next != self._head:
            cur = cur.next
            if cur.item == item:
                return True
        return False
复制代码
# 测试数据

if __name__ == "__main__":
    print("--------创建链表-------")
    scl_list = SingleCycleLinkList()
    scl_list.add(1)
    scl_list.add(2)
    scl_list.append(3)
    scl_list.insert(2, 4)
    scl_list.insert(4, 5)
    scl_list.insert(0, 6)
    print("length:",len(scl_list))
    scl_list.travel()
    print(scl_list.is_contain(3))
    print(scl_list.is_contain(7))
    print(3 in scl_list)
    print(7 in scl_list)
    scl_list.remove(1)
    print("length:",len(scl_list))
    scl_list.travel()
    print("--------循环遍历-------")
    for i in scl_list:
        print(i)
复制代码
# 输出结果

--------创建链表-------
length: 6


4


True
False
True
False
length: 5


3


--------循环遍历-------


3

复制代码

算法分析

操作 复杂度
访问元素
在头部插入/删除
在尾部插入/删除
在中间插入/删除

联系我们

个人博客网站:www.bling2.cn/

Github地址:github.com/lb971216008…

知乎专栏:zhuanlan.zhihu.com/Use-Python-…

小专栏:xiaozhuanlan.com/Use-Python-…

博客园:www.cnblogs.com/Use-Python-…

关注

关注微信公众号【不灵兔】

随时随地学软件编程-关注百度小程序和微信小程序
关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。
本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。
[Python 实现·数据结构与算法之单向循环链表]http://www.zyiz.net/tech/detail-141549.html

上一篇:Python 图像处理 OpenCV (12): Roberts 算子、 Prewitt 算子、 Sobel 算子和 Laplacian 算子边缘检测技术

下一篇:LeetCode 215. 数组中的第K个最大元素 | Python

赞(0)

共有 条评论 网友评论

验证码: 看不清楚?
    关注微信小程序
    程序员编程王-随时随地学编程

    扫描二维码或查找【程序员编程王】

    可以随时随地学编程啦!

    技术文章导航 更多>
    扫一扫关注最新编程教程