定义
线性表的定义是描述其逻辑结构,而通常会在线性表上进行的查找、插入、删除等操作。
线性表作为一种基本的数据结构类型,在计算机存储器中的映象(或表示)一般有两种形式,一种是顺序映象,一种是链式映象。
线性表的顺序存储
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()
来源:oschina
链接:https://my.oschina.net/u/4349325/blog/3508609