def:动态集合,由数学集合定义所衍生出来的,由算法操作的能增大,缩小或发生其他变化,我们称这样的集合是动态的。动态集合一般有如下操作:
10.1 栈和队列
def:栈是一种动态集合,在其上执行DELETE操作被删除的是最近插入的元素,实现的是一种先进后出的策略,被称为POP;INSERT操作被称为PUSH。其有一top属性指向最近插入的元素,当top<0时,栈中不包含任何元素,称栈是空的,若试图对一个空栈执行弹出操作,则称栈下溢。
class STACK():
def __init__(self, n):
self.stack = [None for i in range(n)]
self.top = -1
def __getitem__(self, key):
return self.stack[key]
def __setitem__(self, key, value):
self.stack[key] = value
def STACK_EMPTY(S):
if S.top == -1:
return True
else:
return False
def PUSH(S, x):
S.top = S.top + 1
S[S.top] = x
def POP(S):
if STACK_EMPTY(S):
raise("underflow")
else:
S.top = S.top - 1
return S[S.top + 1]
def:队列是一种动态集合,在其上执行DELETE操作被删除的是在集合中存在最久的元素,实现的是一种先进先出的策略,被称为DEQUEUE;INSERT操作被称为ENQUEUE。其有head属性指向队头元素,tail属性指向队尾元素(下一个新元素的位置)并在最后的位置环绕,head=tail时队列为空。
class QUEUE():
def __init__(self, n):
self.queue = [None for i in range(n)]
self.length = n
self.head = 0
self.tail = 0
def __getitem__(self, key):
return self.queue[key]
def __setitem__(self, key, value):
self.queue[key] = value
def ENQUEUE(Q, x):
Q[Q.tail] = x
if Q.tail == Q.length-1:
Q.tail = 0
else:
Q.tail = Q.tail + 1
def DEQUEUE(Q):
x = Q[Q.head]
if Q.head == Q.length -1:
Q.head = 0
else:
Q.head = Q.head + 1
return x
10.2 链表
def:链表是这样一种数据结构,对象中包含指针,各个对象按线性顺序排列,其顺序由各个对象里的指针决定。
链表元素通常包括关键字key,和两个指针prev和next,分别指向前一个元素与后一个元素,当prev指针为空时其为第一个元素,next指针为空时其为最后一个元素。而链表的head属性为指向第一个元素的指针。
链表根据时间使用情况有多种形式:1.单连接的,链表各个元素中不保护prev指针,只依赖于next指针决定对象的线性顺序。2.已排序的,链表的线性顺序与链表元素中关键字的线性顺序一致。3.循环链表,表头的prev指针指向最后一个元素,最后一个元素的next指向表头元素。
链表主要包含以下操作:search,线性查找第一个出现的关键字为k的元素;insert在链表头插入元素x;delete,删除链表中的元素x
class LISTNODE():
def __init__(self, key):
self.key = key
self.prev = None
self.next = None
class LIST():
def __init__(self):
self.head = None
def LIST_SEARCH(L, k):
"""
theta(n)
"""
x = L.head
while x != None and x.key != k:
x = x.next
return x
def LIST_INSERT(L, x):
"""
theta(1)
"""
x.next = L.head
if L.head != None:
L.head.prev = x
L.head = x
x.prev = None
def LIST_DELETE(L, x):
"""
theta(1)
"""
if x.prev != None:
x.prev.next = x.next
else:
L.head = x.next
if x.next != None:
x.next.prev = x.prev
def:哨兵(sentinel)是一个哑对象,其作用是简化边界条件的处理。在链表中加入哨兵,将链表变为双向循环链表,位于第一个元素和最后一个元素之间,取代head的作用。使得代码变得简洁,基本不能降低数据结构相关操作的渐近时间界,但可以减低常数因子。
class LISTNODE():
def __init__(self, key):
self.key = key
self.prev = None
self.next = None
class DL_LIST():
def __init__(self):
self.nil = LISTNODE(None)
self.nil.next = self.nil
self.nil.prev = self.nil
def DL_LIST_SEARCH(L, k):
x = L.nil.next
while x != L.nil and x.key != k:
x = x.next
return x
def DL_LIST_INSERT(L, x):
x.next = L.nil.next
L.nil.next.prev = x
L.nil.next = x
x.prev = L.nil
def DL_LIST_DELETE(L, x):
x.prev.next = x.next
x.next.prev = x.prev
在许多不存在对象只有数组的环境中,需要表达对象的概念可以通过数组来实现对象的表达。
对象的多数组表示:对于同构的一组对象,使用n个数组来表示其n个属性。通过访问不同数组的相同下标来访问下标所对应的同一个对象的不同属性。
对象的当数组表示:使用一个数组来保存不同对象的数据,对对象附加数据来保存下一个或上一个对象的下标,下标所指向的为对象的第一个属性的位置,其余属性通过偏移来访问。
对象的分配与释放:对象池的雏形,申请一大块内存用于保存对象,每次新加入的对象都从这块内存中分配,使用自由表作为垃圾收集器
class STACK():
def __init__(self, n):
self.next = [None for i in range(n)]
self.key = [None for i in range(n)]
self.prev = [None for i in range(n)]
self.free = self.INIT(n)
self.list = None
def INIT(self, n):
for i in range(n):
if i != 9:
self.next[i] = i + 1
if i != 0:
self.prev[i] = i - 1
return 0
def ALLOCATE_OBJECT(self):
if self.free == None:
raise("out of space")
else:
x = self.free
self.free = self.next[x]
return x
def FREE_OBJECT(self, x):
self.next[x] = self.free
self.free = x
def PUSH(self, value):
x = self.ALLOCATE_OBJECT()
self.key[x] = value
self.prev[x] = None
self.next[x] = self.list
if self.list != None:
self.prev[self.list] = x
self.list = x
def POP(self):
if self.list == None:
raise("underflow")
v = self.key[self.list]
x = self.next[self.list]
self.FREE_OBJECT(self.list)
self.list = x
return v
def PRINT(self):
x = self.list
print("list-----------------")
while x != None:
print("index is ",x, "value is ", self.key[x])
x = self.next[x]
y = self.free
print("free-----------------")
while y != None:
print("index is ", y)
y = self.next[y]
if __name__ == "__main__":
s = STACK(10)
for i in range(5):
s.PUSH(i+10)
s.PRINT()
input("")
for i in range(4):
print(s.POP())
s.PRINT()
10.4 有根树的表示