栈是一种特殊的数据结构,只能在一端进行插入和删除操作。栈的特点是后进先出(LIFO,Last In First Out),也就是最后进入的元素最先被处理。
栈的应用非常广泛,以下是一些典型应用场景:
1、函数调用
在程序中,每个函数调用都需要将当前状态的信息(比如函数调用前的参数、局部变量和程序计数器等)保存到栈中,等到函数调用结束后再从栈中弹出这些信息,恢复调用前的状态。这个过程被称作函数的压栈和弹栈操作。
2、表达式求值
通常我们在计算机中对表达式求值时都采用栈来实现。比如中缀表达式转后缀表达式的操作就需要使用栈。
3、系统调用
在操作系统中,内核通常会将一个系统调用的参数、返回值和程序计数器等状态保存到进程的用户栈中,在系统调用结束后再从栈中弹出这些信息,恢复调用前的状态。
4、缓存机制
缓存通常也使用栈的方式实现,被访问的数据最先进入栈顶,最后的则返回底部。例如:网页缓存
5、代码编辑器
用栈来判断括号是否成对,以及最近的括号匹配情况。若左括号,则入栈;若右括号,则将栈顶元素弹出,若是对应的左括号,则继续遍历;否则匹配失败。
6、进制转换
利用栈可以实现很多不同类型的算法,其中包括进制转换。下面是一个 Python 实现示例:
def decimal_to_binary(decimal_num: int) -> str:
"""
将一个十进制整数转换为二进制字符串
"""
stack = []
while decimal_num > 0:
remainder = decimal_num % 2
stack.append(remainder)
decimal_num //= 2
binary_str = ""
while stack:
binary_str += str(stack.pop())
return binary_str
def decimal_to_hexadecimal(decimal_num: int) -> str:
"""
将一个十进制整数转换为十六进制字符串
"""
hex_table = "0123456789ABCDEF"
stack = []
while decimal_num > 0:
remainder = decimal_num % 16
stack.append(hex_table[remainder])
decimal_num //= 16
hex_str = ""
while stack:
hex_str += stack.pop()
return hex_str
以上代码包含两个函数,decimal_to_binary() 和 decimal_to_hexadecimal(),分别用于将一个十进制整数转换为二进制和十六进制字符串。它们的实现非常相似,只有进制数和用于转换的字符表不同。
这里使用了一个栈,该栈由余数(或模数)组成。在主循环中,每次将取得的余数推入栈中,并将被转换数除以进制数以便下一次迭代。一旦没有元素需要被推入栈中,我们开始按照 FILO 的原则依次取出余数,将其转换为对应的进制符号,并附加到结果字符串的末尾。最后结果字符串即为转换结果。
可以通过调用上述函数将一个整数从十进制转换为其他进制。
#include
#include
// 定义一个递归函数,用于将十进制数字转换为二进制并反转输出
void reverse(int num) {
// 如果 num 是 1 或 0,则直接将其转化为二进制输出
if (num == 1 || num == 0){
printf("%d", num%2);
return;
}
// 取 num 对 2 的余数,输出
printf("%d", num%2);
// 用 floor 函数将 num 除以 2 取整,作为下一次递归的参数
reverse(floor(num/2));
}
int main()
{
int num = 20;
// 调用 reverse 函数,将十进制数字 num 转换为二进制并反转输出
reverse(num);
return 0;
}
以上代码展示了一个将十进制数字转换为二进制并反转输出的递归函数 reverse()。该函数的实现思路是通过对十进制数字不断取模(余数)来得到对应的二进制数字,并将其输出。然后使用 floor() 函数将当前的十进制数字除以 2 取整,并递归传入新的参数,反复递归直到数字变成 0 或 1 此时输出 0 或 1。
在 main() 函数中,定义一个十进制数字 num,并将其传入 reverse() 函数中进行二进制转换和反转输出。最后返回 0,结束程序的执行。