zoukankan      html  css  js  c++  java
  • 重学数据结构之栈

    一、前言简介

      数据结构课程是一门重要的计算机基础课程,而我本人在上学期间真是没学好这门课, 听课总是听得云里雾里的,写起代码来也不知道如何编写和运用这些数据结构,以致于后来考试也只能是低分飘过,所以现在就需要花时间重新学习一下数据结构了!

      为了能够更好地学习和掌握数据结构,除了学习和理解相应的概念,我还会找几个题目并用所学的数据结构来解决问题,相应的问题和代码也会一并记录在博客中。

    二、栈的概念

    1.基本概念

      栈(stack)又被称为堆栈,是一种保存数据元素的容器。栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表,允许进行插入和删除操作的一端叫做栈顶(top),另一端则叫做栈底(bottom),插入元素一般称为进栈(PUSH),删除元素一般称为出栈(POP)。

      栈按照后进先出的原则(LIFO, Last In First Out)存储数据,后存入的元素会先被取出来使用。存入栈中的元素相互之间并没有任何具体的关系,只有存入的时间先后顺序,而没有元素的前后顺序或者元素的位置等概念。

    2.抽象数据类型

      栈的基本操作一个封闭的数据集合,在一个栈里需要实现将元素压入栈中即进栈、从栈中弹出元素即出栈、返回最后一个插入栈中的元素、获取栈中元素的数量等方法,下面就是一个栈的抽象数据类型描述:

    ADT Stack:

      Stack(self)  # 创建一个空栈

      empty(self)  # 判断栈是否为空

      push(self, x)  # 将元素压入栈中

      pop(self)  # 从栈中弹出元素

      peek(self)  # 返回最后一个插入的元素

      size(sellf)  # 获取栈中元素的数量

    3.用 Python 实现

      在 Python 中没有栈这种数据结构,但我们可以借助 list 来实现,用 list 来存放数据,并实现一个栈所需要的各种方法,具体代码如下:

     1 # 自定义栈
     2 class MyStack:
     3     def __init__(self):
     4         self.data = []
     5 
     6     def push(self, x):
     7         """
     8         将数据压入栈中
     9         :param x: 需要插入的元素
    10         :return: 
    11         """
    12         self.data.append(x)
    13 
    14     def pop(self):
    15         """
    16         从栈中弹出元素
    17         :return: 弹出的元素
    18         """
    19         if not self.empty():
    20             ret, self.data = self.data[-1], self.data[:-1]
    21             return ret
    22         return None
    23 
    24     def empty(self):
    25         """
    26         判断栈是否为空
    27         :return: 栈空--True,非空--False
    28         """
    29         return len(self.data) == 0
    30 
    31     def size(self):
    32         """
    33         获取栈中元素的数量
    34         :return: 
    35         """
    36         return len(self.data)
    37 
    38     def peek(self):
    39         """
    40         返回最后一个插入的元素
    41         :return: 最后一个插入的元素
    42         """
    43         if not self.empty():
    44             return self.data[-1]
    45         return None

    三、栈的应用

    1.进制转换

    1)问题描述

      输入一个任意的十进制正整数,将其转化成相应的二进制、八进制和十六进制的数。

    2)解决思路

      这里首先需要介绍一个公式:

    N = (N div d) * d + N mod d

      其中 div 表示整除,mod 表示求余。例如当输入的正整数 N 为777,输出的进制是八进制时,计算过程如下:

    N      N div 8    N mod 8

    777   97       1

    97     12       1

    12    1     4

    1      0     1  

      在进行进制转换的时候,我们就可以将每次求余的结果保存在栈中,最后将栈中的数依次取出,就是转换后的结果了,例如十进制的777转换成八进制就是1411。

    3)代码实现

      如何用代码来解决这个问题?一个思路就是将每次求余的结果保存在栈中,而整除的结果则用来进行下一步的计算,直到这个整除的结果为0,表明计算结束,再出栈中依次取出元素,得到的结果就是转换成相应进制后的数。具体代码如下:

     1 def solution(n: int, scale: int):
     2     """
     3     进制转换
     4     :param n: 正整数
     5     :param scale: 进制
     6     :return:
     7     """
     8     stack = MyStack()
     9     # 循环计算
    10     while n // scale >= 0 and n > 0:
    11         stack.push(n % scale)
    12         n = n // scale
    13     # 输出
    14     while not stack.empty():
    15         print(stack.pop(), end="")

    2.括号匹配

    1)问题描述

      输入一个字符串,里面可能有“()”、“[]”和“{}”三种括号,编写程序检查该字符串中的括号是否成对出现。

    2)解决思路

      遍历这个字符串,用栈来存放每次遍历的元素,如果遍历的元素和栈顶的括号是配对的,则进行出栈操作将栈顶元素弹出,反之若不配对,则进行入栈操作将该元素插入到栈中。等遍历结束后,若栈为空,则表明该字符串中的括号都是成对出现的,若栈不为空,则表明有括号不匹配。

    3)代码实现

     1 def solution(input_string: str):
     2     """
     3     判断输入的字符中的括号是否成对出现
     4     :param input_string: 输入字符串
     5     :return:
     6     """
     7     def match(c1: str, c2: str):
     8         """
     9         判断两个括号是否匹配
    10         :param c1: 
    11         :param c2: 
    12         :return: 
    13         """
    14         if c1 == "(" and c2 == ")":
    15             return True
    16         elif c1 == "[" and c2 == "]":
    17             return True
    18         elif c1 == "{" and c2 == "}":
    19             return True
    20         else:
    21             return False
    22 
    23     stack = MyStack()
    24     for i in range(len(input_string)):
    25         if stack.empty():
    26             # 栈空直接入栈
    27             stack.push(input_string[i])
    28         else:
    29             # 栈非空时进行比较
    30             if match(stack.peek(), input_string[i]):
    31                 stack.pop()
    32             else:
    33                 stack.push(input_string[i])
    34     print("匹配!") if stack.empty() else print("不匹配!")
  • 相关阅读:
    *** 82 删除排序链表中的重复元素II
    83 删除排序链表中的重复元素
    61 旋转链表
    ASP.NET MVC3 ModelState.IsValid为false的问题
    ServletContext
    ServletConfig
    Servlet线程安全
    Servlet的一些细节(2)
    Servlet的一些细节(1)
    Servlet的接口实现类
  • 原文地址:https://www.cnblogs.com/TM0831/p/12831061.html
Copyright © 2011-2022 走看看