数据结构算法

2018-06-07  本文已影响20人  shenyoujian

1、什么是线性数据结构:

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

2、有哪些线性数据结构:

栈,队列,deques,列表

3、栈:

# -*- utf8 -*-
# Stack.py
'''
用python实现栈
实现一个栈类,用列表做底层实现
'''

class Stack:
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def push(self, item):
        self.items.append(item)

    def pop(self):
        return self.items.pop()

    def peek(self):
        return self.items[len(self.items)-1]

    def size(self):
        return len(self.items)


s = Stack()
print(s.isEmpty())
s.push(4)
s.push('dog')
print(s.size())
print(s.peek())
print(s.isEmpty())
print(s.pop())
print(s.size())

4、栈的实际应用,简单括号匹配

'''
栈的实际应用,简单括号匹配
匹配
(()()()())
(((())))
(()((())()))
不匹配
((((((())
()))
(()()(()
大概思路就是把括号们从左到右先判断,如果是左括号{,就入栈
如果是}就出栈,从内到外匹配。例如{}这个,先是{入栈,然后是}就把栈里的{出栈与}匹配
最后所有符号都被处理后并且栈也是空就说明匹配成功了。
'''

def parChecker(symbolString):
    # 先实例化一个空栈
    s = Stack()
    balanced = True
    index = 0
    while index < len(symbolString) and balanced:
        symbol = symbolString[index]
        if symbol == '{':
            s.push(symbol)
        else:
            if s.isEmpty():
                balanced = False
            else:
                s.pop()

        index = index + 1

    if balanced and s.isEmpty():
        return True
    else:
        return False

print(parChecker('{{{}}}'))
print(parChecker('{{}'))

# True
# False

'''
栈的实际应用,符号匹配。
不仅每个开始符号都有对应的结束符号,而且符号的类型也匹配。
匹配
{ { ( [ ] [ ] ) } ( ) }
[ [ { { ( ( ) ) } } ] ]
[ ] [ ] [ ] ( ) { }
不匹配
( [ ) ]
( ( ( ) ] ) )
[ { ( ) ]
大概思路就是每个开始符号入栈,当出现结束符号,检查该结束符号
是否正确匹配栈顶部开始符号的类型。如果两个符号不匹配,则整个字符串不匹配,
如果整个字符串都被处理完并且空栈,则字符串匹配。
'''
def parChecker2(symbolString):
    s = Stack()
    balanced = True
    index = 0
    while index > len(symbolString) and balanced:
        symbol = symbolString[index]
        if symbol in "{[(":
            s.push(symbol)
        else:
            if s.isEmpty():
                balanced = False
            else:
                top = s.pop()
                if not matches(top, symbol):
                    balanced = False

        index = index + 1
    if balanced and s.isEmpty():
        return True
    else:
        return False

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

