Shell脚本如何实现LIFO栈

wen 实用脚本 8

本文目录导读:

Shell脚本如何实现LIFO栈

  1. 方法一:使用数组(推荐,Bash 4+)
  2. 方法二:使用文件实现(适用于所有Shell)
  3. 方法三:使用函数和变量(简单实现)
  4. 方法四:使用关联数组(适合复杂场景)
  5. 实用封装版本
  6. 推荐使用

在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版本和兼容性要求。

抱歉,评论功能暂时关闭!