【基础数据结构】栈

这篇具有很好参考价值的文章主要介绍了【基础数据结构】栈。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

堆栈的定义、入栈、出栈、查询栈顶

#include <stdio.h>
#include <stdlib.h>

typedef int DataType;

// 定义栈节点结构体
struct StackNode;

struct StackNode {
    DataType data;              // 节点数据
    struct StackNode* next;     // 指向下一个节点的指针
};

// 定义栈结构体
struct Stack {
    struct StackNode* head;     // 栈顶节点指针
    int size;                   // 栈的大小(元素数量)
};

// 将元素压入栈中
void StackPushStack(struct Stack* stk, DataType dt) {
    struct StackNode* vtx = (struct StackNode*)malloc(sizeof(struct StackNode));  // 创建新节点
    vtx->next = stk->head;       // 新节点的下一个节点指针指向栈顶节点
    vtx->data = dt;              // 设置新节点的数据为传入的数据
    stk->head = vtx;             // 更新栈顶节点为新节点
    ++stk->size;                 // 增加栈的大小
}

// 将栈顶元素弹出栈
void StackPopStack(struct Stack* stk) {
    struct StackNode* temp = stk->head;   // 临时存储栈顶节点指针
    stk->head = temp->next;               // 更新栈顶节点为下一个节点
    free(temp);                           // 释放原栈顶节点的内存
    --stk->size;                          // 减少栈的大小
}

// 获取栈顶元素的值
DataType StackGetTop(struct Stack* stk) {
    return stk->head->data;     // 返回栈顶节点的数据
}

int main() {
    // 创建一个栈
    struct Stack myStack;
    myStack.head = NULL;    // 初始化栈顶节点指针为空
    myStack.size = 0;       // 初始化栈的大小为0

    // 将元素压入栈中
    StackPushStack(&myStack, 10);
    StackPushStack(&myStack, 20);
    StackPushStack(&myStack, 30);

    // 获取栈顶元素并打印
    DataType top = StackGetTop(&myStack);
    printf("Top element: %d\n", top);

    // 从栈中弹出一个元素
    StackPopStack(&myStack);

    // 获取新的栈顶元素并打印
    top = StackGetTop(&myStack);
    printf("Top element after popping: %d\n", top);

    return 0;
}

例题1

括号的最大嵌套深度

提示

如果字符串满足以下条件之一,则可以称之为 有效括号字符串valid parentheses string,可以简写为 VPS):

  • 字符串是一个空字符串 "",或者是一个不为 "(" 或 ")" 的单字符。
  • 字符串可以写为 ABA 与 B 字符串连接),其中 A 和 B 都是 有效括号字符串 。
  • 字符串可以写为 (A),其中 A 是一个 有效括号字符串 。

类似地,可以定义任何有效括号字符串 S 的 嵌套深度 depth(S)

  • depth("") = 0
  • depth(C) = 0,其中 C 是单个字符的字符串,且该字符不是 "(" 或者 ")"
  • depth(A + B) = max(depth(A), depth(B)),其中 A 和 B 都是 有效括号字符串
  • depth("(" + A + ")") = 1 + depth(A),其中 A 是一个 有效括号字符串

