📜  栈数据结构(介绍及程序)

📅  最后修改于: 2022-05-13 01:57:09.167000             🧑  作者: Mango

栈数据结构(介绍及程序)

堆栈是一种线性数据结构,遵循特定的操作执行顺序。顺序可以是 LIFO(后进先出)或 FILO(先进后出)。

堆栈中主要执行以下三个基本操作:

  • Push:在堆栈中添加一个项目。如果堆栈已满,则称其为溢出条件。
  • 弹出:从堆栈中删除一个项目。这些项目以它们被推送的相反顺序弹出。如果堆栈为空,则称其为下溢条件。
  • Peek 或 Top:返回堆栈的顶部元素。
  • isEmpty:如果堆栈为空,则返回 true,否则返回 false。

如何实际理解堆栈?
堆栈有许多现实生活中的例子。考虑一个简单的例子,在食堂里,盘子相互叠放。位于顶部的板是第一个被移除的板,即已放置在最底部位置的板在堆叠中保留的时间最长。因此,可以简单地看出遵循 LIFO/FILO 的顺序。

堆栈操作的时间复杂度:

push()、pop()、isEmpty() 和 peek() 都需要 O(1) 时间。我们不会在任何这些操作中运行任何循环。

堆栈的应用:

  • 符号的平衡
  • 中缀到后缀/前缀转换
  • 许多地方的重做撤消功能,如编辑器、Photoshop。
  • Web 浏览器中的前进和后退功能
  • 用于许多算法,如河内塔、树遍历、股票跨度问题、直方图问题。
  • 回溯是算法设计技术之一。回溯的一些例子是 Knight-Tour 问题、N-Queen 问题、通过迷宫找到自己的路,以及在所有这些问题中类似游戏的国际象棋或跳棋,如果这种方法效率不高,我们会回到前面状态并进入另一条路径。为了从当前状态返回,我们需要存储之前的状态,为此我们需要一个堆栈。
  • 在拓扑排序和强连通分量等图算法中
  • 在内存管理中,任何现代计算机都使用堆栈作为运行目的的主要管理。在计算机系统中运行的每个程序都有自己的内存分配
  • 字符串反转也是栈的另一个应用。在这里,每个字符被一个一个地插入到堆栈中。所以字符串的第一个字符在栈底,而字符串的最后一个元素在栈顶。在堆栈上执行弹出操作后,我们以相反的顺序得到一个字符串。

执行:
栈的实现有两种方式:

  • 使用数组
  • 使用链表

使用数组实现堆栈

C++
/* C++ program to implement basic stack
   operations */
#include 
 
using namespace std;
 
#define MAX 1000
 
class Stack {
    int top;
 
public:
    int a[MAX]; // Maximum size of Stack
 
    Stack() { top = -1; }
    bool push(int x);
    int pop();
    int peek();
    bool isEmpty();
};
 
bool Stack::push(int x)
{
    if (top >= (MAX - 1)) {
        cout << "Stack Overflow";
        return false;
    }
    else {
        a[++top] = x;
        cout << x << " pushed into stack\n";
        return true;
    }
}
 
int Stack::pop()
{
    if (top < 0) {
        cout << "Stack Underflow";
        return 0;
    }
    else {
        int x = a[top--];
        return x;
    }
}
int Stack::peek()
{
    if (top < 0) {
        cout << "Stack is Empty";
        return 0;
    }
    else {
        int x = a[top];
        return x;
    }
}
 
bool Stack::isEmpty()
{
    return (top < 0);
}
 
