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),故依旧选择后者。
链表的实现
其实这个程序有点小问题不知你发现没有,我也是刚发现的,其实就是first指标其实一直指向了一个空节点。通过实例.getnext()才能够获得真正的第一个节点。
将(*)部分改成如下即可:
需要注意的是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个数后再放入。
前言
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个数后再放入。
相关文章推荐
- 1.8-Redis数据结构
- 数据结构课设 银行排队问题之单队列多窗口服务
- hdu 1542 线段树之扫描线之面积并
- 贪心(数据结构):COGS 468. [NOI2010]超级钢琴
- 数据结构2.2
- 数据结构上机2.1
- 算法和数据结构学习笔记
- 图的深度优先遍历--数据结构做得
- 大话数据结构—散列表查找(哈希表)
- 数据结构课设 词频统计
- redis基本数据结构之压缩列表
- 从零开始_学_数据结构(三)——树的初步应用
- ZOJ 3587 扩展KMP应用
- 数据结构学习笔记03队列
- 【数据结构】关于二分法
- 【数据结构】关于二分法
- 虚拟文件系统中的数据结构(fs_struct、files_struct)
- hdu 3954(线段树区间更新)
- [LeetCode][数据结构]Implement Queue using Stacks
- 图的广度优先遍历,运用了数据结构,感觉非常好用,等会把深度优先遍历也用数据结构写一遍