单向链表

链表#

简介#

单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始。单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。它的每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。

链式存储结构的线性表将采用一组任意的存储单元存放线性表中的数据元素。由于不需要按顺序存储,链表在插入、删除数据元素时比顺序存储要快,但是在查找一个节点时则要比顺序存储要慢,使用链式存储可以克服顺序线性表需要预先知道数据大小的缺点,链表结构可以充分利用内存空间,实现灵活的内存动态管理。但是链式存储失去了数组随机存取的特点,同时增加了节点的指针域,空间开销较大。

结构#

image-20210309225425257

代码#

需求#

  1. 验证列表是否有值
  2. 从头部插入元素
  3. 从尾部插入元素
  4. 指定位置插入元素
  5. 删除元素
  6. 验证节点是否在链表中
  7. 根据节点索引查找值
  8. 链表排序
  9. 修改数据

代码实现#

Copy
# !/usr/bin/env python3 # -*- coding: utf-8 -*- # @Time : 2021/3/8 下午8:47 # @Author : SR # @Email : srcoder@163.com # @File : link_list.py # @Software: PyCharm # 基础配置 class Node: '''节点''' def __init__(self, data): self.data = data # 存储数据 self.next = None # 下一个节点 class SingleLinkList: '''链表''' def __init__(self): self.header = None # 节点头部 self.length = 0 # 链表长度

验证列表是否有值#

Copy
def is_empty(self): '''判断是否为空''' if not self.length == 0: # 链表长度为0则没有值 return False return True

image-20210310092027334

头插法#

Copy
def create_linklist_by_head(self, node): '''头插法''' if self.is_empty(): self.header = node else: node.next = self.header self.header = node self.length += 1

image-20210310092136288

尾插法#

Copy
def create_linklist_by_tail(self, node): '''尾插法''' current_node = self.header if self.is_empty(): self.create_linklist_by_head(node) else: while not current_node.next == None: current_node = current_node.next # 获取最后一个元素 current_node.next = node # 最后一个元素下一个元素即为新增节点 self.length += 1

image-20210310092909591

指定元素加入元素#

Copy
def create_linklist_by_insert(self, node, index): '''插入在指定位置''' current_node = self.header # 获取首节点 if index <= 0 or self.length == 0: index = 1 if index == 1: # 索引为1的时候 默认直接插入到首位 self.create_linklist_by_head(node) elif index == 2: node.next = self.header.next current_node.next = node self.length += 1 elif index > self.length: # 索引大于链表长度 默认插入到尾部 self.create_linklist_by_tail(node) else: for i in range(1, index - 1): current_node = current_node.next # 获取插入之前的元素 例如想插在3号位置 此时节点为2号元素 node.next = current_node.next # 将插入的元素与后一位联系起来 例如此时插入3号位置  current_node.next = node self.length += 1

插入首号位置

image-20210310211410992
插入大于链表长度位置

image-20210310211707810
插入2号位置

image-20210310211949503
插入小于0号位置

image-20210310212243796
在首位与末位之间任意插入

image-20210310212448109

删除指定元素#

Copy
def delete_linklist_by_index(self, index): if self.is_empty(): print('当前链表无数据') else: if index not in range(1, self.length): while index not in range(1, self.length): print("死扑街啊 不知道从哪里删除吗 重新输入啊!") index = eval(input("请重新输入啊>>:")) if index == 1: self.header = self.header.next elif index == 2: current_node = self.header current_node.next = current_node.next.next else: current_node = self.header for i in range(1, index - 1): current_node = current_node.next current_node.next = current_node.next.next self.length -= 1

删除首位元素

image-20210310220851595
删除末位元素

image-20210310221054756
删除2号元素

image-20210310222521366
删除首位到末尾之间任意元素

image-20210310222727483

验证值是否存在链表中#

Copy
def isContainNum(self, number): flag = False current_node = self.header for i in range(1, self.length): if current_node.data == number: print("该链表包含%s--->位于%s位置" % (number, i)) flag = True break # 找到元素则直接退出循环 current_node = current_node.next if not flag: print("该值%s不在链表之中" % number)

image-20210311092253284

根据索引取值#

