有序表是一种数据项依照其某可比性质(如整数大小,字母前后)来决定在列表中的位置
越小的数据项越靠近列表的头,越靠前
node的定义如上一讲一样
class Node:
def __init__(self,initdata):
self.data = initdata
self.next = None
def getData(self):
return self.data
def getNext(self):
return self.next
def setData(self,newdata):
self.data = newdata
def setNext(self,newnext):
self.next = newnext
ADT OList
- Olist():创建一个空的有序表
- add(item):在表中添加一个数据项,并保持整体顺序,此项原不存在
- remove(item):从有序表中移除一个数据项,此项应存在,有序表被修改
- search(item):在有序表中查找数据项,返回是否存在
- isEmpty():是否空表
- size():返回表中数据项的个数
- index(item):返回数据项在表中的位置,此项应存在
- pop():移除并返回有序表中最后一项,表中应至少存在一项
- pop(pos):移除并返回有序表中指定位置的数据项,此位置应存在
在实现有序表的时候,需要记住的是,数据项的相对位置,取决于它们之间的:"大小"比较
如下图
有序表Olist实现
- 同样采用链表方式实现
- Node定义相同
- Olist也设置一个head来保存链表表头
class Olist:
def __init__(self):
self.head = None
- 其中isEmpty/size/remove这些方法,与节点的次序无关,所以其实现跟Ulist是一样的.
def isEmpty(self):
return self.head == None
def size(self):
current = self.head
count = 0
while current != None:
count = count+1
current = current.getNext()
return count
def remove(self,item):
current = self.head
previous = None
found = False
while current != None and not found:
if current.getData() == item:
found = True
else:
previous = current
current = current.getNext()
if previous == None:
self.head = current.getNext()
else:
previous.setNext(current.getNext())
- search方法实现
在无序表的search中,如果需要查找的数据项不存在,则会搜遍整个链表,知道表尾
但是对于有序表来说,可以利用链表节点有序排列的特性,来为search节省不存在数据项的查询时间
一旦当前节点的数据项大于所要查找的数据项,则说明链表后面已经不可能再有要查找的数据项,可以直接返回False
如:我们如果想要在下面的表查找45
def search(self,item):
current = self.head
found = False
while current != None:
if current.getData() ==item:
found = True
break
else:
if current.getData()>item:
break
else:
current = current.getNext()
return found
- add方法
相比无序表,改变最大的方法是add,因为add方法必须保证加入的数据项添加在合适的位置,以维护整个链表的有序性
比如在(17,26,54,77,93)的有序表中,加入数据项31,我们需要沿着链表,找到第一个比31大的数据项54,将31插入到54的前面
由于涉及到的插入位置是当前节点之前,而链表无法得到"前驱"节点的引用,所以要跟remove方法类似,引入一个previous的引用,跟随当前节点current
,一旦找到首个比31大的数据项,previous就派上用场了
def add(self,item):
current = self.head
previous = None
N = Node(item)
while current != None:
if current.getData() > item:
found = True
break
else:
previous = current
current = current.getNext()
if previous == None:
N.setNext(self.head)
self.head = N
else:
N.setNext(current)
previous.setNext(N)
综上:
class Olist:
def __init__(self):
self.head = None
def isEmpty(self):
return self.head == None
def size(self):
current = self.head
count = 0
while current != None:
count = count+1
current = current.getNext()
return count
def remove(self,item):
current = self.head
previous = None
found = False
while current != None and not found:
if current.getData() == item:
found = True
else:
previous = current
current = current.getNext()
if previous == None:
self.head = current.getNext()
else:
previous.setNext(current.getNext())
def search(self,item):
current = self.head
found = False
while current != None:
if current.getData() ==item:
found = True
break
else:
if current.getData()>item:
break
else:
current = current.getNext()
return found
def add(self,item):
current = self.head
previous = None
N = Node(item)
while current != None:
if current.getData() > item:
found = True
break
else:
previous = current
current = current.getNext()
if previous == None:
N.setNext(self.head)
self.head = N
else:
N.setNext(current)
previous.setNext(N)
u=Olist()
u.add(45)
u.add(48)
u.add(86)
u.remove(48)
print(u.search(45))
print(u.search(86))
print(u.size())
线性结构小结
-
线性数据结构Linear DS将数据项以某种线性的次序组织起来
-
栈Stack维持了数据项的后进先出LIFO的次序
Stack的基本操作包括push,pop,isEmpty -
队列Queue维持了数据项先进先出FIFO的次序
Queue的基本操作包括enqueue,dequeue,isEmpty -
双端队列Deque可以同时具备栈和队列的功能
deque的主要操作包括addFront,addRear,removeFront,removeRear,isEmpty -
列表list是数据项能够维持相对位置的数据集
-
链表的实现,可以保持列表维持相对位置的特点,而不需要连续的存储空间
-
链表实现时,其各种方法,对链表头部head需要特别的处理