数据结构:线性数据结构(1)-栈(栈,队列,deques, 列表)

版权声明:作者:Rookiekk 联系邮箱:[email protected] 欢迎转载或分享,但请务必声明文章出处。 https://blog.csdn.net/qq_18888869/article/details/88086002

栈,队列,deques, 列表是一类容器,他们数据项之间的顺序由添加或删除的顺序决定,一旦一个数据项被添加,它相对于前后元素一直保持该位置不变。注入此类的数据结构称为线性数据结构。

栈(栈,队列,deques, 列表)是一个项的有序集合:栈的底部很重要,因为在栈中靠近底部的项是存储时间最长的。最近添加的项是最先会被移除的。这种排序原则有时被称为 LIFO,后进先出。

1.栈的抽象数据类型

栈被构造为项的有序集合,其中项被添加和从末端一处的位置称为顶部,栈是有序的LIFO。栈操作如下:

  • Stack()创建一个空的新栈。它不需要参数,并返回一个空栈。
  • push(item)将一个新项添加到栈的顶部。它需要item做参数并不返回任何内容。
  • pop()从栈中删除顶部项。它不需要参数并返回item。栈被修改。
  • peek()从栈返回顶部项,但不会删除它。不需要参数,不修改栈。
  • isEmpty()测试栈是否为空。不需要参数,并返回boolean值。
  • size()返回栈中的item数量。不需要参数,并返回一个整数。

2.python实现栈

#栈
class Stack(object):
    def __init__(self, ):
        self.items = list() 
    
    def isEmpty(self):
        return self.items == []
    def size(self):
        return len(self.items)
    def push(self, item):
        self.items.append( item)
    def pop(self):
        return self.items.pop()
    def peek(self):
        return self.items[-1]

3.实例应用 

3.1括号匹配

# 判断括号匹配
def parChecker(symbolString):
    s = Stack()
    balance = True
    index = 0
    
    while index < len(symbolString) and balance:
        symbol = symbolString[index]
        if symbol in '([{':
            s.push(symbol)
        else:
            if s.isEmpty():
                balance = False
                break
            else:
                top = s.pop()
                if not matches(top, symbol):
                    balance = False
        index += 1
        
    if balance and s.isEmpty():
        return True
    else:
        return False

def matches(open,close):
    opens = "([{"
    closers = ")]}"
    return opens.index(open) == closers.index(close)
    
print(parChecker('[(()){}]'))
print(parChecker(''))
print(parChecker('()()))'))
print(parChecker('[{}]('))

 3.2十进制转二进制

#十进制转二进制
def dec2bin(num):
    s = Stack()
    while num > 0:
        r = num % 2
        s.push(r)
        num //= 2
    binstring = ''
    while not s.isEmpty():
        binstring = binstring + str(s.pop())
    
    return binstring
dec2bin(233)

3.3中缀前缀和后缀表达式 

中缀转换为后缀的算法:

首先假设中缀表达式是一个由空格分隔的标记字符串。 操作符标记是*,/,+和 - ,以及左右括号。操作数是单字符 A,B,C 等。 以下步骤将后缀顺序生成一个字符串。

  1. 创建一个名为 opstack 的空栈以保存运算符。给输出创建一个空列表。
  2. 通过使用字符串方法拆分将输入的中缀字符串转换为标记列表。
  3. 从左到右扫描标记列表。
    • 如果标记是操作数,将其附加到输出列表的末尾。
    • 如果标记是左括号,将其压到 opstack 上。
    • 如果标记是右括号,则弹出 opstack,直到删除相应的左括号。将每个运算符附加到输出列表的末尾。
    • 如果标记是运算符,*,/,+或 - ,将其压入 opstack。但是,首先删除已经在 opstack 中具有更高或相等优先级的任何运算符,并将它们加到输出列表中。
  4. 当输入表达式被完全处理时,检查 opstack。仍然在栈上的任何运算符都可以删除并加到输出列表的末尾。

下图展示了对表达式 A * B + C * D 的转换算法。

3.9.中ç¼åç¼ååç¼è¡¨è¾¾å¼.figure9

#中缀表达式转换为后缀表达式
def infix2Posfix(exp):
    prec = {}
    prec['('] = 1
    prec['+'] = 2
    prec['-'] = 2
    prec['*'] = 3
    prec['/'] = 3
    s = Stack()
    postfixList = []
    tokenList = exp.split()
    print(tokenList)
    for token in tokenList:
#         print(token)
        if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or token in "0123456789":
            postfixList.append(token)
        elif token == '(':
            s.push(token)
        elif token == ')':
            top = s.pop()
            while top != '(':
                postfixList.append(top)
                top = s.pop()
#             s.pop()
        else:
#             top = s.peek()
            while (not s.isEmpty() and prec[token] <= prec[s.peek()] ):
                postfixList.append(s.pop())
#                 print(s.size())
                
            s.push(token)
    while not s.isEmpty():
        postfixList.append(s.pop())
    
    return ' '.join(postfixList)

s = 'A * B + C * D'
s1 = 'A + B * C + D'
s2 = '( A + B ) * ( C + D )'
print(infix2Posfix(s))
print(infix2Posfix(s1))
print(infix2Posfix(s2))

 后缀表达式求值:

假设后缀表达式是一个由空格分隔的标记字符串。 运算符为*,/,+和 - ,操作数假定为单个整数值。 输出将是一个整数结果。

  1. 创建一个名为 operandStack 的空栈。
  2. 拆分字符串转换为标记列表。
  3. 从左到右扫描标记列表。
    • 如果标记是操作数,将其从字符串转换为整数,并将值压到operandStack。
    • 如果标记是运算符*,/,+-,它将需要两个操作数。弹出operandStack 两次。 第一个弹出的是第二个操作数,第二个弹出的是第一个操作数。执行算术运算后,将结果压到操作数栈中。
  4. 当输入的表达式被完全处理后,结果就在栈上,弹出 operandStack 并返回值。
    #后缀表达式求值
    def postfixEval(postfixexp):
        s = Stack()
        postfixList = postfixexp.split()
        for token in postfixList:
            if token in '+-*/':
                op2 = s.pop()
                op1 = s.pop()
                val = doMath(token, int(op1), int(op2))
                s.push(val)
            else:
                s.push(token)
            
        return s.pop()
    
    def doMath(op, op1, op2):
        if op == "*":
            return op1 * op2
        elif op == "/":
            return op1 / op2
        elif op == "+":
            return op1 + op2
        else:
            return op1 - op2       
    
    print(postfixEval('7 8 + 3 2 + /'))

    其他线性数据结构:

队列:https://blog.csdn.net/qq_18888869/article/details/88134592

列表(链表):https://blog.csdn.net/qq_18888869/article/details/88138785

deque:https://blog.csdn.net/qq_18888869/article/details/88137237

github代码:https://github.com/makang101/python-data-structure

参考:

problem-solving-with-algorithms-and-data-structure-using-python 中文版

数据结构(C语言版)严蔚敏

猜你喜欢

转载自blog.csdn.net/qq_18888869/article/details/88086002