数据结构小记【Python/C++版】——栈篇

一,基础概念

栈是一种存放数据的线性结构容器,栈中的数据元素只能在同一端进行添加和删除等操作。

栈中被用来进行数据读写的一端被称作栈顶,无法进行任何操作的另一端被称为栈底。

元素在栈中的移动顺序依照后进先出(LIFO)原则,较早入栈的元素,更接近栈底,更晚被弹出。

栈结构在生活中的抽象模型有:酒店堆起来的盘子,书架上堆起来的书等,都是从最顶部开始取走和放回的。

二,栈的图示结构

三,栈的常见操作

push: 入栈操作,将数据从栈顶压入。

pop: 出栈操作,从栈顶弹出数据。

peek: 返回栈顶的数据而不删除它。

size: 返回栈中数据的数量。

isEmpty: 检查栈是否为空。

isFull: 检查栈是否已满。

四,栈的代码实现

1.Python语言实现

方式1.使用Python内置数据类型实现:

list, collections.deque, queue.LifoQueue

方式2.封装Stack类来实现

Demo.01:  基于list实现

stack = []

#基于append函数实现入栈操作
stack.append('a')
stack.append('b')
stack.append('c')

print('Initial stack:')
print(stack)

print('\nElements popped from stack:')

#基于pop函数实现出栈操作
print(stack.pop())
print(stack.pop())

print('\nStack after elements are popped:')
print(stack)

Demo.02:  基于deque实现

from collections import deque
stack = deque()

#基于append函数实现入栈操作
stack.append('a')
stack.append('b')
stack.append('c')

print('Initial stack:')
print(stack)

print('\nElements popped from stack:')

#基于pop函数实现出栈操作
print(stack.pop())
print(stack.pop())

print('\nStack after elements are popped:')
print(stack)

Demo.03:  基于LifoQueue实现

from queue import LifoQueue

stack = LifoQueue(maxsize=3)
print(stack.qsize())

#基于put函数实现入栈操作
stack.put('a')
stack.put('b')
stack.put('c')

print("Full: ", stack.full())
print("Size: ", stack.qsize())

#基于get函数实现出栈操作
print('\nElements popped from the stack')
print(stack.get())
print(stack.get())

print("\nEmpty: ", stack.empty())

Demo.04:  封装Stack类来实现

class Stack:
    #初始化栈
    def __init__(self, size):
        self.arr = [None] * size
        self.capacity = size
        self.top = -1

    #入栈操作
    def push(self, val):
        if self.isFull():
            print('Stack is full…')
            exit(-1)

        print(f'Inserting {val} into the stack…')
        self.top = self.top + 1
        self.arr[self.top] = val

    #出栈操作
    def pop(self):
        if self.isEmpty():
            print('Stack is empty..')
            exit(-1)
        print(f'Removing {self.peek()} from the stack')
        top = self.arr[self.top]
        self.top = self.top - 1
        return top

    #返回栈顶元素
    def peek(self):
        if self.isEmpty():
            exit(-1)
        return self.arr[self.top]

    def size(self):
        return self.top + 1

    def isEmpty(self):
        return self.size() == 0

    def isFull(self):
        return self.size() == self.capacity

if __name__ == '__main__':
    stack = Stack(3)

    stack.push(1)
    stack.push(2)
    stack.pop()
    stack.pop()

    stack.push(3)
    stack.push(4)
    print('Top element is', stack.peek())
    print('The stack size is', stack.size())

    stack.pop()
    if stack.isEmpty():
        print('The stack is empty')
    else:
        print('The stack is not empty')

运行结果:

Inserting 1 into the stack…
Inserting 2 into the stack…
Removing 2 from the stack
Removing 1 from the stack
Inserting 3 into the stack…
Inserting 4 into the stack…
Top element is 4
The stack size is 2
Removing 4 from the stack
The stack is not empty

2.C++语言实现

方式1.基于STL标准库自带的std::stack进行实现

方式2.封装一个Stack类来实现

Demo.01:  基于std::stack实现

#include <iostream>
#include <stack>
using namespace std;
void main()
{
       stack<int> mystack;
       mystack.push(0);
       mystack.push(1);
       mystack.push(2);
       //弹出并打印栈顶元素
       while (!mystack.empty()) {
              cout << ' ' << mystack.top();
              mystack.pop();
       }
}

Demo.02: 封装Stack类来实现

#include<iostream>
using namespace std;
#define MAX 1024
class Stack
{
    int top;
public:
    int myStack[MAX];
    Stack() { top = -1; }
    bool push(int x);
    int pop();
    bool isEmpty();
};
bool Stack::push(int item)
{
    if (top >= (MAX - 1)) {
        cout << "stack is full..";
        return false;
    }
    else {
        myStack[++top] = item;
        cout << item << endl;
        return true;
    }
}
int Stack::pop()
{
    if (top < 0) {
        cout << "stack is empty..";
        return 0;
    }
    else {
        int item = myStack[top--];
        return item;
    }
}
bool Stack::isEmpty()
{
    return (top < 0);
}
int main()
{
    class Stack stack;
    cout << "The Stack Push " << endl;
    stack.push(2);
    stack.push(4);
    stack.push(6);
    cout << "The Stack Pop : " << endl;
    while (!stack.isEmpty())
    {
        cout << stack.pop() << endl;
    }
    return 0;
}

