• 单向链表


    链表

    简介

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

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

    结构

    image-20210309225425257

    代码

    需求

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

    代码实现

    # !/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  # 链表长度
    

    验证列表是否有值

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

    image-20210310092027334

    头插法

        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

    尾插法

      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

    指定元素加入元素

     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

    删除指定元素

     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

    验证值是否存在链表中

     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

    根据索引取值

        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
    

    image-20210311101341032

    遍历链表

        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("
    ")
    
    

    链表排序

        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
    

    完整代码

    # !/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("
    ")
    
        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("
    ")
            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()
    
    
  • 相关阅读:
    第一次个人编程作业
    第一次博客作业
    20175311 2018-2019-2 《Java程序设计》第五周学习总结
    2018-2019-2 20175311 实验一《Java开发环境的熟悉》实验报告
    20175311 2018-2019-2 《Java程序设计》第四周学习总结
    团队项目-选题报告
    第二次结队编程作业
    第一次结对编程作业
    第1组 团队展示(组长)
    第一次个人编程作业
  • 原文地址:https://www.cnblogs.com/SR-Program/p/14516620.html
Copyright © 2020-2023  润新知