数据结构----读书笔记三(栈的知识点)
2017-12-25 12:47
411 查看
在这一节中,我会记录学习二种特殊形式的线性表,其中一种只能在一端进行操作,也就是只能在队尾进行插入删除操作的栈,还有一种是在一段进行插入(队伍尾巴)在另一端进行删除操作(队伍的前头)的队列。二者均是线性表。
栈
栈是只能在表尾进行插入删除操作,并且表尾被称为了栈顶,另一端被称为了栈底,不含任何元素的栈被称为空栈,栈的结构属于后进先出(LIFO)结构,所以被称为了后进先出表。
栈的结构是一个线性表,只不过是一个特殊的线性表,只是限制了插入删除的位置,即栈底是固定的,栈顶是变化的。
1,栈的顺序存储结构(顺序栈)
顺序存储结构中,一般以数组来作为存储的容器,bottom一般为数组的下标0那个位置,top为-1时表明空栈,top=0时表示有一个元素,top应小于stacksize的大小。
栈的顺序存储结构与一般的线性表的顺序存储没有很大的区别,有的区别在于操作只能在数组的尾端进行操作,也就是只能在栈顶进行操作,需要维持一个记录栈顶位置的变量。因为栈操作只涉及到的是栈顶元素的操作,所以,在插入删除操作时不涉及到大量元素的搬移的工作,时间复杂度为O(1)。
栈中可以通过共享空间来达到最大限度的利用事先开辟好的存储空间的目的。什么是共享空间?就是在一个空间比较大的数组中维护二个栈的操作,一个栈的栈底在数组下标为0的地方,一个栈的栈底在数组下标为n-1的地方,二者的栈顶元素来朝着中间方向来进行延伸。使用的前提在于,二者的数据类型是相同的,否则会使得问题变得复杂。
2,栈的链式存储结构(链栈)
栈的链式存储结构中头指针的存在,而栈顶变量也是必不可少的,可以使二者合二为一,并且栈顶在头部了,单链表中的头结点也就失去了意义,不需要头结点。
栈的链式存储结构中的进栈,出栈操作需要分配内存以及删除内存的操作,并且对于栈顶的指针进行操作即可。
栈的应用
1,递归程序,主要考虑的结束条件,不能无穷无尽的运行到底。
兔子的繁殖问题,主要是应用的斐波那契数列。利用递归以及迭代可以实现斐波那契数列。
对于迭代而言,主要利用的循环的结构,而对于递归则利用的是选择结构。
对于递归的操作,由栈的结构来实现。
2,四则运算表达式求值
四则运算利用栈的结构来实现,称为逆波兰表示,也可以称为后缀表达式,在后缀表达式中,遇到数字即压入栈,遇到字符则出栈,出栈一般由二维操作符,但如果栈已空,说明为一维操作符,这样就可以解决四则运算的苦恼。
我们一般的表示是中缀表达式,需要把中缀表达式转换为后缀表达式,具体转换的步骤如下:
从人的思维角度来说,比较容易可以实现这个步骤,先把数字写好,然后如果有先运算的,就在后面加个字符。
从规则的角度来说,对于数字则输出,对于符号则判断与栈顶元素的优先级判断是否出栈,一直到所有的表达式写完。以9+(3-1)*3+10/2为例。
1,初始化一个空栈。
2,对于字符串从左到右来进行处理,然后数字9则输出,对于+符号入栈,对于(则入栈,对于数字3则输出,对于符号-入栈,对于数字1输出,对于)符号需要将(之前的出栈,包括(符号,对于入栈,的优先级高于后面的数字3的+符号,所以输出数字3之后则+不能入栈,将*出栈,,+的优先级与栈顶的+优先级相同,所以+不入栈,输出+符号,输出数字10,然后对于/的优先级高于+则入栈,输出数字2,因为没有符号,则所有的符号均出栈。
顺序栈的实现代码(python)
利用顺序栈来实现中缀表达式转后缀表达式,实现四则运算
python来实现链栈,并且实现顺序栈的上述的功能
栈
栈是只能在表尾进行插入删除操作,并且表尾被称为了栈顶,另一端被称为了栈底,不含任何元素的栈被称为空栈,栈的结构属于后进先出(LIFO)结构,所以被称为了后进先出表。
栈的结构是一个线性表,只不过是一个特殊的线性表,只是限制了插入删除的位置,即栈底是固定的,栈顶是变化的。
1,栈的顺序存储结构(顺序栈)
顺序存储结构中,一般以数组来作为存储的容器,bottom一般为数组的下标0那个位置,top为-1时表明空栈,top=0时表示有一个元素,top应小于stacksize的大小。
栈的顺序存储结构与一般的线性表的顺序存储没有很大的区别,有的区别在于操作只能在数组的尾端进行操作,也就是只能在栈顶进行操作,需要维持一个记录栈顶位置的变量。因为栈操作只涉及到的是栈顶元素的操作,所以,在插入删除操作时不涉及到大量元素的搬移的工作,时间复杂度为O(1)。
栈中可以通过共享空间来达到最大限度的利用事先开辟好的存储空间的目的。什么是共享空间?就是在一个空间比较大的数组中维护二个栈的操作,一个栈的栈底在数组下标为0的地方,一个栈的栈底在数组下标为n-1的地方,二者的栈顶元素来朝着中间方向来进行延伸。使用的前提在于,二者的数据类型是相同的,否则会使得问题变得复杂。
2,栈的链式存储结构(链栈)
栈的链式存储结构中头指针的存在,而栈顶变量也是必不可少的,可以使二者合二为一,并且栈顶在头部了,单链表中的头结点也就失去了意义,不需要头结点。
栈的链式存储结构中的进栈,出栈操作需要分配内存以及删除内存的操作,并且对于栈顶的指针进行操作即可。
栈的应用
1,递归程序,主要考虑的结束条件,不能无穷无尽的运行到底。
兔子的繁殖问题,主要是应用的斐波那契数列。利用递归以及迭代可以实现斐波那契数列。
对于迭代而言,主要利用的循环的结构,而对于递归则利用的是选择结构。
对于递归的操作,由栈的结构来实现。
2,四则运算表达式求值
四则运算利用栈的结构来实现,称为逆波兰表示,也可以称为后缀表达式,在后缀表达式中,遇到数字即压入栈,遇到字符则出栈,出栈一般由二维操作符,但如果栈已空,说明为一维操作符,这样就可以解决四则运算的苦恼。
我们一般的表示是中缀表达式,需要把中缀表达式转换为后缀表达式,具体转换的步骤如下:
从人的思维角度来说,比较容易可以实现这个步骤,先把数字写好,然后如果有先运算的,就在后面加个字符。
从规则的角度来说,对于数字则输出,对于符号则判断与栈顶元素的优先级判断是否出栈,一直到所有的表达式写完。以9+(3-1)*3+10/2为例。
1,初始化一个空栈。
2,对于字符串从左到右来进行处理,然后数字9则输出,对于+符号入栈,对于(则入栈,对于数字3则输出,对于符号-入栈,对于数字1输出,对于)符号需要将(之前的出栈,包括(符号,对于入栈,的优先级高于后面的数字3的+符号,所以输出数字3之后则+不能入栈,将*出栈,,+的优先级与栈顶的+优先级相同,所以+不入栈,输出+符号,输出数字10,然后对于/的优先级高于+则入栈,输出数字2,因为没有符号,则所有的符号均出栈。
顺序栈的实现代码(python)
# -*- coding: utf-8 -*- class Stack_sq(): def __init__(self): self._list = [] self._top = -1 def is_empty(self): if self._top == -1: print "the stack is empty" else: print "the stack has data" def insert_one(self, data): self._list.append(data) self._top += 1 def delete_one(self): if self._top <= -1: print "can not delete data" self._list.pop() self._top -= 1 def read_stack(self): for i in self._list: print i, print "is all data" stack = Stack_sq() stack.is_empty() stack.insert_one(1) stack.insert_one(2) stack.insert_one(3) stack.read_stack() stack.delete_one() stack.read_stack()
利用顺序栈来实现中缀表达式转后缀表达式,实现四则运算
# -*- coding: utf-8 -*- class Stack_sq(): def __init__(self): self._list = [] self._top = -1 def is_empty(self): if self._top == -1: return 1 else: return 0 def get_length(self): length = self._top + 1 return length def insert_one(self, data): self._list.append(data) self._top += 1 def delete_one(self): if self._top <= -1: print "can not delete data" self._list.pop() self._top -= 1 def read_stack(self): for i in self._list: print i, print "is all data" def last_data(self): return self._list[self._top] def symbol2rank(str1): dict1 = {'+': 6, '-': 5, '*': 4, '/': 3, '(': 2, ')': 1} return dict1[str1] def rank2symbol(str2): dict2 = {'6': '+', '5': '-', '4': '*', '3': '/', '2': '(', '1': ')'} str2 = str(str2) return dict2[str2] def operation(s1, s2, s): if s == '+': sum = s2 + s1 elif s == '-': sum = s2 - s1 elif s == '*': sum = s2 * s1 elif s == '/': sum = s2 / s1 else: print "the expression is wrong" return sum def middle2behind(string): string1 = '' stack = Stack_sq() for s in string: if s in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']: string1 = string1 + s continue s = symbol2rank(s) while True: if s >= 2: if stack.is_empty() == 1: stack.insert_one(s) break else: s_l = stack.last_data() if s < s_l or s_l == 2: stack.insert_one(s) break elif s - s_l > 1: string1 = string1 + rank2symbol(s_l) stack.delete_one() else: string1 = string1 + rank2symbol(s) break if s == 1: s_l = stack.last_data() if s_l == 2: stack.delete_one() break else: string1 = string1 + rank2symbol(s_l) stack.delete_one() if stack.is_empty() == 1: break while True: if stack.is_empty() == 1: break s_l = stack.last_data() string1 = string1 + rank2symbol(s_l) stack.delete_one() return string1 def four_operation(string): stack = Stack_sq() sum = 0 for s in string: if s in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']: stack.insert_one(int(s)) else: length = stack.get_length() if length < 2: print "the expression is wrong!" return False s_l = stack.last_data() stack.delete_one() s_ll = stack.last_data() stack.delete_one() sum = operation(s_l, s_ll, s) stack.insert_one(sum) sum_all = stack.last_data() return sum_all r = "8+3*5+6*(6+8*3)/2" r1 = middle2behind(r) sum = four_operation(r1) print sum # 8+3*5+6*(6+8*3)/2的中缀表达式向后缀表达式的转换,并实现四则运算
python来实现链栈,并且实现顺序栈的上述的功能
# -*- coding: utf-8 -*- class Node(): def __init__(self, data): self._data = data self._next = None class Stack_link(): def __init__(self): self._head = Node(data=-1) self._top = self._head def is_empty(self): if self._head._data == -1: return 1 else: return 0 def insert_one(self, data): a = Node(data) p = self._head while True: if p == self._top: p._next = a self._top = a self._head._data += 1 break else: p = p._next def delete_one(self): p = self._head while True: if self._head == -1: print "stack is empty" break else: if p._next == self._top: p._next = None self._top = p self._head._data -= 1 break else: p = p._next def last_data(self): last_data = self._top._data return last_data def get_length(self): length = self._head._data + 1 return length def symbol2rank(str1): dict1 = {'+': 6, '-': 5, '*': 4, '/': 3, '(': 2, ')': 1} return dict1[str1] def rank2symbol(str2): dict2 = {'6': '+', '5': '-', '4': '*', '3': '/', '2': '(', '1': ')'} str2 = str(str2) return dict2[str2] def operation(s1, s2, s): if s == '+': sum = s2 + s1 elif s == '-': sum = s2 - s1 elif s == '*': sum = s2 * s1 elif s == '/': sum = s2 / s1 else: print "the expression is wrong" return sum def middle2behind(string): string1 = '' # stack = Stack_sq() stack = Stack_link() for s in string: if s in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']: string1 = string1 + s continue s = symbol2rank(s) while True: if s >= 2: if stack.is_empty() == 1: stack.insert_one(s) break else: s_l = stack.last_data() if s < s_l or s_l == 2: stack.insert_one(data=s) break elif s - s_l > 1: string1 = string1 + rank2symbol(s_l) stack.delete_one() else: string1 = string1 + rank2symbol(s) break if s == 1: s_l = stack.last_data() if s_l == 2: stack.delete_one() break else: string1 = string1 + rank2symbol(s_l) stack.delete_one() if stack.is_empty() == 1: break while True: if stack.is_empty() == 1: break s_l = stack.last_data() string1 = string1 + rank2symbol(s_l) stack.delete_one() return string1 def four_operation(string): stack = Stack_sq() sum = 0 for s in string: if s in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']: stack.insert_one(int(s)) else: length = stack.get_length() if length < 2: print "the expression is wrong!" return False s_l = stack.last_data() stack.delete_one() s_ll = stack.last_data() stack.delete_one() sum = operation(s_l, s_ll, s) stack.insert_one(sum) sum_all = stack.last_data() return sum_all # 实现四则运算8+3*5+6*(7+8)/2的中缀表达式向后缀表达式的转换 r = "8+3*5+6*(6+8*3)/2" r1 = middle2behind(r) sum = four_operation(r1) print sum # 测试链栈是否正常工作 # stack = Stack_link() # stack.insert_one(3) # stack.insert_one(3) # stack.insert_one(4) # a = stack.last_data() # stack.delete_one() # print a
相关文章推荐
- 数据结构----读书笔记二(线性表的知识点)
- 数据结构------读书笔记四(队列的知识点)
- 各种数据结构的知识点归纳
- 【读书笔记】《框架设计(第2版)CLR Via C#》中两个比较有趣的知识点(转)(good)
- 数据结构基本知识点
- [置顶] 数据结构知识点总结--排序
- [数据结构]第五章-数组和广义表(读书笔记3)
- 数据结构小知识点整理
- [数据结构]第六章-树和二叉树(读书笔记3)
- 数据结构一些知识点备忘
- 数据结构一些知识点备忘
- 数据结构基本知识点
- 《Linux内核设计与实现》读书笔记(六)- 内核数据结构
- 数据结构读书笔记
- 数据结构面试知识点整理
- 读书笔记——数据结构(2)算法分析
- C++基本知识点(读书笔记)
- 《数据结构》第三章 知识点结构导图
- 数据结构一些知识点备忘
- 数据结构一些知识点备忘