• Python数据结构与算法—线性表


    定义

    线性表的定义是描述其逻辑结构,而通常会在线性表上进行的查找、插入、删除等操作。

    线性表作为一种基本的数据结构类型,在计算机存储器中的映象(或表示)一般有两种形式,一种是顺序映象,一种是链式映象。

    线性表的顺序存储

    1.定义:若将线性表L=(a0,a1, ……,an-1)中的各元素依次存储于计算机一片连续的存储空间,这种机制表示为线性表的顺序存储结构。

    2.特点:

    • 逻辑上相邻的元素 ai, ai+1,其存储位置也是相邻的;
    • 存储密度高,方便对数据的遍历查找。
    • 对表的插入和删除等运算的效率较差。

    3.程序实现

    在Python中,list存放于一片单一连续的内存块,故可借助于列表类型来描述线性表的顺序存储结构,而且列表本身就提供了丰富的接口满足这种数据结构的运算。

     1 L = [1,2,3,4]
     2 L.append(10)      #尾部增加元素
     3 #[1, 2, 3, 4, 10]
     4 
     5 L.insert(1,20)    #插入元素
     6 #[1, 20, 2, 3, 4, 10]
     7 
     8 L.remove(3)       #删除元素
     9 #[1, 20, 2, 4, 10]     
    10 
    11 L[4] = 30         #修改
    12 #[1, 20, 2, 4, 30]
    13 
    14 L.index(2)        #查找
    15 #2
    顺序存储代码

    线性表的链式存储

    1.定义:将线性表L=(a0,a1,……,an-1)中各元素分布在存储器的不同存储块,称为结点,每个结点(尾节点除外)中都持有一个指向下一个节点的引用,这样所得到的存储结构为链表结构。

    2.特点

    • 逻辑上相邻的元素 ai, ai+1,其存储位置也不一定相邻;
    • 存储稀疏,不必开辟整块存储空间。
    • 对表的插入和删除等运算的效率较高。
    • 逻辑结构复杂,不利于遍历。

    3.程序实现

      1 """
      2 linklist.py  链表程序实现
      3 重点代码
      4 
      5 思路分析
      6 1. 创建节点类,生成节点对象
      7   包含数据和下一个节点的引用
      8 2. 链表类,生成链表对象
      9   可以对链表进行数据操作
     10 """
     11 
     12 
     13 class Node():
     14     """
     15     一个节点里面包含两个数据,一个是当前的数据,一个是指向下一个数据的next,
     16     当next数据为None时,次节点为最后一个节点
     17     """
     18 
     19     def __init__(self, data, next=None):
     20         self.data = data
     21         self.next = next
     22 
     23 
     24 class Linklist():
     25     def __init__(self):
     26         "生成一个头节点,头结点为head,假设当前的Node是空值"
     27         self.head = Node(None)
     28 
     29     # 初始添加一组链表节点
     30     def linklist(self, list_):
     31         # 设p为头节点
     32         p = self.head
     33         # 循环链表,链表的每一个值都赋值给p.next
     34         for i in list_:
     35             p.next = Node(i)
     36             # 每一次循环 p.next重新赋值为p
     37             p = p.next
     38 
     39     # 遍历链表
     40     def shou_link(self):
     41         # 设p为第一个节点 (链表中头节点和第一个节点是不同的)
     42         # 如果这里把p设为头节点的话,那while就要从第一节点开始
     43         p = self.head.next
     44         # 如果p.next为空值,此时的p.next是链表中的最后一个节点,
     45         while p is not None:
     46             # p.data是本次节点的值,循环打印本次的节点的值
     47             print(p.data, end=" ")
     48             # 每一次循环 p.next重新赋值为p
     49             p = p.next
     50         print()
     51 
     52     # 获取链表的长度
     53     def get_lenght(self):
     54         p = self.head
     55         n = 0
     56         while p.next is not None:
     57             n += 1
     58             p = p.next
     59         return n
     60 
     61     # 判断链表是否为空
     62     def empty(self):
     63         # 如果链表的长度为0,那链表自然是空的
     64         if self.get_lenght() == 0:
     65             return True
     66         else:
     67             return False
     68 
     69     # 清空链表
     70     def clear(self):
     71         # 第一个节点为空值,那就后面的几个节点就断开了,也就相当于清空了
     72         self.head.next = None
     73 
     74     # 尾部插入节点
     75     def add_link(self, data):
     76         # 生成一个新的节点,把这个节点插到尾部
     77         # node是节点 data是节点的值
     78         node = Node(data)
     79         p = self.head
     80         # 循环出最后一个节点
     81         while p.next is not None:
     82             p = p.next
     83         # 循环完最后一个p为最后一个节点,将最后一个节点用next连接node, node为链表的最后一个节点
     84         p.next = node
     85 
     86     # 选择位置插入节点
     87     # 思想:先将新节点的next连接后一个节点,再将前一个节点的next连接新节点
     88     def insert(self, index, data):
     89         # 先判断 下标index的位置,要求下标不能小于0和大于链表的长度
     90         # 如果超出范围,人工报错
     91         if index < 0 or index > self.get_lenght():
     92             raise IndexError("index out of range")
     93         p = self.head
     94         # 定义p移动到插入位置的前一个
     95         for i in range(index):  # index从0开始
     96             # 假如index=0,p=p.next
     97             # 假如index=1,p=p.next.next
     98             # 假如index=2,p=p.next.next.next 以此类推
     99             p = p.next
    100         node = Node(data)  # 生成一个新的节点
    101         # 将node插入链表p的后面
    102         # node的前一个节点p 后一个节点p.next
    103         node.next = p.next
    104         p.next = node
    105 
    106     # 删除节点
    107     # 思想:前一个节点的next 连接到删除节点的后一个节点
    108     def del_node(self, data):
    109         p = self.head
    110         # 查找删除节点的值
    111         while p.next and p.next.data != data:
    112             p = p.next
    113         # 如果循环到最后以为还没找到,说明删除的值不在链表中
    114         if p.next is None:
    115             raise ValueError("value is error")
    116         else:
    117             #跨过删除的节点,连接删除节点的后面节点
    118             p.next = p.next.next
    119 
    120     # 通过下标,获取节点的值
    121     def get_data(self, index):
    122         if index < 0 or index > self.get_lenght():
    123             raise IndexError("index out of range")
    124         # p为第一个节点
    125         p = self.head.next
    126 
    127         for i in range(index):
    128             # 同插入节点
    129             p = p.next
    130         return p.data
    131 
    132 
    133 print("-----------测试--------------")
    134 if __name__ == '__main__':
    135     list = Linklist()
    136     l = [1, 2, 3, 4, 5]
    137     list.linklist(l)
    138     list.shou_link()  # 1 2 3 4 5
    139     print(list.get_lenght())  # 5
    140     print(list.empty())  # False
    141     list.add_link(6)
    142     list.shou_link()  # 1 2 3 4 5 6
    143     list.insert(3, 22)
    144     list.shou_link()  # 1 2 3 22 4 5 6
    145     list.del_node(5)
    146     list.shou_link()  # 1 2 3 22 4 6
    147     print(list.get_data(2))  # 3
    148     list.clear()
    链式存储代码
  • 相关阅读:
    angular2 UT 导入 jquery问题解决
    css超过指定宽度用...表示
    karma-coverage通过浏览器显示
    angular2复选框及其按钮
    前端分页控制
    input复选框checkbox默认样式纯css修改
    弧形侧边栏
    浅谈软件测试
    随笔1
    java注解小记
  • 原文地址:https://www.cnblogs.com/maplethefox/p/10988401.html
Copyright © 2020-2023  润新知