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()
链式存储代码

 

posted @ 2019-06-07 16:03  maplethefox  阅读(1194)  评论(0编辑  收藏  举报