Copy
def searchNodeByIndex(self, index): current_node = self.header if self.is_empty(): print("当前链表为空") else: if index not in range(1, self.length): while index not in range(1, self.length): print('死扑街啊 索引有误 请重新输入啊') index = eval(input('请重新输入啊>>:')) for i in range(1, index): current_node = current_node.next return current_node

根据索引修改链表值#

Copy
def alterNumByIndex(self, index, number): if self.is_empty(): print("当前链表为空 无可修改的数据!") else: current_node = self.header if index not in range(1, self.length): while index not in range(1, self.length): print("死扑街啊 索引写错了") index = eval(input("请重新输入啊>>:")) for i in range(1, index): current_node = current_node.next current_node.data = number

image-20210311101341032

遍历链表#

Copy
def travel(self): current_node = self.header if self.length == 0: print("当前链表为空") else: for i in range(self.length): print("%s " % current_node.data, end=" ") current_node = current_node.next print("\n")

链表排序#

Copy
def list_sort(self): for i in range(self.length): current_node = self.header for j in range(self.length - 1 - i): if current_node.data > current_node.next.data: temp = current_node.data current_node.data = current_node.next.data current_node.next.data = temp current_node = current_node.next

完整代码#

Copy
# !/usr/bin/env python3 # -*- coding: utf-8 -*- # @Time : 2021/3/10 上午9:04 # @Author : SR # @Email : srcoder@163.com # @File : link_list.py # @Software: PyCharm class Node: def __init__(self, data): self.data = data self.next = None class SingleLinkList: def __init__(self): self.header = None self.length = 0 # 链表长度 def is_empty(self): '''判断是否为空''' if not self.length == 0: return False return True def create_linklist_by_head(self, node): '''头插法''' if self.is_empty(): self.header = node else: node.next = self.header self.header = node self.length += 1 def create_linklist_by_tail(self, node): '''尾插法''' current_node = self.header if self.is_empty(): self.create_linklist_by_head(node) else: while not current_node.next == None: current_node = current_node.next current_node.next = node self.length += 1 def create_linklist_by_insert(self, node, index): '''插入在指定位置''' current_node = self.header # 获取首节点 if index <= 0 or self.length == 0: index = 1 if index == 1: self.create_linklist_by_head(node) elif index == 2: node.next = self.header.next current_node.next = node self.length += 1 elif index > self.length: self.create_linklist_by_tail(node) else: for i in range(1, index - 1): current_node = current_node.next # 获取插入之前的元素 例如想插在3号位置 此时节点为2号元素 node.next = current_node.next # 将插入的元素与后一位联系起来 例如此时插入3号位置  current_node.next = node self.length += 1 def delete_linklist_by_index(self, index): '''通过索引删除''' if self.is_empty(): print('当前链表无数据') else: if index not in (1, self.length): while index not in (1, self.length): print("死扑街啊 不知道从哪里删除吗 重新输入啊!") index = eval(input("请重新输入啊>>:")) if index == 1: self.header = self.header.next elif index == 2: current_node = self.header current_node.next = current_node.next.next else: current_node = self.header for i in range(1, index - 1): current_node = current_node.next current_node.next = current_node.next.next self.length -= 1 def isContainNum(self, number): '''验证链表是否包含某值''' flag = False current_node = self.header for i in range(1, self.length): if current_node.data == number: print("该链表包含%s--->位于索引%s" % (number, i)) flag = True if not flag: print("该值%s不在链表之中" % number) def searchNodeByIndex(self, index): '''通过索引寻找某节点''' current_node = self.header if self.is_empty(): print("当前链表为空") else: if index not in range(1, self.length): while index not in range(1, self.length): print('死扑街啊 索引有误 请重新输入啊') index = eval(input('请重新输入啊>>:')) for i in range(1, index): current_node = current_node.next return current_node def alterNumByIndex(self, index, number): '''索引修改值''' if self.is_empty(): print("当前链表为空 无可修改的数据!") else: current_node = self.header if index not in range(1, self.length): while index not in range(1, self.length): print("死扑街啊 索引写错了") index = eval(input("请重新输入啊>>:")) for i in range(1, index): current_node = current_node.next current_node.data = number def travel(self): '''便利链表''' current_node = self.header if self.length == 0: print("当前链表为空") else: for i in range(self.length): print("%s " % current_node.data, end=" ") current_node = current_node.next print("\n") def list_sort(self): '''链表排序''' for i in range(self.length): current_node = self.header for j in range(self.length - 1 - i): if current_node.data > current_node.next.data: temp = current_node.data current_node.data = current_node.next.data current_node.next.data = temp current_node = current_node.next def main(): # 创建一个单链表对象 single_link_list = SingleLinkList() # 实例化 print(''' ********************************************************************************************************************** **********************************************请选择相应的序号完成相应的操作******************************************** ********************************************************************************************************************** ** 0、结束所有操作!!!!!! *** ** 1、验证链表里面有没有值! *** ** 2、从头部插入数值! *** ** 3、从尾部插入数值! *** ** 4、按指定位置插入数值! *** ** 5、删除操作! *** ** 6、查找一个节点是否在链表中! *** ** 7、按下标查找节点处的数值! *** ** 8、给链表排序! *** ** 9、修改! *** ********************************************************************************************************************** ''') while True: number = eval(input('请输入上述数字对应的编号>>:').strip()) if number not in range(1, 9): while number not in range(1, 9): print("死扑街啊 不认识上面字吗 选择的功能为开发啊!") number = eval(input('请重新输入上述数字对应的编号>>:').strip()) if number == 0: return elif number == 1: print("正在验证链表里面有没有值:") if not single_link_list.is_empty(): single_link_list.travel() else: print("当前链表无数据!") print("\n") elif number == 2: print("目前的链表状态。") single_link_list.travel() print("正在从头部插入数值:") node = Node(int(input("请输入需要插入的值>>:"))) single_link_list.create_linklist_by_head(node) print("操作后链表的状态。") single_link_list.travel() elif number == 3: print("目前的链表状态。") single_link_list.travel() node = Node(int(input("请输入需要插入的值>>:"))) if not single_link_list.is_empty(): print("正在从尾部插入数值:") single_link_list.create_linklist_by_tail(node) print("操作后链表的状态。") single_link_list.travel() else: single_link_list.create_linklist_by_head(node) print("操作后链表的状态。") single_link_list.travel() elif number == 4: print("目前的链表状态。") single_link_list.travel() print("正在从指定位置插入数值:") node = Node(int(input("请输入需要插入的值>>:"))) index = int(input("请输入需要插入的位置>>:")) single_link_list.create_linklist_by_insert(node, index) print("操作后链表的状态。") single_link_list.travel() elif number == 5: if not single_link_list.is_empty(): print("目前的链表状态。") single_link_list.travel() print("正在从指定位置删除数值:") index = int(input("请输入需要删除的位置>>:")) single_link_list.delete_linklist_by_index(index) print("操作后链表的状态。") single_link_list.travel() else: print("当前链表为空 请添加数据!") elif number == 6: if not single_link_list.is_empty(): print("目前的链表状态。") single_link_list.travel() print("正在查找一个节点是否在链表中:") num = eval(input("请输入需要查询的元素>>:")) single_link_list.isContainNum(num) else: print("当前链表为空") elif number == 7: if not single_link_list.is_empty(): print("正在按下标查找节点处的数值>>:") node = single_link_list.searchNodeByIndex( eval(input("输入下标值>>:"))) # 查找某节点处的值 print("这个位置的值为:%s" % node.data) else: print("当前链表为空") elif number == 8: if not single_link_list.is_empty(): print("目前的链表状态。") single_link_list.travel() print("正在排序:") single_link_list.list_sort() print("操作后链表的状态。") single_link_list.travel() else: print("当前链表为空") else: if not single_link_list.is_empty(): print("目前的链表状态。") single_link_list.travel() print("正在修改(这是在上面排序后的前提下修改。):") index = eval(input("输入要修改的得位置>>:")) # 修改的下角标 num = eval(input("输入要修改为的数>>:")) # 要修改成的那个数 single_link_list.alterNumByIndex(index, num) print("操作后链表的状态。") single_link_list.travel() # 遍历一遍 else: print("当前链表为空") if __name__ == '__main__': main()
posted @   SR丶  阅读(156)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示
CONTENTS