// Driver program to test above functions
int main()
{
    class Stack s;
    s.push(10);
    s.push(20);
    s.push(30);
    cout << s.pop() << " Popped from stack\n";
    //print all elements in stack :
    cout<<"Elements present in stack : ";
    while(!s.isEmpty())
    {
        // print top element in stack
        cout<


C
// C program for array implementation of stack
#include 
#include 
#include 
 
// A structure to represent a stack
struct Stack {
    int top;
    unsigned capacity;
    int* array;
};
 
// function to create a stack of given capacity. It initializes size of
// stack as 0
struct Stack* createStack(unsigned capacity)
{
    struct Stack* stack = (struct Stack*)malloc(sizeof(struct Stack));
    stack->capacity = capacity;
    stack->top = -1;
    stack->array = (int*)malloc(stack->capacity * sizeof(int));
    return stack;
}
 
// Stack is full when top is equal to the last index
int isFull(struct Stack* stack)
{
    return stack->top == stack->capacity - 1;
}
 
// Stack is empty when top is equal to -1
int isEmpty(struct Stack* stack)
{
    return stack->top == -1;
}
 
// Function to add an item to stack.  It increases top by 1
void push(struct Stack* stack, int item)
{
    if (isFull(stack))
        return;
    stack->array[++stack->top] = item;
    printf("%d pushed to stack\n", item);
}
 
// Function to remove an item from stack.  It decreases top by 1
int pop(struct Stack* stack)
{
    if (isEmpty(stack))
        return INT_MIN;
    return stack->array[stack->top--];
}
 
// Function to return the top from stack without removing it
int peek(struct Stack* stack)
{
    if (isEmpty(stack))
        return INT_MIN;
    return stack->array[stack->top];
}
 
// Driver program to test above functions
int main()
{
    struct Stack* stack = createStack(100);
 
    push(stack, 10);
    push(stack, 20);
    push(stack, 30);
 
    printf("%d popped from stack\n", pop(stack));
 
    return 0;
}


Java
/* Java program to implement basic stack
operations */
class Stack {
    static final int MAX = 1000;
    int top;
    int a[] = new int[MAX]; // Maximum size of Stack
 
    boolean isEmpty()
    {
        return (top < 0);
    }
    Stack()
    {
        top = -1;
    }
 
    boolean push(int x)
    {
        if (top >= (MAX - 1)) {
            System.out.println("Stack Overflow");
            return false;
        }
        else {
            a[++top] = x;
            System.out.println(x + " pushed into stack");
            return true;
        }
    }
 
    int pop()
    {
        if (top < 0) {
            System.out.println("Stack Underflow");
            return 0;
        }
        else {
            int x = a[top--];
            return x;
        }
    }
 
    int peek()
    {
        if (top < 0) {
            System.out.println("Stack Underflow");
            return 0;
        }
        else {
            int x = a[top];
            return x;
        }
    }
    
    void print(){
    for(int i = top;i>-1;i--){
      System.out.print(" "+ a[i]);
    }
  }
}
 
// Driver code
class Main {
    public static void main(String args[])
    {
        Stack s = new Stack();
        s.push(10);
        s.push(20);
        s.push(30);
        System.out.println(s.pop() + " Popped from stack");
        System.out.println("Top element is :" + s.peek());
        System.out.print("Elements present in stack :");
        s.print();
    }
}


Python3
# Python program for implementation of stack
 
# import maxsize from sys module
# Used to return -infinite when stack is empty
from sys import maxsize
 
# Function to create a stack. It initializes size of stack as 0
def createStack():
    stack = []
    return stack
 
# Stack is empty when stack size is 0
def isEmpty(stack):
    return len(stack) == 0
 
# Function to add an item to stack. It increases size by 1
def push(stack, item):
    stack.append(item)
    print(item + " pushed to stack ")
     
# Function to remove an item from stack. It decreases size by 1
def pop(stack):
    if (isEmpty(stack)):
        return str(-maxsize -1) # return minus infinite
     
    return stack.pop()
 
# Function to return the top from stack without removing it
def peek(stack):
    if (isEmpty(stack)):
        return str(-maxsize -1) # return minus infinite
    return stack[len(stack) - 1]
 
# Driver program to test above functions   
stack = createStack()
push(stack, str(10))
push(stack, str(20))
push(stack, str(30))
print(pop(stack) + " popped from stack")


C#
// C# program to implement basic stack
// operations
using System;
 
namespace ImplementStack {
class Stack {
    private int[] ele;
    private int top;
    private int max;
    public Stack(int size)
    {
        ele = new int[size]; // Maximum size of Stack
        top = -1;
        max = size;
    }
 
    public void push(int item)
    {
        if (top == max - 1) {
            Console.WriteLine("Stack Overflow");
            return;
        }
        else {
            ele[++top] = item;
        }
    }
 
    public int pop()
    {
        if (top == -1) {
            Console.WriteLine("Stack is Empty");
            return -1;
        }
        else {
            Console.WriteLine("{0} popped from stack ", ele[top]);
            return ele[top--];
        }
    }
 
    public int peek()
    {
        if (top == -1) {
            Console.WriteLine("Stack is Empty");
            return -1;
        }
        else {
            Console.WriteLine("{0} popped from stack ", ele[top]);
            return ele[top];
        }
    }
 
    public void printStack()
    {
        if (top == -1) {
            Console.WriteLine("Stack is Empty");
            return;
        }
        else {
            for (int i = 0; i <= top; i++) {
                Console.WriteLine("{0} pushed into stack", ele[i]);
            }
        }
    }
}
 
// Driver program to test above functions
class Program {
    static void Main()
    {
        Stack p = new Stack(5);
 
        p.push(10);
        p.push(20);
        p.push(30);
        p.printStack();
        p.pop();
    }
}
}


Javascript


C++
// C++ program for linked list implementation of stack
#include 
using namespace std;
 
// A structure to represent a stack
class StackNode {
public:
    int data;
    StackNode* next;
};
 
StackNode* newNode(int data)
{
    StackNode* stackNode = new StackNode();
    stackNode->data = data;
    stackNode->next = NULL;
    return stackNode;
}
 
int isEmpty(StackNode* root)
{
    return !root;
}
 
void push(StackNode** root, int data)
{
    StackNode* stackNode = newNode(data);
    stackNode->next = *root;
    *root = stackNode;
    cout << data << " pushed to stack\n";
}
 
int pop(StackNode** root)
{
    if (isEmpty(*root))
        return INT_MIN;
    StackNode* temp = *root;
    *root = (*root)->next;
    int popped = temp->data;
    free(temp);
 
    return popped;
}
 
int peek(StackNode* root)
{
    if (isEmpty(root))
        return INT_MIN;
    return root->data;
}
 
// Driver code
int main()
{
    StackNode* root = NULL;
 
    push(&root, 10);
    push(&root, 20);
    push(&root, 30);
 
    cout << pop(&root) << " popped from stack\n";
 
    cout << "Top element is " << peek(root) << endl;
     
    cout<<"Elements present in stack : ";
     //print all elements in stack :
    while(!isEmpty(root))
    {
        // print top element in stack
        cout<


C
// C program for linked list implementation of stack
#include 
#include 
#include 
 
// A structure to represent a stack
struct StackNode {
    int data;
    struct StackNode* next;
};
 
struct StackNode* newNode(int data)
{
    struct StackNode* stackNode =
      (struct StackNode*)
      malloc(sizeof(struct StackNode));
    stackNode->data = data;
    stackNode->next = NULL;
    return stackNode;
}
 
int isEmpty(struct StackNode* root)
{
    return !root;
}
 
void push(struct StackNode** root, int data)
{
    struct StackNode* stackNode = newNode(data);
    stackNode->next = *root;
    *root = stackNode;
    printf("%d pushed to stack\n", data);
}
 
int pop(struct StackNode** root)
{
    if (isEmpty(*root))
        return INT_MIN;
    struct StackNode* temp = *root;
    *root = (*root)->next;
    int popped = temp->data;
    free(temp);
 
    return popped;
}
 
int peek(struct StackNode* root)
{
    if (isEmpty(root))
        return INT_MIN;
    return root->data;
}
 
int main()
{
    struct StackNode* root = NULL;
 
    push(&root, 10);
    push(&root, 20);
    push(&root, 30);
 
    printf("%d popped from stack\n", pop(&root));
 
    printf("Top element is %d\n", peek(root));
 
    return 0;
}


Java
// Java Code for Linked List Implementation
 
public class StackAsLinkedList {
 
    StackNode root;
 
    static class StackNode {
        int data;
        StackNode next;
 
        StackNode(int data) { this.data = data; }
    }
 
    public boolean isEmpty()
    {
        if (root == null) {
            return true;
        }
        else
            return false;
    }
 
    public void push(int data)
    {
        StackNode newNode = new StackNode(data);
 
        if (root == null) {
            root = newNode;
        }
        else {
            StackNode temp = root;
            root = newNode;
            newNode.next = temp;
        }
        System.out.println(data + " pushed to stack");
    }
 
    public int pop()
    {
        int popped = Integer.MIN_VALUE;
        if (root == null) {
            System.out.println("Stack is Empty");
        }
        else {
            popped = root.data;
            root = root.next;
        }
        return popped;
    }
 
    public int peek()
    {
        if (root == null) {
            System.out.println("Stack is empty");
            return Integer.MIN_VALUE;
        }
        else {
            return root.data;
        }
    }
 
    // Driver code
    public static void main(String[] args)
    {
 
        StackAsLinkedList sll = new StackAsLinkedList();
 
        sll.push(10);
        sll.push(20);
        sll.push(30);
 
        System.out.println(sll.pop()
                           + " popped from stack");
 
        System.out.println("Top element is " + sll.peek());
    }
}


Python3
# Python program for linked list implementation of stack
 
# Class to represent a node
 
 
class StackNode:
 
    # Constructor to initialize a node
    def __init__(self, data):
        self.data = data
        self.next = None
 
 
class Stack:
 
    # Constructor to initialize the root of linked list
    def __init__(self):
        self.root = None
 
    def isEmpty(self):
        return True if self.root is None else False
 
    def push(self, data):
        newNode = StackNode(data)
        newNode.next = self.root
        self.root = newNode
        print ("% d pushed to stack" % (data))
 
    def pop(self):
        if (self.isEmpty()):
            return float("-inf")
        temp = self.root
        self.root = self.root.next
        popped = temp.data
        return popped
 
    def peek(self):
        if self.isEmpty():
            return float("-inf")
        return self.root.data
 
 
# Driver code
stack = Stack()
stack.push(10)
stack.push(20)
stack.push(30)
 
print ("% d popped from stack" % (stack.pop()))
print ("Top element is % d " % (stack.peek()))
 
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)


C#
// C# Code for Linked List Implementation
using System;
 
public class StackAsLinkedList {
 
    StackNode root;
 
    public class StackNode {
        public int data;
        public StackNode next;
 
        public StackNode(int data) { this.data = data; }
    }
 
    public bool isEmpty()
    {
        if (root == null) {
            return true;
        }
        else
            return false;
    }
 
    public void push(int data)
    {
        StackNode newNode = new StackNode(data);
 
        if (root == null) {
            root = newNode;
        }
        else {
            StackNode temp = root;
            root = newNode;
            newNode.next = temp;
        }
        Console.WriteLine(data + " pushed to stack");
    }
 
    public int pop()
    {
        int popped = int.MinValue;
        if (root == null) {
            Console.WriteLine("Stack is Empty");
        }
        else {
            popped = root.data;
            root = root.next;
        }
        return popped;
    }
 
    public int peek()
    {
        if (root == null) {
            Console.WriteLine("Stack is empty");
            return int.MinValue;
        }
        else {
            return root.data;
        }
    }
 
    // Driver code
    public static void Main(String[] args)
    {
 
        StackAsLinkedList sll = new StackAsLinkedList();
 
        sll.push(10);
        sll.push(20);
        sll.push(30);
 
        Console.WriteLine(sll.pop() + " popped from stack");
 
        Console.WriteLine("Top element is " + sll.peek());
    }
}
 
/* This code contributed by PrinciRaj1992 */


Javascript


输出 :

10 pushed into stack
20 pushed into stack
30 pushed into stack
30 Popped from stack
Top element is : 20
Elements present in stack : 20 10  

优点:易于实施。由于不涉及指针,因此节省了内存。
缺点:它不是动态的。它不会根据运行时的需要而增长和缩小。
使用链表实现堆栈:

C++

// C++ program for linked list implementation of stack
#include 
using namespace std;
 
// A structure to represent a stack
class StackNode {
public:
    int data;
    StackNode* next;
};
 
StackNode* newNode(int data)
{
    StackNode* stackNode = new StackNode();
    stackNode->data = data;
    stackNode->next = NULL;
    return stackNode;
}
 
int isEmpty(StackNode* root)
{
    return !root;
}
 
void push(StackNode** root, int data)
{
    StackNode* stackNode = newNode(data);
    stackNode->next = *root;
    *root = stackNode;
    cout << data << " pushed to stack\n";
}
 
int pop(StackNode** root)
{
    if (isEmpty(*root))
        return INT_MIN;
    StackNode* temp = *root;
    *root = (*root)->next;
    int popped = temp->data;
    free(temp);
 
    return popped;
}
 
int peek(StackNode* root)
{
    if (isEmpty(root))
        return INT_MIN;
    return root->data;
}
 
// Driver code
int main()
{
    StackNode* root = NULL;
 
    push(&root, 10);
    push(&root, 20);
    push(&root, 30);
 
    cout << pop(&root) << " popped from stack\n";
 
    cout << "Top element is " << peek(root) << endl;
     
    cout<<"Elements present in stack : ";
     //print all elements in stack :
    while(!isEmpty(root))
    {
        // print top element in stack
        cout<

C

// C program for linked list implementation of stack
#include 
#include 
#include 
 
// A structure to represent a stack
struct StackNode {
    int data;
    struct StackNode* next;
};
 
struct StackNode* newNode(int data)
{
    struct StackNode* stackNode =
      (struct StackNode*)
      malloc(sizeof(struct StackNode));
    stackNode->data = data;
    stackNode->next = NULL;
    return stackNode;
}
 
int isEmpty(struct StackNode* root)
{
    return !root;
}
 
void push(struct StackNode** root, int data)
{
    struct StackNode* stackNode = newNode(data);
    stackNode->next = *root;
    *root = stackNode;
    printf("%d pushed to stack\n", data);
}
 
int pop(struct StackNode** root)
{
    if (isEmpty(*root))
        return INT_MIN;
    struct StackNode* temp = *root;
    *root = (*root)->next;
    int popped = temp->data;
    free(temp);
 
    return popped;
}
 
int peek(struct StackNode* root)
{
    if (isEmpty(root))
        return INT_MIN;
    return root->data;
}
 
int main()
{
    struct StackNode* root = NULL;
 
    push(&root, 10);
    push(&root, 20);
    push(&root, 30);
 
    printf("%d popped from stack\n", pop(&root));
 
    printf("Top element is %d\n", peek(root));
 
    return 0;
}

Java

// Java Code for Linked List Implementation
 
public class StackAsLinkedList {
 
    StackNode root;
 
    static class StackNode {
        int data;
        StackNode next;
 
        StackNode(int data) { this.data = data; }
    }
 
    public boolean isEmpty()
    {
        if (root == null) {
            return true;
        }
        else
            return false;
    }
 
    public void push(int data)
    {
        StackNode newNode = new StackNode(data);
 
        if (root == null) {
            root = newNode;
        }
        else {
            StackNode temp = root;
            root = newNode;
            newNode.next = temp;
        }
        System.out.println(data + " pushed to stack");
    }
 
    public int pop()
    {
        int popped = Integer.MIN_VALUE;
        if (root == null) {
            System.out.println("Stack is Empty");
        }
        else {
            popped = root.data;
            root = root.next;
        }
        return popped;
    }
 
    public int peek()
    {
        if (root == null) {
            System.out.println("Stack is empty");
            return Integer.MIN_VALUE;
        }
        else {
            return root.data;
        }
    }
 
    // Driver code
    public static void main(String[] args)
    {
 
        StackAsLinkedList sll = new StackAsLinkedList();
 
        sll.push(10);
        sll.push(20);
        sll.push(30);
 
        System.out.println(sll.pop()
                           + " popped from stack");
 
        System.out.println("Top element is " + sll.peek());
    }
}

Python3

# Python program for linked list implementation of stack
 
# Class to represent a node
 
 
class StackNode:
 
    # Constructor to initialize a node
    def __init__(self, data):
        self.data = data
        self.next = None
 
 
class Stack:
 
    # Constructor to initialize the root of linked list
    def __init__(self):
        self.root = None
 
    def isEmpty(self):
        return True if self.root is None else False
 
    def push(self, data):
        newNode = StackNode(data)
        newNode.next = self.root
        self.root = newNode
        print ("% d pushed to stack" % (data))
 
    def pop(self):
        if (self.isEmpty()):
            return float("-inf")
        temp = self.root
        self.root = self.root.next
        popped = temp.data
        return popped
 
    def peek(self):
        if self.isEmpty():
            return float("-inf")
        return self.root.data
 
 
# Driver code
stack = Stack()
stack.push(10)
stack.push(20)
stack.push(30)
 
print ("% d popped from stack" % (stack.pop()))
print ("Top element is % d " % (stack.peek()))
 
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)

C#

// C# Code for Linked List Implementation
using System;
 
public class StackAsLinkedList {
 
    StackNode root;
 
    public class StackNode {
        public int data;
        public StackNode next;
 
        public StackNode(int data) { this.data = data; }
    }
 
    public bool isEmpty()
    {
        if (root == null) {
            return true;
        }
        else
            return false;
    }
 
    public void push(int data)
    {
        StackNode newNode = new StackNode(data);
 
        if (root == null) {
            root = newNode;
        }
        else {
            StackNode temp = root;
            root = newNode;
            newNode.next = temp;
        }
        Console.WriteLine(data + " pushed to stack");
    }
 
    public int pop()
    {
        int popped = int.MinValue;
        if (root == null) {
            Console.WriteLine("Stack is Empty");
        }
        else {
            popped = root.data;
            root = root.next;
        }
        return popped;
    }
 
    public int peek()
    {
        if (root == null) {
            Console.WriteLine("Stack is empty");
            return int.MinValue;
        }
        else {
            return root.data;
        }
    }
 
    // Driver code
    public static void Main(String[] args)
    {
 
        StackAsLinkedList sll = new StackAsLinkedList();
 
        sll.push(10);
        sll.push(20);
        sll.push(30);
 
        Console.WriteLine(sll.pop() + " popped from stack");
 
        Console.WriteLine("Top element is " + sll.peek());
    }
}
 
/* This code contributed by PrinciRaj1992 */

Javascript


输出:

10 pushed to stack
20 pushed to stack
30 pushed to stack
30 popped from stack
Top element is 20
Elements present in stack : 20 10 

优点:堆栈的链表实现可以根据运行时的需要进行扩展和收缩。
缺点:由于涉及指针,需要额外的内存。

https://youtu.be/vZEuSFXSMDI我们将在单独的文章中介绍堆栈应用程序的实现。

堆栈集 -2(中缀到后缀)

测验:堆栈问题

参考:
http://en.wikipedia.org/wiki/Stack_%28abstract_data_type%29#Problem_Description