IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Python 触“类”旁通3|单链表基本操作之找查、删除和倒序 -> 正文阅读

[数据结构与算法]Python 触“类”旁通3|单链表基本操作之找查、删除和倒序

本篇准备学习单链表的找查、删除和倒序操作,所有操作会用到以下前文《触“类”旁通2|数据结构入门之单链表的创建和遍历》中的代码,除__init__是必须的外,其它方法和属性基本只是为了方便赋值和检验结果正确与否而设,在解决问题时尽可能地不使用;更不能使用上篇中特别指出的“万能偷懒大法”来解决问题。节点类的基本属性和方法,如下:

class Node():
    def __init__(self, value=None, Next=None):
        self.val = value
        self.next = Next
        if type(self.next)==Node and self.next.val==None:
            self.next=None

    def __repr__(self):
        return f'Node({self.val}->{self.next})'
    
    def __str__(self):
        return f'{self.val}->{self.next}'

    def __len__(self):
        if self.val is None:
            return 0
        length,ptr = 0,self
        while ptr is not None:
            length += 1
            ptr = ptr.next
        return length 

    def __eq__(self, other):
        ptr1,ptr2 = self,other
        if len(ptr1)!=len(ptr2):
            return False
        while ptr1 is not None:
            if ptr1.val!=ptr2.val:
                return False
            ptr1 = ptr1.next
            ptr2 = ptr2.next
        else:
            return True

    def size():
        return self.__len__()

    @property
    def length(self):
        return self.size()

    @property
    def value(self):
        return self.val

    @property
    def values(self):
        ret,ptr = [],self
        while ptr is not None:
            ret.append(ptr.val)
            ptr = ptr.next
        return ret

    def pprint(self):
        print('->'.join([str(i) for i in self.values]))

    def isNode(node):
        return isinstance(node,Node) and isinstance(node.next,(Node,type(None)))

    def build(*data, split=True):
        '''把数据转换成节点链表'''
        lst,ret = [],Node()
        for val in data:
            if type(val) is str:
                if not split:
                    lst.append(val)
                    continue
                if str=='':
                    continue
                try:
                    num = int(val)
                    lst.extend([int(_) for _ in val])
                except:
                    lst.extend([_ for _ in val])
            elif hasattr(val,'__iter__'):
                lst.extend([_ for _ in val])
            elif type(val) is Node:
                if not val.isNone:
                    lst.extend(val.values)
            else:
                lst.append(val)
        ret = Node()
        for i in lst[::-1]:
            ret = Node(i, ret)
        return ret

    def copy(node):
        ret = Node()
        ptr1,ptr2 = node,ret
        while ptr1 is not None:
            ptr2.next = Node(ptr1.val)
            ptr1,ptr2 = ptr1.next,ptr2.next
        return ret.next

查找操作

1. 查找首个元素

返回等于目标值num的第一个元素的索引号,头节点为0;找不到则返回 -1。

    def find(self, num):
        ptr,ret = self,-1
        while ptr is not None:
            ret += 1
            if ptr.val == num: break
            ptr = ptr.next
        else:
            ret = -1
        return ret

2. 查找所有元素

返回等于目标值num的所有元素的索引号列表;找不到则返回 [-1]。

    def findall(self, num):
        ptr,idx,ret = self,-1,[]
        while ptr is not None:
            idx += 1
            if ptr.val == num:
                ret.append(idx)
            ptr = ptr.next
        if ret == []: ret = [-1]
        return ret

删除操作

1. 清空

>>> def clear(self):
	self.val = self.next = None
	return self

>>> n = Node.build(1,2,3)
>>> n
Node(1->2->3->None)
>>> clear(n)
Node(None->None)
>>> n
Node(None->None)
>>> 

2. 销毁

设置一个类的内置__del__() 方法:当节点不再被需要调用时,引用计数为0时就会被回收,并且调用__del__()方法显示其回收过程。

【知识点】Python 采用自动引用计数(简称 ARC)的方式实现垃圾回收机制。该方法的核心思想是:每个 Python 对象都会配置一个计数器,初始 Python 实例对象的计数器值都为 0,如果有变量引用该实例对象,其计数器的值会加 1,依次类推;反之,每当一个变量取消对该实例对象的引用,计数器会减 1。如果一个 Python 对象的的计数器值为 0,则表明没有变量引用该 Python 对象,即证明程序不再需要它,此时 Python 就会自动调用 __del__() 方法将其回收。?

del obj 并不主动调用__del__方法,只有引用计数为0时,__del__()才会被执行,并且定义了__del_()的实例无法被Python的循环垃圾收集器收集,所以尽量不要自定义__del__()。一般情况下,__del__() 不会破坏垃圾处理器。

节点类中添加以下代码用以测试:?

    def __del__(self):
        print(id(self),self)

    def init1():
        a=Node(1)
        b=Node(2)
        return a

    def init2():
        a=Node(1)
        b=Node(2)
        a.next = b
        return a

测试结果大致反馈了被回收对象的id和内容:

>>> a = Node.init1()
55624680 2->None????????# init1()中的a没被调用,引用计数为0,即被回收
>>> a = Node.init2()
50818736 1->None????????# init1()中的b也不需要了,才被回收
>>> a = Node()
55624680 1->2->None????????# 这是init2()中的a,此时才被回收
55624752 2->None????????# 这是init2()中的b被回收
>>> a = Node.build(3,4,5)
55624680 None->None????????# 前2个是build方法中用过的两个临时空节点 ret
55624872 None->None
50818736 None->None????????# 这个是上一步 a=Node() 设置的空节点
>>> del a
55624704 3->4->5->None????????# del操作即可销毁,引用计数为0从头节点开始回收
55624872 4->5->None
55624920 5->None
>>>?

3. 删除头节点

4. 删除中间节点

5. 删除尾节点

6. 删除首个指定值的节点

7. 删除指定值的所有节点

8. 删除尾节点

编辑中。。。

    def pop(self):
        if self.next is None:
            ret = self.val
            self.val = self.next = None
            return ret
        temp = Node()
        ptr1,ptr2 = self,temp
        while ptr1.next is not None:
            ptr2.next = Node(ptr1.val)
            ptr1,ptr2 = ptr1.next,ptr2.next
            ret = ptr1.val
        self.val,self.next = temp.next.val,temp.next.next
        return ret

    def __del__(self):
        #print(self)
        pass

    def reverseList(self):
        ptr = ret = Node()
        num = self.pop()
        while num is not None:
            ptr.next = Node(tmp)
            ptr = ptr.next
            num = self.pop()
        return ret.next

    def reverse(self):
        tmp = Node()
        ptr = self
        while ptr is not None:
            tmp = Node(ptr.val,tmp)
            ptr = ptr.next
        self.val,self.next = tmp.val,tmp.next
        return self

    def __reversed__(self):
        ret,ptr = Node(),self
        while ptr is not None:
            ret = Node(ptr.val, ret)
            ptr = ptr.next
        return ret

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-07 12:20:33  更:2021-08-07 12:21:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 18:25:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码