赞
踩
列表是一种数据项按照相对位置存放的数据集,有时也称为“无序表unordered list”,其中数据项只按照存放位置来索引,如第1个、第2个……、最后一个等。
如一个考试分数的集合“54, 26, 93, 17, 77和31”,如果用无序表来表示,就是[54, 26, 93, 17, 77, 31]。
虽然列表数据结构要求保持数据项的前后相对位置,但这种前后位置的保持,并不要求数据项依次存放在连续的物理存储空间。
因此,我们可以采用链表的结构来实现无序表。
如下图,链表中的数据项存放位置并没有规则,通过在数据项之间建立链接指向,来保持其前后相对位置。
第一个和最后一个数据项需要显式标记出来,一个是队首,一个是队尾。
链表实现的最基本元素是节点Node,上图中的head、54、93、end等,就是链表的一个个节点。
每个节点至少要包含2个信息:数据项本身(data),以及指向下一个节点的引用信息(next)。
注意:next为None时,表示没有下一个节点了!
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
先来分析一下步骤:
链表的第一个和最后一个节点最重要:
如果想访问到链表中的所有节点,就必须从第一个节点开始沿着链接遍历下去。所以无序表必须要有对第一个节点的引用信息。
添加数据项:
由于无序表并没有限定数据项之间的顺序,出于对性能的考虑,应添加到表头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())
有序表是一种数据项依照其某可比性质(如整数大小、字母表先后)来决定在列表中的位置。
下面对数据项的讨论并不仅适用于整数,可适用于所有定义了
__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)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。