'''

5、栈的实际应用:十进制转换二进制

image.png
'''
栈的实际应用:十进制转换二进制
计算机内的所有值都是以0和1存储的,例如:十进制 233 对应的二进制表示 11101001, 
2*10^2 + 3*10^1 + 3*10^0
1*2^7 + 1*2^6 + 1*2^5 + 1*2^4 + 1*2^3 + 1*2^2 + 1*2^1 + 1*2^0
计算机使用除2算法,并且用栈来跟踪二进制结果的数字
大概思路就是:传入一个十进制的参数,并重复除以2,然后使用内置%提取余数,把余数入栈,当除到0后,再出栈构造二进制字符串
'''

def divideBy2(decNumber):
    remstack = Stack()

    while decNumber > 0:
        rem = decNumber % 2
        remstack.push(rem)
        decNumber = decNumber//2


    binString = ""
    while not remstack.isEmpty():
        binString = binString + str(remstack.pop())

    return binString

print(divideBy2(42))

# 101010

'''
栈的实际应用:十进制和基数的转换
例如:233对应的八进制351和十六进制E9
3*8^2 + 5*8^1 + 1*8^0
14*16^ + 9*16^0
大概思路:增加一个基数的参数,把除2换成除基数,然后余数继续入栈,除到0就开始出栈,
不同的是余数会大于9,然后先创建一组数字来表示超过9的余数,在下标取值。
'''

def baseConverter(decNumber, base):
    digits = "0123456789ABCDEF"

    remstack = Stack()

    while decNumber > 0:
        rem = decNumber % base
        remstack.push(rem)
        decNumber = decNumber // base

    newString = ""
    while not remstack.isEmpty():
        newString = newString + digits[remstack.pop()]

    return newString

print(baseConverter(25,2))
print(baseConverter(25,16))

# 11001
# 19

6、栈的实际应用:中缀转后缀

image.png
def infixToPostfix(infixexpr):
    prec = {}                                               # 使用一个字典来保存操作符的优先级,左括号被赋予最低的值,
    prec["*"] = 3                                           # 这样与其进行比较的任何运算符将具有更高的优先级,将被放置在它的顶部
    prec["/"] = 3
    prec["+"] = 2
    prec["-"] = 2
    prec["("] = 1
    opStack = Stack()                                       # 中间件
    postfixList = []                                        # 最终表达式的存储列表
    tokenList = infixexpr.split()                           # 把传进来表达式进行拆分

    for token in tokenList:
        if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or token in "0123456789":
            postfixList.append(token)
        elif token == '(':
            opStack.push(token)
        elif token == ')':                                  # 遇到右括号就出栈
             topToken = opStack.pop()       
             while topToken != '(':                         # 出栈的如果不是左括号就添加到输出列表
                postfixList.append(topToken)
                topToken = opStack.pop()                    # 直到出栈是左括号为止
        else:
            while(not opStack.isEmpty()) and \
                (prec[opStack.peek()] >= prec[token]):      # 如果是运算符,就去判断栈是否为空,不为空就判断栈顶与token的优先级
                    postfixList.append(opStack.pop())       # 栈顶的运算符比token高就出栈加入输出列表

            opStack.push(token)                             # 否则入栈

    while not opStack.isEmpty():
        postfixList.append(opStack.pop())
    return "".join(postfixList)

print(infixToPostfix("A * B + C * D"))
print(infixToPostfix("( A + B ) * C - ( D - E ) * ( F + G )"))

# AB*CD*+
# AB+C*DE-FG+*-

7、栈的实际应用:后缀表达式求值

image.png
'''
栈的实际应用:后缀表达式求值
做完上面的中缀转换后缀之后,就可以来求表达式的值,选择的数据结构还是栈。
大概思路:遇到操作数就入栈,遇到运算符就出栈两个然后运算后再入栈。注意除法不是交换运算符,先出栈的为被除数,后出栈的为除数。
1、创建一个名为operandStank的空栈
2、拆分字符串转换为标记列表。
3、从左到右扫描标记列表
    - 如果标记是操作数,将其从字符串转换为整数,并将值压到operandStack。
    - 如果标记是运算符 *,/,+ 或 - ,它将需要两个操作数。弹出operandStack 两次。
        第一个弹出的是第二个操作数,第二个弹出的是第一个操作数。执行算术运算后,
        将结果压到操作数栈中。
4. 当输入的表达式被完全处理后,结果就在栈上,弹出 operandStack 并返回值。
'''

def postfixEval(postfixExpr):
    operandStack = Stack()
    tokenList = postfixExpr.split()

    for token in tokenList:
        if token in "0123456789":
            operandStack.push(int(token))
        else:
            operand2 = operandStack.pop()
            operand1 = operandStack.pop()
            result = doMath(token, operand1, operand2)  
            operandStack.push(result)               
    return operandStack.pop()

def doMath(token, operand1, operand2):
    if token == "*":
        return operand1 * operand2
    elif token == "/":
        return operand1 / operand2
    elif token == "+":
        return operand1 + operand2
    else:
        return operand1 - operand2

print(postfixEval('7 8 + 3 2 + /'))

# 3.0
上一篇 下一篇

猜你喜欢

热点阅读