例如:"""()()""()(()())" 都是 有效括号字符串(嵌套深度分别为 0、1、2),而 ")(" 、"(()" 都不是 有效括号字符串 。

给你一个 有效括号字符串 s,返回该字符串的 s 嵌套深度 。

示例 1:

输入:s = "(1+(2*3)+((8)/4))+1"
输出:3
解释:数字 8 在嵌套的 3 层括号中。

示例 2:

输入:s = "(1)+((2))+(((3)))"
输出:3

提示:

  • 1 <= s.length <= 100
  • s 由数字 0-9 和字符 '+''-''*''/''('')' 组成
  • 题目数据保证括号表达式 s 是 有效的括号表达式
#include <stdio.h>
#include <stdlib.h>
typedef struct {
    char* stack;
    int top;
} Stack;

Stack* createStack(int capacity) {
    Stack* stack = (Stack*)malloc(sizeof(Stack));
    stack->stack = (char*)malloc(capacity * sizeof(char));
    stack->top = -1;
    return stack;
}

void push(Stack* stack, char element) {
    stack->stack[++stack->top] = element;
}

char pop(Stack* stack) {
    return stack->stack[stack->top--];
}

int isEmpty(Stack* stack) {
    return stack->top == -1;
}                                                                                                    
int maxDepth(char* s) {
    int maxDepth = 0;
    int currentDepth = 0;
    int i = 0;
    Stack* stack = createStack(100);
    while (s[i] != '\0') {
        if (s[i] == '(') {
            push(stack, s[i]);
            currentDepth++;
            if (currentDepth > maxDepth) {
                maxDepth = currentDepth;
            }
        } else if (s[i] == ')') {
            pop(stack);
            currentDepth--;
        }
        i++;
    }
    return maxDepth;
}
int main() {
    char s[] = "(1+(2*3)+((8)/4))+1";
    int depth = maxDepth(s);
    printf("The maximum nesting depth is: %d\n", depth);
    return 0;
}

例题2

回文链表

给定一个链表的 头节点 head ,请判断其是否为回文链表。

如果一个链表是回文,那么链表节点序列从前往后看和从后往前看是相同的。

示例 1:

【基础数据结构】栈,基础数据结构,数据结构

输入: head = [1,2,3,3,2,1]
输出: true

示例 2:

【基础数据结构】栈,基础数据结构,数据结构

输入: head = [1,2]
输出: false

提示:

  • 链表 L 的长度范围为 [1, 105]
  • 0 <= node.val <= 9
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

struct ListNode {
    int val;
    struct ListNode* next;
};

// 创建一个堆栈结构
struct Stack {
    int* array;
    int top;
    int capacity;
};

// 初始化堆栈
struct Stack* createStack(int capacity) {
    struct Stack* stack = (struct Stack*)malloc(sizeof(struct Stack));
    stack->array = (int*)malloc(capacity * sizeof(int));
    stack->top = -1;
    stack->capacity = capacity;
    return stack;
}

// 判断堆栈是否为空
bool isEmpty(struct Stack* stack) {
    return stack->top == -1;
}

// 判断堆栈是否已满
bool isFull(struct Stack* stack) {
    return stack->top == stack->capacity - 1;
}

// 将元素压入堆栈
void push(struct Stack* stack, int value) {
    if (isFull(stack)) {
        return;
    }
    stack->array[++stack->top] = value;
}

// 从堆栈中弹出元素
int pop(struct Stack* stack) {
    if (isEmpty(stack)) {
        return -1;
    }
    return stack->array[stack->top--];
}

// 判断链表是否为回文链表
bool isPalindrome(struct ListNode* head) {
    if (!head || !head->next) {
        return true;
    }
    
    // 统计链表的长度
    int length = 0;
    struct ListNode* curr = head;
    while (curr) {
        length++;
        curr = curr->next;
    }
    
    // 将链表前半部分的值压入堆栈
    struct Stack* stack = createStack(length / 2);
    curr = head;
    int i = 0; 
    for (i = 0; i < length / 2; i++) {
        push(stack, curr->val);
        curr = curr->next;
    }
    
    // 如果链表长度为奇数,跳过中间节点
    if (length % 2 == 1) {
        curr = curr->next;
    }
    
    // 比较链表后半部分的值与堆栈中弹出的值是否相等
    while (curr) {
        int value = pop(stack);
        if (value != curr->val) {
            return false;
        }
        curr = curr->next;
    }
    
    return true;
}

int main() {
    // 创建链表 [1, 2, 3, 2, 1]
    struct ListNode* head = (struct ListNode*)malloc(sizeof(struct ListNode));
    head->val = 1;
    head->next = (struct ListNode*)malloc(sizeof(struct ListNode));
    head->next->val = 2;
    head->next->next = (struct ListNode*)malloc(sizeof(struct ListNode));
    head->next->next->val = 3;
    head->next->next->next = (struct ListNode*)malloc(sizeof(struct ListNode));
    head->next->next->next->val = 2;
    head->next->next->next->next = (struct ListNode*)malloc(sizeof(struct ListNode));
    head->next->next->next->next->val = 1;
    head->next->next->next->next->next = NULL;
    
    bool isPalin = isPalindrome(head);
    if (isPalin) {
        printf("The linked list is a palindrome.\n");
    } else {
        printf("The linked list is not a palindrome.\n");
    }
    
    // 释放链表的内存
    struct ListNode* curr = head;
    while (curr) {
        struct ListNode* temp = curr;
        curr = curr->next;
        free(temp);
    }
    
    return 0;
}

例题3

反转链表

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

【基础数据结构】栈,基础数据结构,数据结构

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例 2:

【基础数据结构】栈,基础数据结构,数据结构

输入:head = [1,2]
输出:[2,1]

示例 3:

输入:head = []
输出:[]

提示:文章来源地址https://www.toymoban.com/news/detail-815233.html

  • 链表中节点的数目范围是 [0, 5000]
  • -5000 <= Node.val <= 5000
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

struct ListNode {
    int val;
    struct ListNode* next;
};

// 创建一个堆栈结构
struct Stack {
    int* array;
    int top;
    int capacity;
};

// 初始化堆栈
struct Stack* createStack(int capacity) {
    struct Stack* stack = (struct Stack*)malloc(sizeof(struct Stack));
    stack->array = (int*)malloc(capacity * sizeof(int));
    stack->top = -1;
    stack->capacity = capacity;
    return stack;
}
// 判断堆栈是否为空
bool isEmpty(struct Stack* stack) {
    return stack->top == -1;
}
// 判断堆栈是否已满
bool isFull(struct Stack* stack) {
    return stack->top == stack->capacity - 1;
}
// 将元素压入堆栈
void push(struct Stack* stack, int value) {
    if (isFull(stack)) {
        return;
    }
    stack->array[++stack->top] = value;
}
// 从堆栈中弹出元素
int pop(struct Stack* stack) {
    if (isEmpty(stack)) {
        return -1;
    }
    return stack->array[stack->top--];
}
// 反转链表
struct ListNode* reverseList(struct ListNode* head) {
	if (!head || !head->next) {
        return head;
    }
	 // 统计链表的长度
    int length = 0;
    struct ListNode* curr = head;
    while (curr) {
        length++;
        curr = curr->next;
    }
    // 将链表的值压入堆栈
    struct Stack* stack = createStack(length);
    curr = head;
    int i = 0; 
    for (i = 0; i < length; i++) {
        push(stack, curr->val);
        curr = curr->next;
    }
    // 将堆栈弹出的值给链表 
    curr = head;
    while (curr) {
        curr->val = pop(stack);
        curr = curr->next;
    }
	return head;
} 

int main() {
    // 创建链表 [1, 2, 3, 4, 5]
    struct ListNode* head = (struct ListNode*)malloc(sizeof(struct ListNode));
    head->val = 1;
    head->next = (struct ListNode*)malloc(sizeof(struct ListNode));
    head->next->val = 2;
    head->next->next = (struct ListNode*)malloc(sizeof(struct ListNode));
    head->next->next->val = 3;
    head->next->next->next = (struct ListNode*)malloc(sizeof(struct ListNode));
    head->next->next->next->val = 4;
    head->next->next->next->next = (struct ListNode*)malloc(sizeof(struct ListNode));
    head->next->next->next->next->val = 5;
    head->next->next->next->next->next = NULL;
    
    head=reverseList(head);
    int i=0;
    for(i=0;i<5;i++)
    {
    	printf("%d ",head->val);
    	head=head->next;
	}
    // 释放链表的内存
    struct ListNode* curr = head;
    while (curr) {
        struct ListNode* temp = curr;
        curr = curr->next;
        free(temp);
    }
    
    return 0;
}

到了这里,关于【基础数据结构】栈的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【算法基础】数据结构

    【算法基础】数据结构

    826. 单链表 - AcWing题库 827. 双链表 - AcWing题库 828. 模拟栈 - AcWing题库 3302. 表达式求值 - AcWing题库 遍历输入的操作 如果是数字就存入num的堆栈 (同时注意123,2123这种长数字要一次性存入) 如果是(  直接存入op的堆栈 如果是  )就一直运算,直到遇到( 如果是操作符(如

    2024年02月12日
    浏览(15)
  • 数据结构基础

    数据结构基础

    数据的结构存在逻辑结构和储存结构两个方面;逻辑结构有集合、线性结构、树形结构、图状结构;存储结构有顺序、链式和索引。 集合 线性结构 树形结构 节点接口 构建树的工具类 测试类 图状结构 撤销: Ctrl/Command + Z 重做: Ctrl/Command + Y 加粗: Ctrl/Command + B 斜体: Ctr

    2024年02月12日
    浏览(10)
  • 数据结构基础--散列表

    数据结构基础--散列表

    散列表,又叫 哈希表 (Hash Table),是能够通过给定的的值直接访问到具体对应的值的一个数据结构。也就是说,把映射到一个表中的位置来直接访问记录,以加快访问速度。 通常,把这个称为 Key,把对应的记录称为 Value,所以也可以说是通过 Key 访问

    2024年02月04日
    浏览(9)
  • c++基础数据结构

    基础数据结构 目录 • 线性结构 • 二叉堆 • 并查集 • 哈希表 • 应用举例 一、线性结构 基础知识 • 数组 • 带头结点的双链表 – He a d 结点 : 虚拟头结点 – Fir s t 结点 : 第一个有实际内容的结点 • 队列 : 循环队列与 Open-Close 表 例 1. 最小值 • 实现一个 n 个元素的线性

    2024年02月10日
    浏览(6)
  • 基础数据结构:数组介绍

    基础数据结构:数组介绍

    程序设计 = 数据结构+算法 说到数据结构是什么,我们得先来谈谈什么叫数据。 正所谓\\\"巧妇难为无米之炊’,再强大的计算机,也是要有\\\"米’下锅才可以的,否则就是一堆破铜烂铁 这个\\\"米\\\"就是数据。 数据: 是描述客观事物的符号,是计算机中可以操作的对象,是能被计算

    2024年02月11日
    浏览(10)
  • 数据结构基础-数组

    数据结构基础-数组

    概述 定义 在计算机科学中,数组是由一组元素(值或变量)组成的数据结构,每个元素有至少一个索引或键来标识 In computer science, an array is a data structure consisting of a collection of elements (values or variables), each identified by at least one array index or key 因为数组内的元素是 连续存储 的,

    2024年02月07日
    浏览(9)
  • 【数据结构-栈】栈基础

    【数据结构-栈】栈基础

    💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学习,不断总结,共同进步,活到老学到老 导航 檀越剑指大厂系列:全面总

    2024年02月09日
    浏览(7)
  • Java基础--数据结构

    Java基础--数据结构

    Java工具包提供了强大的数据结构。在Java中的数据结构主要包括以下几种接口和类: 枚举(Enumeration)、位集合(BitSet)、向量(Vector)、栈(Stack)、字典(Dictionary)、哈希表(Hashtable)、属性(Properties) 以上这些类是传统遗留的,在Java2中引入了一种新的框架-集合框架

    2023年04月14日
    浏览(11)
  • 数据结构与算法基础

    数据结构与算法基础

    1.1、数组 已知5行5列的二维数组a中的各元素占两个字节,求元素a[2][3]按行优先存储的存储地址? 按行存:a+(5*2+3) 2=a+26 按列存:a+(5 3+2)*2=a+34 1.2、稀疏矩阵 在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为 稀疏矩阵 ;与之

    2024年02月04日
    浏览(14)
  • 基础+常用的数据结构

    基础+常用的数据结构

    JDK,它是功能齐全的 Java SDK,是提供给开发者使用,能够创建和编译 Java 程序的开发套件。它包含了 JRE,同时还包含了编译 java 源码的编译器 javac 以及一些其他工具比如 javadoc(文档注释工具)、jdb(调试器)、jconsole(基于 JMX 的可视化监控⼯具)、javap(反编译工具)等等

    2024年01月22日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包