您的位置:首页 > 理论基础 > 数据结构算法

python 下的数据结构与算法---4:线形数据结构,栈,队列,双端队列,列表

2016-03-24 21:32 666 查看
目录:

前言

1:栈

  1.1:栈的实现

  1.2:栈的应用:

    1.2.1:检验数学表达式的括号匹配

    1.2.2:将十进制数转化为任意进制

    1.2.3:后置表达式的生成及其计算

2:队列

  2.1:队列的实现

  2.2:队列的应用之囚徒问题

3:双端队列

  3.1:双端队列的实现

  3.2:双端队列的应用之回文检测

4:列表

  3.1:链表的实现

前言

  线性数据结构有四种:栈(stack),队列(queue),双端队列(deque),列表(list)

  线性数据结构就是一群数据的集合,数据的位置和其加入的先后顺序有关,并且由此将其看为有两端,头(top)与尾(rear)【其中认为头是最先加入的数据,尾是最后加入的数据】

一:栈(stack)

1:栈的构造

  栈可以看成是堆盘子,只能从上端加入以及从上端取出,也就是只能从一端对其进行操作。对应到线形结构就是只能在尾部对其进行加入与删除的数据结构。简称LIFO(last in first out),即是后进先出。

  习惯上我们把栈尾部叫做栈顶(TOP),加入数据叫做压栈(push),删除叫做出栈(pop)

  要注意一点的是,此处的栈顶其实是list的队尾,理论上将两个top对应起来也是简单的,但是前面讲过list的insert(0,i)与pop(0)都是O(n)的操作,而末尾的append(i)与pop(i)都是O(1),故依旧选择后者。

class LinkedList:

class __Node:
def __init__(self, item, next = None):
self.item = item
self.next = next

def getItem(self):
return self.item

def setItem(self, item):
self.item = item

def setNext(self,next):
self.next = next

def getNext(self):
return self.next

def __init__(self,contents=[]):
self.first = LinkedList.__Node(None,None)
self.last = self.first
self.numItems = 0
for i,e in enumerate(contents):
if i == 1:
self.first = self.first.getNext()
self.append(e)

def append(self,item):
node = LinkedList.__Node(item)
self.last.setNext(node)
self.last = node
self.numItems += 1

def __getitem__(self,index):
if index >= 0 and index < self.numItems:
cursor = self.first.getNext()
for i in range(index):
cursor = cursor.getNext()
return cursor.getItem()

raise IndexError("LinkedList index out of range")

def __setitem__(self,index,val):
if index >= 0 and index < self.numItems:
cursor = self.first.getNext()
for i in range(index):
cursor = cursor.getNext()
cursor.setItem(val)
return

raise IndexError("LinkedList assignment index out of range")

def __add__(self,other):
if type(self) != type(other):
raise TypeError("Concatenate undefined for " + str(type(self)) + " + " + str(type(other)))
result = LinkedList()
cursor = self.first.getNext()
while cursor != None:
result.append(cursor.getItem())
cursor = cursor.getNext()

cursor = other.first.getNext()

while cursor != None:
result.append(cursor.getItem())
cursor = cursor.getNext()
return result

def insert(self,index,item):
cursor = self.first
if index < self.numItems:
for i in range(index):
cursor = cursor.getNext()

node = LinkedList.__Node(item, cursor.getNext())
cursor.setNext(node)
self.numItems += 1
else:
self.append(item)

linkedlist = LinkedList([1,2,3,4,5])
linkedlist2 = LinkedList([9,8,7,6])
print(linkedlist.first.item)

print(linkedlist[2])
linkedlist.append('append')
linkedlist.insert(2,'insert')
linkedlist += linkedlist2
for i in linkedlist:
print(i)


链表的实现
  其实这个程序有点小问题不知你发现没有,我也是刚发现的,其实就是first指标其实一直指向了一个空节点。通过实例.getnext()才能够获得真正的第一个节点。

将(*)部分改成如下即可:

for i,e in enumerate(contents):
if i == 1:
self.first = self.first.getNext()
self.append(e)


  需要注意的是linked list的性质就和list完全不一样了,我们回顾一下,list的访问元素时间都是O(1),中间插入元素为O(k)[k为插入位置后面有的元素数],而linked元素的位置由于是相对的,访问元素需要从first开始依次查找,故时间为O(k)[k为寻找元素前面的元素个数],插入元素则比较简单,改变下两个next指向就行了,所以为O(1),好吧,不开玩笑了,其实不是这样的,插入元素前需要先从头开始找到插入元素前的节点,而此为O(k),是更高阶,所有还是为O(k),好吧,其实上面两个都对,o(1)情况是若linked list无序时,直接加到最后,O(k)是若是有序的,则需要从头开始比较比它小的k个数后再放入。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: