C语言用指针支持栈是一种利用指针实现栈数据结构的方法,实现简单、易于理解,在C语言中广泛应用。本攻略将详细介绍如何使用指针实现栈数据结构,并提供两个示例说明。
什么是栈
栈(Stack)是一种先进后出(LIFO)的数据结构,常用于函数调用、表达式求值等场景。栈包含两个基本操作:压栈(push)和弹栈(pop),以及获取栈顶元素(top)等操作。
用指针实现栈
用指针实现栈,可以采用链表数据结构来表示栈。链表中每个节点包含两个元素:一个是数据元素,一个是指向下一个节点的指针。
定义一个Node节点结构体,用于存储节点数据和指针:
struct Node {
int data;
struct Node* next;
};
定义一个栈数据结构,包含指向栈顶节点的指针:
struct Stack {
struct Node* top;
};
初始化栈:
void initStack(Stack* stack) {
stack->top = NULL;
}
判断栈是否为空:
bool isEmpty(const Stack* stack) {
return stack->top == NULL;
}
压栈操作:
void push(Stack* stack, int value) {
Node* node = (Node*)malloc(sizeof(Node));
node->data = value;
node->next = stack->top;
stack->top = node;
}
弹栈操作:
int pop(Stack* stack) {
if (isEmpty(stack)) {
printf("cannot pop an empty stack");
return -1;
}
Node* node = stack->top;
int data = node->data;
stack->top = node->next;
free(node);
return data;
}
获取栈顶元素:
int top(const Stack* stack) {
if (isEmpty(stack)) {
printf("the stack is empty");
return -1;
}
return stack->top->data;
}
示例说明
示例一:括号匹配问题
给定一个只包含{、[、(、)、]、}六个字符的字符串,判断其中的括号是否匹配。
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
struct Node {
char data;
struct Node* next;
};
struct Stack {
struct Node* top;
};
void initStack(Stack* stack) {
stack->top = NULL;
}
bool isEmpty(const Stack* stack) {
return stack->top == NULL;
}
void push(Stack* stack, char value) {
Node* node = (Node*)malloc(sizeof(Node));
node->data = value;
node->next = stack->top;
stack->top = node;
}
char pop(Stack* stack) {
if (isEmpty(stack)) {
return '\0';
}
Node* node = stack->top;
char data = node->data;
stack->top = node->next;
free(node);
return data;
}
char top(const Stack* stack) {
if (isEmpty(stack)) {
return '\0';
}
return stack->top->data;
}
bool match(char left, char right) {
return (left == '(' && right == ')') || (left == '[' && right == ']') || (left == '{' && right == '}');
}
bool isBalanced(const char* str) {
Stack stack;
initStack(&stack);
for (int i = 0; i < strlen(str); i++) {
char c = str[i];
if (c == '(' || c == '[' || c == '{') {
push(&stack, c);
} else if (c == ')' || c == ']' || c == '}') {
if (isEmpty(&stack) || !match(top(&stack), c)) {
return false;
}
pop(&stack);
}
}
return isEmpty(&stack);
}
int main() {
char* str = "{(1 + 2) * [3 - 4]}/5";
bool result = isBalanced(str);
printf("%s\n", result ? "Balanced" : "Not Balanced");
return 0;
}
示例二:二叉树的遍历
前序遍历、中序遍历和后序遍历是二叉树遍历的三种方式,其中前序遍历和后序遍历可以直接用栈来实现。
首先定义二叉树节点结构体:
typedef struct TreeNode {
int val;
struct TreeNode* left;
struct TreeNode* right;
} TreeNode;
前序遍历:
int* preorderTraversal(TreeNode* root, int* returnSize) {
int* result = (int*)malloc(sizeof(int) * 1000);
*returnSize = 0;
Stack stack;
initStack(&stack);
if (root != NULL) {
push(&stack, root);
}
while (!isEmpty(&stack)) {
TreeNode* node = pop(&stack);
result[(*returnSize)++] = node->val;
if (node->right != NULL) {
push(&stack, node->right);
}
if (node->left != NULL) {
push(&stack, node->left);
}
}
return result;
}
后序遍历:
int* postorderTraversal(TreeNode* root, int* returnSize) {
int* result = (int*)malloc(sizeof(int) * 1000);
*returnSize = 0;
Stack stack;
initStack(&stack);
if (root != NULL) {
push(&stack, root);
}
while (!isEmpty(&stack)) {
TreeNode* node = top(&stack);
if (node->left != NULL && node->left->val != INT_MIN) {
push(&stack, node->left);
node->left->val = INT_MIN;
} else if (node->right != NULL && node->right->val != INT_MIN) {
push(&stack, node->right);
node->right->val = INT_MIN;
} else {
pop(&stack);
result[(*returnSize)++] = node->val;
}
}
return result;
}
以上是我使用指针在C语言中实现栈数据结构的方法和两个示例说明,希望对你有所帮助。