文章目录
一、无序表(unordered list)抽象数据类型
1. 无序表的定义
列表是一种数据项按照相对位置存放的数据集,有时也称为“无序表unordered list”,其中数据项只按照存放位置来索引,如第1个、第2个……、最后一个等。
如一个考试分数的集合“54, 26, 93, 17, 77和31”,如果用无序表来表示,就是[54, 26, 93, 17, 77, 31]。
2. 采用链表实现无序表
虽然列表数据结构要求保持数据项的前后相对位置,但这种前后位置的保持,并不要求数据项依次存放在连续的物理存储空间。
因此,我们可以采用链表的结构来实现无序表。
(1)链表
如下图,链表中的数据项存放位置并没有规则,通过在数据项之间建立链接指向,来保持其前后相对位置。
第一个和最后一个数据项需要显式标记出来,一个是队首,一个是队尾。
(2)链表节点
链表实现的最基本元素是节点Node,上图中的head、54、93、end等,就是链表的一个个节点。
每个节点至少要包含2个信息:数据项本身(data),以及指向下一个节点的引用信息(next)。
注意:next为None时,表示没有下一个节点了!
(3)python实现链表节点
class Node:
def __init__(self):
self.data = init_data
self.next = None
def get_data(self):
"""返回当前节点的数据"""
return self.data
def get_next(self):
"""返回下一个节点的地址"""
return self.next
def set_data(self, new_data):
"""修改节点数据"""
self.data = new_data
def set_next(self, new_next):
"""修改下一节点的地址"""
self.next = new_next
(4)python实现链表
先来分析一下步骤:
-
链表的第一个和最后一个节点最重要:
如果想访问到链表中的所有节点,就必须从第一个节点开始沿着链接遍历下去。所以无序表必须要有对第一个节点的引用信息。
-
添加数据项:
由于无序表并没有限定数据项之间的顺序,出于对性能的考虑,应添加到表头head节点上。
注意:两步的顺序不要搞反!否则会丢失head对节点93的引用。
-
统计数据项的数量:
从链表头head开始遍历到表尾同时用变量累加经过的节点个数。
-
搜索数据项是否在链表中:
从链表头head开始遍历到表尾,同时判断当前节点的数据项是否目标。
-
移除数据项:
首先要找到item,这个过程跟上面的的搜索方法一样,但在删除节点时,需要特别的技巧。
需要把前一个节点的next指向current的下一个节点。
完整的代码如下:
class UnorderedList:
def __init__(self):
self.head = None
def is_empty(self):
"""判断链表是否为空"""
return self.head == None
def add(self,item):
"""添加数据项"""
temp = Node(item)
# 步骤顺序千万不要搞错
temp.set_next(self.head)
self.head = temp
def size(self):
"""返回链表大小"""
current = self.head
count = 0
while current != None:
count = count + 1
current = current.get_next()
return count
def search(self,item):
"""查询链表是否包含指定数据项"""
current = self.head
found = False
while current != None and not found:
if current.get_data() == item:
found = True
else:
current = current.get_next()
return found
def remove(self,item):
"""移除指定元素"""
current = self.head
previous = None
found = False
while not found:
if current.get_data() == item:
found = True
else:
previous = current
current = current.get_next()
if previous == None:
self.head = current.get_next()
else:
previous.set_next(current.get_next())
二、有序表(Ordered List)抽象数据类型
1. 有序表的定义
有序表是一种数据项依照其某可比性质(如整数大小、字母表先后)来决定在列表中的位置。
2. 使用python实现有序表
下面对数据项的讨论并不仅适用于整数,可适用于所有定义了
__gt__
方法(即>
操作符)的数据类型。
同样采用链表方法实现有序表,Node定义相同。需要记住的是,数据项的相对位置,取决于它们之间的“大小”比较。
有序表的节点与无序表的一样,并且大部分方法与无序表的方法也一样,只有search方法和add方法有所不同:
search方法:
-
在无序表的search中,如果需要查找的数据项不存在,则会搜遍整个链表,直到表尾;
-
对于有序表来说,可以利用链表节点有序排列的特性,来为search节省不存在数据项的查找时间。
一旦当前节点的数据项大于(或小于)所要查找的数据项,则说明链表后面已经不可能再有要查找的数据项,可以直接返回False。
def search(self,item): current = self.head found = False stop = False while current != None and not found and not stop: if current.get_data() == item: found = True else: if current.get_data() > item: stop = True else: current = current.get_next()
add方法:
-
相比无序表,有序表添加数据项时,必须保证加入的数据项添加在合适的位置,以维护整个链表的有序性。
-
以从小到大的顺序为例:需要先找到恰好大于新数据项的数据项,然后将新数据项插入该数据项的前面。
def add(self,item): current = self.head previous = None stop = False while current != None and not stop: if current.get_data() > item: stop = True else: previous = current current = current.get_next() temp = Node(item) if previous == None: temp.set_next(self.head) self.head = temp else: temp.set_next(current) previous.set_next(temp)