运行结果:

The Stack Push
2
4
6
The Stack Pop :
6
4
2

五,栈的应用场景

栈在软件开发中的主要应用场景有:

1.表达式解析,对表达式的前缀/后缀进行出栈/入栈操作来解析表达式的内容。

2.程序运行记录跟踪,比如在Web浏览器中,每访问一个新页面时,URL被添加到栈中,当点击后退按钮时,栈中弹出以前的URL。

3.实现其他更复杂的数据结构,比如树和图。

简单应用案例

1.场景:编写一个算法,从左到右读取字符串中所有的括号字符,判断其中的括号是否都能互相匹配。

2.实现步骤: 

step.1:新建一个空的栈。

step.2:从左往右依次读取括号字符,如果遇到左括号,调用push将字符压入堆栈,如果遇到右括号,调用pop弹出栈顶的字符。

step.3:如果存在左括号与右括号不匹配,结束时,栈中数据不为空。如果所有的左括号与右括号匹配,结束时,栈中的数据是空的。

3.Python代码实现:

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

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

    def push(self, item):
        self.items.insert(0, item)

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

    def peek(self):
        return self.items[0]

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

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

if __name__ == '__main__':
    test_st1 = "((()))"
    print("The check result is :", parChecker(test_st1))
    test_st2 = "((())"
    print("The check result is :", parChecker(test_st2))

运行结果:

The check result is : True
The check result is : False

六,参考阅读

《Problem Solving with Algorithms and Data Structures Using Python, Second Edition》

https://www.geeksforgeeks.org/stack-in-python/

https://www.techiedelight.com/zh/stack-implementation-python/

  • 23
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
接入第三方登录是让用户方便快捷地使用已有账号登录你的网站或应用程序,提高用户体验的一种方式。本文将介绍如何使用 PHP 实现微信公众号第三方登录。 1. 获取微信授权 首先,需要获取微信用户的授权。具体步骤如下: 1)引导用户打开微信授权页面: ```php $appid = 'your_appid'; $redirect_uri = urlencode('http://yourdomain.com/callback.php'); $scope = 'snsapi_userinfo'; $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=$appid&redirect_uri=$redirect_uri&response_type=code&scope=$scope&state=STATE#wechat_redirect"; header("Location: $url"); ``` 其中,`$appid` 是你的微信公众号的 AppID,`$redirect_uri` 是授权后回调的 URL,`$scope` 是授权作用域,可以是 `snsapi_base` 或 `snsapi_userinfo`,`$state` 是自定义参数,用于防止 CSRF 攻击。 2)获取授权码: 用户同意授权后,会重定向到 `$redirect_uri` 指定的 URL,带上授权码 `code` 和 `state` 参数。 ```php $code = $_GET['code']; $state = $_GET['state']; ``` 3)获取 access_token 和 openid: 使用授权码 `code` 获取 `access_token` 和 `openid`。 ```php $access_token_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=$appid&secret=$secret&code=$code&grant_type=authorization_code"; $response = file_get_contents($access_token_url); $result = json_decode($response, true); $access_token = $result['access_token']; $openid = $result['openid']; ``` 其中,`$secret` 是你的微信公众号的 AppSecret。 2. 获取用户信息 获取到 `access_token` 和 `openid` 后,可以使用以下代码获取用户信息: ```php $userinfo_url = "https://api.weixin.qq.com/sns/userinfo?access_token=$access_token&openid=$openid&lang=zh_CN"; $response = file_get_contents($userinfo_url); $userinfo = json_decode($response, true); ``` 其中,`$userinfo` 包含用户的昵称、头像等信息。 3. 将用户信息保存到数据库 最后,将获取到的用户信息保存到数据库中,以便下次使用时快速登录。 ```php // 连接数据库 $con = mysqli_connect('localhost', 'username', 'password', 'database'); mysqli_set_charset($con, "utf8"); // 查询用户是否已存在 $sql = "SELECT * FROM users WHERE openid='$openid'"; $result = mysqli_query($con, $sql); if (mysqli_num_rows($result) == 0) { // 用户不存在,插入新用户信息 $nickname = mysqli_real_escape_string($con, $userinfo['nickname']); $headimgurl = mysqli_real_escape_string($con, $userinfo['headimgurl']); $sql = "INSERT INTO users (openid, nickname, headimgurl) VALUES ('$openid', '$nickname', '$headimgurl')"; mysqli_query($con, $sql); } // 保存用户登录状态 $_SESSION['openid'] = $openid; ``` 以上就是使用 PHP 实现微信公众号第三方登录的步骤。需要注意的是,为了确保安全性,应该对用户输入的数据进行过滤和验证,防止 SQL 注入和 XSS 攻击等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值