数据结构与算法 | 06.单向循环链表

# CY3761 | 2021-12-08 16:12
import copy
import types

# 单向循环链表
"""
单向循环链表与普通链表区别
尾节点的 next 不再是None, 而是指向链表的头节点
其链表形成一个环, 这种数据结构称为单向循环链表

一般可能用于一群人玩游戏, 当触发某种机制时停止, 这个人出局, 如此类推
"""


class Node:
    def __init__(self, _item, _next=None):
        self._item = _item  # 数据域
        self._next = _next  # 指针域
    
    def next(self, *args):
        if len(args) == 0:
            return self._next
        
        _next = args[0]
        if isinstance(_next, Node) or _next is None:
            self._next = _next
    
    def item(self, *args):
        if len(args) == 0:
            return self._item
        
        self._item = args[0]


# 单向循环链表
class SingleWhileChain:
    def __init__(self):
        self._head = None  # 链表的头节点
        self._leng = 0  # 链表的个数
    
    def isEmpty(self):  # 链表是否为空
        return self._leng <= 0
    
    def length(self):  # 链表长度
        return self._leng
    
    def items(self):  # 获取链表列表 (注意: 这个尾节点的next不会为空, 原来的while方法不适用)
        if self.isEmpty():
            return []
        
        items = []
        """
        aItem = self._head
        
        while aItem:
            items.append(aItem.item())
            aItem = aItem.next()
        """
        # 需要先把头节点加进去
        items.append(self._head.item())
        aItem = self._head.next()
        
        while aItem != self._head:
            items.append(aItem.item())
            aItem = aItem.next()
        
        return items
    
    def before(self, item):
        item = Node(item)
        
        if self.isEmpty():
            self._head = item
            item.next(self._head)
        else:
            # 让 node的next指向头节点
            item.next(self._head)
            
            # 让链表的尾节点的next指向node (找到尾节点)
            foot = self._head
            while foot.next() != self._head:
                foot = foot.next()
            foot.next(item)
            
            self._head = item
        self._leng += 1
    
    def after(self, item):
        item = Node(item)
        
        if not self._head:
            self._head = item
        else:
            foot = self._head
            while foot.next() != self._head:
                foot = foot.next()
            foot.next(item)
        item.next(self._head)
        
        self._leng += 1

        # 向链表指定位置添加节点

    def where(self, pos, item):  # 不需要改变
        pos = int(pos)
    
        if pos <= 0:
            return self.before(item)
        elif pos >= self._leng:
            return self.after(item)
        else:
            item = Node(item)  # 新建节点
            aItem = self._head  # A
            bItem = aItem
        
            while pos > 0:
                bItem = aItem
                aItem = aItem.next()
                pos -= 1
        
            item.next(aItem)
            bItem.next(item)
            self._leng += 1
    
    def head(self):
        return self._head
    
    def foot(self):
        if self.isEmpty():
            return None
        
        aItem = self._head.next()
        
        while aItem != self._head:
            aItem = aItem.next()
        
        return aItem

    def remove(self, item):
        if self.isEmpty():
            return -1
        
        aItem = self._head
        bItem = None
        isWhile = True
        
        while isWhile or aItem != self._head:
            isWhile = False
            if aItem.item() == item:
                if not bItem:
                    # 找到尾节点 并让尾节点的next指向 head
                    foot = self._head
                    while foot.next() != self._head:
                        foot = foot.next()
                    foot.next(self._head.next())
                    self._head = aItem.next()
                else:
                    bItem.next(aItem.next())
                self._leng -= 1
                return 0
            bItem = aItem
            aItem = aItem.next()
        
        return -1
        pass

    def update(self, pos, item):  # 不需要改
        pos = int(pos)
    
        if 0 > pos > self._leng:
            return -1
    
        aItem = self._head  # A
    
        while pos > 0:
            aItem = aItem.next()
            pos -= 1
    
        aItem.item(item)
    
        pass

    def search(self, item):  # 不需要改
        if self.isEmpty():
            return -1
        
        aItem = self._head  # A
        isHas = False
        while aItem:
            if aItem.item() == item:
                isHas = True
                break
        
            aItem = aItem.next()
    
        return 1 if isHas else -1


def eachSingleWhileChain(args, method, methodString, chain=None):
    if chain is None:
        a = SingleWhileChain()
    else:
        a = chain
    print('-' * 80)
    print(a.length(), a.items())
    
    if not isinstance(method, types.LambdaType):
        raise Exception('method not is LambdaType')
    
    for _ in args:
        b = method(a, _)
        
        print(_, b, a.length(), methodString.format(*_), a.items())
        print(a.head().item(), a.head(), a.foot())  # 头节点 == 未节点
        
    return a


if __name__ == '__main__':
    eachSingleWhileChain([
        'A', 'B', 'C', 'D', 'E'
    ], lambda a, _: a.before(_), 'a.before({})')
    
    eachSingleWhileChain([
        'A', 'B', 'C', 'D', 'E'
    ], lambda a, _: a.after(_), 'a.after({})')

    c = eachSingleWhileChain([
        (0, 'A'), (4, 'B'), (1, 'C'), (2, 'D'), (3, 'E')
    ], lambda a, _: a.where(*_), 'a.where({},{})')
    d = copy.deepcopy(c)

    eachSingleWhileChain([
        'A', 'B', 'C', 'D', 'E'
    ], lambda a, _: a.remove(_), 'a.remove({})', c)
    
    """"""
    c = eachSingleWhileChain([
        (0, '一'), (4, '二'), (1, '三'), (2, '四'), (3, '五')
    ], lambda a, _: a.update(*_), 'a.update({},{})', d)

    eachSingleWhileChain([
        '一', '二', '三', '四', '五'
    ], lambda a, _: a.search(_), 'a.search({})', c)
    

在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

CY3761

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

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

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

打赏作者

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

抵扣说明:

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

余额充值