本文目录导读:

在Shell脚本中实现LIFO(后进先出)栈,有几种常见方法,以下是几种实现方式:
使用数组(推荐,Bash 4+)
#!/bin/bash
# 初始化栈
stack=()
# 压栈操作
push() {
stack+=("$1")
echo "Pushed: $1"
}
# 弹栈操作
pop() {
if [ ${#stack[@]} -eq 0 ]; then
echo "Stack is empty!"
return 1
fi
local last_index=$((${#stack[@]} - 1))
local value="${stack[$last_index]}"
unset stack[$last_index]
# 重新索引
stack=("${stack[@]}")
echo "Popped: $value"
return 0
}
# 查看栈顶元素
peek() {
if [ ${#stack[@]} -eq 0 ]; then
echo "Stack is empty!"
return 1
fi
echo "Top: ${stack[-1]}"
}
# 显示栈大小
size() {
echo "Stack size: ${#stack[@]}"
}
# 显示所有元素
display() {
if [ ${#stack[@]} -eq 0 ]; then
echo "Stack is empty!"
return
fi
echo "Stack (top to bottom):"
for ((i=${#stack[@]}-1; i>=0; i--)); do
echo " ${stack[i]}"
done
}
# 测试
push "apple"
push "banana"
push "cherry"
display
pop
pop
display
push "date"
display
使用文件实现(适用于所有Shell)
#!/bin/sh
# 栈文件
STACK_FILE="/tmp/lifo_stack_$$"
# 初始化
init_stack() {
> "$STACK_FILE"
}
# 压栈
push() {
echo "$1" >> "$STACK_FILE"
echo "Pushed: $1"
}
# 弹栈
pop() {
if [ ! -s "$STACK_FILE" ]; then
echo "Stack is empty!"
return 1
fi
# 获取最后一行
local value=$(tail -1 "$STACK_FILE")
# 删除最后一行
head -n -1 "$STACK_FILE" > "${STACK_FILE}.tmp"
mv "${STACK_FILE}.tmp" "$STACK_FILE"
echo "Popped: $value"
return 0
}
# 查看栈顶
peek() {
if [ ! -s "$STACK_FILE" ]; then
echo "Stack is empty!"
return 1
fi
tail -1 "$STACK_FILE"
}
# 显示栈大小
size() {
wc -l < "$STACK_FILE" | tr -d ' '
}
# 显示所有元素
display() {
if [ ! -s "$STACK_FILE" ]; then
echo "Stack is empty!"
return
fi
echo "Stack (top to bottom):"
tac "$STACK_FILE"
}
# 清理
cleanup() {
rm -f "$STACK_FILE" "${STACK_FILE}.tmp"
}
# 测试
init_stack
push "apple"
push "banana"
push "cherry"
display
pop
pop
display
push "date"
display
# 清理
cleanup
使用函数和变量(简单实现)
#!/bin/bash
# 全局栈变量
stack_items=()
stack_count=0
# 压栈
push() {
stack_items[$stack_count]="$1"
((stack_count++))
echo "Pushed: $1"
}
# 弹栈
pop() {
if [ $stack_count -eq 0 ]; then
echo "Stack is empty!"
return 1
fi
((stack_count--))
local value="${stack_items[$stack_count]}"
unset stack_items[$stack_count]
echo "Popped: $value"
}
# 测试
push "A"
push "B"
push "C"
echo "Stack count: $stack_count"
pop
pop
push "D"
pop
pop
pop # 空栈测试
使用关联数组(适合复杂场景)
#!/bin/bash
# 栈对象
declare -A stack
stack_top=-1
# 压栈
push() {
((stack_top++))
stack[$stack_top]="$1"
echo "Pushed: $1 (index: $stack_top)"
}
# 弹栈
pop() {
if [ $stack_top -lt 0 ]; then
echo "Stack is empty!"
return 1
fi
local value="${stack[$stack_top]}"
unset stack[$stack_top]
((stack_top--))
echo "Popped: $value"
}
# 测试
push "first"
push "second"
push "third"
echo "---"
pop
pop
push "fourth"
pop
pop
实用封装版本
#!/bin/bash
# 栈类
Stack() {
local -n stack=$1
local operation=$2
local value=$3
case $operation in
push)
stack+=("$value")
echo "Pushed: $value"
;;
pop)
if [ ${#stack[@]} -eq 0 ]; then
echo "Stack is empty!"
return 1
fi
local last_index=$((${#stack[@]} - 1))
local popped="${stack[$last_index]}"
unset stack[$last_index]
stack=("${stack[@]}")
echo "Popped: $popped"
;;
peek)
if [ ${#stack[@]} -eq 0 ]; then
echo "Stack is empty!"
return 1
fi
echo "Top: ${stack[-1]}"
;;
size)
echo "Size: ${#stack[@]}"
;;
display)
echo "Stack (top to bottom):"
for ((i=${#stack[@]}-1; i>=0; i--)); do
echo " ${stack[i]}"
done
;;
*)
echo "Unknown operation: $operation"
return 1
;;
esac
}
# 使用示例
my_stack=()
Stack my_stack push "apple"
Stack my_stack push "banana"
Stack my_stack push "cherry"
Stack my_stack display
Stack my_stack pop
Stack my_stack pop
Stack my_stack display
Stack my_stack size
推荐使用
- 数组方式(方法一):最简单直接,性能好
- 文件方式(方法二):跨平台兼容性好,适合所有shell
- 封装版本:代码复用性强,适合大型脚本
选择哪种方式取决于你的具体需求、Shell版本和兼容性要求。