栈是一种线性数据结构,顺序可能是 LIFO(后进先出)或 FILO(先进先出)。

堆栈主要有三个基本操作:

1、push,把元素压入栈

2、pop,从栈中弹出元素(同时从栈中移除),最后加入的第一个被弹出

3、peek 或 top,返回堆栈顶部的元素

4、isEmpty,如果 stack 为空则返回 true,否则返回 false

如何理解堆栈?

堆栈有许多现实生活中的例子。考虑在食堂中堆叠在一起的碟子,位于顶部的碟子是第一个被移除的,放置在最底部的碟子在堆中保持最长时间。

堆栈操作的时间复杂度:

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

实现:

有两种方法来实现堆栈:

1、使用数组

2、使用链表

使用数组实现堆栈

优点:易于实施。存取操作不涉及指针

缺点:不是动态的。不会在运行时根据需要增长和缩小。

//
// 栈的数组实现
// Created by ruby on 2019/1/17.
// #include <limits.h>
#include <stdio.h>
#include <stdlib.h> // 保存栈的数据结构
struct Stack {
int top;
int capacity;
int* array;
}; // 根据指定大小创建栈, 初始化大小为 0, 容量为 capacity
struct Stack* createStack(unsigned capacity) {
struct Stack* stack = (struct Stack*)malloc(sizeof(struct Stack));
stack->top = -1;
stack->capacity = capacity;
stack->array = (int*)malloc(capacity * sizeof(int));
return stack;
} // 栈是否已满
int isFull(struct Stack* stack) {
return stack->top == stack->capacity - 1;
} // 栈是否为空
int isEmpty(struct Stack* stack) {
return stack->top == -1;
} // 添加 item 到栈中
void push(struct Stack* stack, int item) {
if (isFull(stack)) {
printf("stack is full\n");
return;
} stack->array[++stack->top] = item;
} // 从栈中弹出一个元素
int pop(struct Stack* stack) {
if (isEmpty(stack)) {
printf("stack is empty\n");
return -1;
} return stack->array[stack->top--];
} 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;
}

  

使用链表实现堆栈

优点:堆栈的链表实现可以根据运行时的需求增长和缩小。

缺点:由于需要指针记录元素地址,需要额外的内存。

#include <limits.h>
#include <stdlib.h>
#include <stdio.h> 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;
}

  

栈(C语言实现)的更多相关文章

  1. 数据结构与算法之顺序栈C语言实现

    顺序栈是一种特殊的顺序表,主要操作是入栈和出栈.将顺序表加一些特定限制,就成了顺序栈. 注: 1.顺序栈C语言实现: 2.按较简单的方式实现,主要帮助理解,可在此基础上修改,更加完善: 3.提供几个简 ...

  2. 【小白成长撸】--链栈(C语言版)

    // 链栈.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <stdio.h> #include <st ...

  3. 【小白成长撸】--顺序栈(C语言版)

    // 顺序栈.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h"//test1.0--栈表仅限Int类型 #include <stdio. ...

  4. 数据结构---栈C语言实现

    #include <stdio.h> #include <stdlib.h> #define uchar unsigned char #define uint unsigned ...

  5. 逆波兰表达式[栈 C 语言 实现]

    逆波兰表达式 逆波兰表达式又叫做后缀表达式.在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表示.波兰逻辑学家J.Lukasiewicz于1929年提出了另一种表示 ...

  6. 链表栈C语言实现

    #ifndef LINKSTACK_H_INCLUDED #define LINKSTACK_H_INCLUDED #include <stdlib.h> #include <std ...

  7. 顺序表栈C语言实现

    /* * SeqStack.h * * Created on: 2019年8月1日 * Author: Administrator */ #ifndef SEQSTACK_H_ #define SEQ ...

  8. 动态栈-------C语言

    使用带头结点的单链表实现 主要使用链表中的头插来实现栈的先进后出的特点 /***************************************************** Author:Si ...

  9. 静态栈-------C语言

    /***************************************************** Author:Simon_Kly Version:0.1 Date: 20170520 D ...

  10. 顺序栈C语言实现

    "` #include <stdio.h> #define MAXSIZE 10001 #define ELEMTYPE int #define STACK_EMPTY -999 ...

随机推荐

  1. nmap命令详解

    基础命令学习目录 原文链接:http://www.cnblogs.com/hongfei/p/3801357.html Nmap即网络映射器对Linux系统/网络管理员来说是一个开源且非常通用的工具. ...

  2. Centos7.2构建Python3.6开发环境

    1.安装python3.6 1.这里使用一台全新的腾讯云主机,首先获取linux系统版本信息. [root@VM_46_121_centos ~]# cat /etc/redhat-release C ...

  3. teamwork 2

    1.访问上学期项目团队,学习他们的得失. 上学期学长们有一个项目是学霸系统,在看过了学长们的相关博客后,我们可以感受到学长们确实花费了不少心思,也看到了许多值得我们学习的地方. 首先,学长们在项目开始 ...

  4. OO第三次阶段总结

    (1)调研,规格化设计的大致发展和为什么得到人类重视 结构化程序设计(英语:Structured programming),一种编程范型.它采用子程序(函数就是一种子程序).代码区块.for循环以及w ...

  5. 关于react虚拟DOM的研究

    1.传统的前端是这样的,我在学校也都是这样做的,html(jsp)主要负责提供所有的DOM节点,而javascript负责动态效果,比如按钮点击,图片轮播等,这样的话javascript如何组织结构是 ...

  6. python实现树莓派开机自动发送IP到指定邮箱

    #!/usr/bin/python # -*- coding:UTF-8 -*- #测试发送邮件163邮箱发送到qq邮箱 import smtplib from email.mime.text imp ...

  7. HDU 4405 Aeroplane chess 期望dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4405 Aeroplane chess Time Limit: 2000/1000 MS (Java/ ...

  8. 结对随即四则运算(带界面Java版)

    //随机四则运算类 public class 随机四则运算 { public static void main(String[] args) { new 界面();//进入随机四则运算的首界面 } } ...

  9. ASP.NET Forms身份验证概述

    表单身份验证允许您使用自己的代码对用户进行身份验证,然后在cookie或页面URL中维护身份验证令牌.表单身份验证通过FormsAuthenticationModule类参与ASP.NET页面生命周期 ...

  10. Python入门:类与类的继承

    类,是一些有共同特征和行为事物的抽象概念的总和. 1. 定义一个类: 我们使用class来定义一个类,和之前说过的定义函数用def类似.在类里面给变量赋值时,专业术语称之为类的属性. 比如拿可口可乐来 ...