数据结构与算法01(python实现)__单链表的实现
以下代码以OOP(面向对象)的思想实现ADT(Abstract Data Type),基于python,其中python对定义变量实质是引用(类似C语言的指针)的思想贯彻全篇代码
# 节点的实现 class Node(object): '''节点保存,数据+地址''' def __init__(self, item): self.item = item self.next = None # 链表的实现 class SingleLinkList(object): '''链表,找到节点+实现操作''' def __init__(self): # 通过head指向头节点,即可找到其他节点 self.__head = None # 实现链表的各种操作 def is_empty(self): '''判断链表是否为空''' # 如果链表为空,self__head指向None; 不为空,则not None return self.__head is None # 空 == True;非空 == False def add(self, item): '''头插法,链表头部增加节点''' node = Node(item) # 实例化节点(数据+next) node.next = self.__head # 1.新增节点指向原首节点 self.__head = node # 2.原head指向新增节点 # 以上满足,原链表为空的特殊情况 def length(self): '''得到链表的长度(节点数量)''' cur = self.__head # 需要一个游标cursor指向节点,通过移动cursor,得到遍历节点的目的 count = 0 while cur != None: cur = cur.next # 游标移动至下一节点 count += 1 return count # 以上满足,原链表为空的特殊情况 def travle(self): '''遍历整个链表,不断输出每个节点的item(数据区)''' cur = self.__head while cur != None: # 如果是空链表,cur没有item属性,但是也进不来循环,所以满足空链表特殊情况 print(cur.item, end=' ') # input item, not address(next) cur = cur.next print() def append(self, item): '''尾插法, 链表尾部添加节点''' node = Node(item) cur = self.__head # 如果链表为空,需要单独考虑 if self.is_empty(): self.__head = node else: # 链表不为空的情况 # 遍历到尾部再添加 while cur.next != None: # 这里不能让cursor移动到None,因为单链表没法回退,没法添加节点了 cur = cur.next # 移动cursor 这相当于循环终止条件,不写死循环!!! node.next = None cur.next = node def insert(self, pos, item): '''指定位置添加元素''' # assert 0 <= pos <= self.length(), '请输入正确的位置' # 可以采用断言抛异常的方式,但是为了程序的健壮性,我们采用以下方式 node = Node(item) # 如果链表为空 if self.is_empty(): self.__head = node else: # 链表非空 if pos <= 0: self.add(node) elif pos >= self.length(): self.append(node) else: # 中间位置添加 cur = self.__head for num in range(pos-1): # cursor移动pos-1次,单链表不能回头 cur = cur.next # cur现在指向我们要添加节点的上一个节点 node.next = cur.next cur.next = node def search(self, item): '''判断节点是否存在''' cur = self.__head if self.is_empty(): return False # 链表为空,直接F while cur != None: # while cur.next != None: # 这么写的话,如果所判断的节点是最后一个,则无法判断了 if cur.item == item: # 如果存在,返回T return True cur = cur.next return False def remove(self, item): '''删除指定节点''' if self.is_empty(): return None # 这里需要两个游标 previous和cursor # 要删除一个节点,即使该节点前一个直接指向后一个而跳过它,需要两个游标(单链表不能回退) pre = None cur = self.__head while cur is not None: if cur.item == item: # 找到了要删除的节点 if cur == self.__head: # 要删除的是首节点 self.__head = cur.next else: # 要删除的是中间+尾节点 pre.next = cur.next pre = cur cur = cur.next if __name__ == '__main__': sll = SingleLinkList() # sll.append(1000) # sll.insert(0, 2000) print(sll.is_empty()) # True sll.add(100) sll.add(200) sll.add(300) print(sll.is_empty()) # False print(sll.length()) # 3 sll.travle() # 300 200 100 sll.append(400) sll.travle() # 300 200 100 400 print(sll.length()) # 4 sll.insert(2, 'insert_ele') sll.travle() # 300 200 insert_ele 100 400 print(sll.search('我在吗')) # False print(sll.search(300)) # True print(sll.search(200)) # True print(sll.search(400)) # True # 300 200 insert_ele 100 400 sll.remove(300) sll.travle() # 200 insert_ele 100 400
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)