1. 顺序表(Sequential List)
逻辑相邻,物理相邻:存储空间紧凑,不必为节点间的逻辑关系而增加额外的存储开销。
所有元素存放在一片地址连续的存储单元中,需要开辟连续存储空间,造成存储空间“碎片”。
插入、删除操作需要移动表中约一半的元素,当n较大时,顺序表的效率低。
按位查找:顺序表的时间为O(1),是随机存取
插入和删除:顺序表需移动表长约一半的元素,时间为O(n)
顺序表的存储密度为1,而链表的存储密度小于1。仅从存储密度看,顺序表的存储空间利用率高。
但顺序表需要预先分配初始空间,所有数据占用一整片地址连续的内存空间。
以下代码是顺序表的基本操作:
class SequentialList(Object):
def __init__(self, size = 50): # 初始化线性表,定义线性表的最大长度为50
self.max = size
self.data = [None]*self.max
self.num = 0 # 表中元素的个数
def is_empty(self): # 判断线性表是否为空
return self.num is 0
def is_full(self): # 判断线性表是否为满
return self.num is self.max
def length(self): # 返回线性表中元素的个数
return self.num
def append(self.value): # 在表尾插入一个元素
if self.num > self.max:
print("List is full.")
else:
self.data[self.num] = value
self.num += 1
def prepend(self.value): # 在表头位置插入一个元素
if self.num >= self.max:
print("List is full")
else:
for i in range(self.num, 0, -1):
self.data[i] = self.data[i-1] # 每个元素往后移一位
self.data[0] = value
self.num += 1
def reverse(self): # 逆转顺序表的顺序
i = 0
number = self.num-1
while i <= number:
self.prepend(self.data.pop(i))
i += 1
return self.data
2. 链表(Linked List)
数据元素存放在任意的存储单元中,这组存储单元可以是连续的,也可以是不连续的。
通过指针域来反映数据元素的逻辑关系。
链表是一种物理存储单元上非连续、非顺序的存储结构。
数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
按位查找:链表的时间为O(n),是顺序存取。
插入和删除:链表不需要移动元素,在给出某个合适位置的指针后,插入和删除所需时间为O(1)。
(1)单链表
每个结点只设置一个指向其后继结点的指针成员,这样的链表简称单链表。
基本操作:
1)插入和删除结点操作
2)整体建立单链表(头插法和尾插法)
头插法:
尾插法:
以下代码是线性表的基本操作:
class SingleNode: # 单链表的节点
def __init__(self, elem = None):
self.elem = elem # 存放数据
self.next = None # 下一个节点的链接
class SingleLinkList:
def __init__(self):
self.head = SingleNode()
self.head.next = None
def is_empty(self): # 判断单链表是否为空
return self.head.next == None
def length(self): # 获取链表长度
p = self.head
count = 0
while p != None:
count += 1
p = p.next
return count
def traverse(self): # 遍历链表
p = self.head.next
while p != None:
print(p.elem, end=' ')
p = p.next
print('\n')
def prepend(self, elem): # 链表头添加元素
node = SingleNode(elem)
node.next = self.head.next
self.head.next = node
def append(self, elem): # 链表尾部添加元素
p = self.head
s = SingleNode(elem)
while p.next != None:
p = p.next
p.next = s
def locate_item(self, elem): # 找某个元素的下标
index = 0
p = self.head.next
while p != None:
if p.elem == elem:
return index
index += 1
p = p.next
def reverse(self): # 逆转链表
p = self.head.next
self.head.next = None
while p != None:
temp = p.next
p.next = self.head.next
self.head.next = p
p = temp
lst = []
cur = self.head.next
while cur != None:
lst.append(cur.elem)
cur = cur.next
return lst
(2)双链表
如果每个结点中设置两个指针成员,分别用以指向其前驱结点和后继结点,这样的链表简称双链表。
基本操作:与单链表类似,设计结点插入和删除的操作改为双链表方式即可。
1. 插入和删除结点操作
插入结点操作:将结点s插入到双链表中p结点的后面
删除结点操作:删除双链表中的p结点
2. 整体建立双链表
头插法和尾插法