完整教程:【数据结构】顺序栈的基本操作

目录

一、数据结构定义:顺序栈的存储结构

二、基础操作算法

1. 初始化栈(InitStack)

2. 判断栈空(StackEmpty)

3. 判断栈满(StackFull)

4. 求栈长度(StackLength)

5. 清空栈(ClearStack)

6. 销毁栈(DestroyStack)

7. 入栈(Push)

8. 出栈(Pop)

9. 获取栈顶元素(GetTop)

三、扩展操作算法

1. 栈扩容(ExpandStack)

2. 栈遍历(TraverseStack)

3. 栈复制(CopyStack)

4. 栈比较(CompareStack)

四、典型应用:进制转换(Conversion)

五、顺序栈的基本操作的代码完整实现

(一)C++代码

(二)Python代码

(三)Java代码

六、程序运行结果展示

(一)C++程序运行截图

(二)Python程序运行截图

(三)Java程序运行截图

七、算法整体总结


一、数据结构定义:顺序栈的存储结构

typedef int SElemType;  // 栈元素类型(可替换为其他类型,如char、struct等)
typedef struct {
    SElemType *base;    // 栈底指针:指向数组起始位置(固定不变,除非扩容)
    SElemType *top;     // 栈顶指针:指向栈顶元素的**下一个位置**(空栈时与base重合)
    int stacksize;      // 当前栈的最大容量(数组长度)
    int increment;      // 扩容增量:栈满时自动扩容的大小
} SqStack;

设计思想:用动态数组(base指向的连续内存)存储栈元素,通过topbase的差值计算栈中元素数量,通过stacksize限制最大容量,increment支持动态扩容。

二、基础操作算法

1. 初始化栈(InitStack
void InitStack(SqStack &S, int incr = INCREMENT) {
    S.base = new SElemType[MAXSIZE];  // 分配初始容量为MAXSIZE的数组
    if (!S.base) {  // 内存分配失败检查
        cerr << "内存分配失败,栈初始化失败!" << endl;
        exit(EXIT_FAILURE);
    }
    S.top = S.base;  // 空栈:栈顶指针与栈底指针重合
    S.stacksize = MAXSIZE;  // 初始容量
    S.increment = (incr > 0) ? incr : INCREMENT;  // 确保扩容增量为正数
}

算法逻辑

  • 为栈分配初始内存(大小MAXSIZE),base指向内存首地址;
  • 空栈时topbase指向同一位置,stacksize记录初始容量,increment设置扩容步长;
  • 处理内存分配失败的异常(直接退出程序,避免后续错误)。时间复杂度:O (1)(仅内存分配和指针赋值)。
2. 判断栈空(StackEmpty
bool StackEmpty(SqStack S) {
    return (S.base == S.top);  // 栈顶与栈底重合 → 空栈
}

算法逻辑:栈的本质是 “top指针移动”:空栈时top未移动,与base指向同一位置,直接通过指针比较判断。时间复杂度:O(1)。

3. 判断栈满(StackFull
bool StackFull(SqStack S) {
    return (S.top - S.base == S.stacksize);  // 元素数量等于最大容量 → 栈满
}

算法逻辑top - base计算当前元素数量(因top指向栈顶元素下一个位置,差值即元素个数),若等于stacksize则栈满。时间复杂度:O(1)。

4. 求栈长度(StackLength
int StackLength(SqStack S) {
    return (S.top - S.base);  // 指针差值即元素个数
}

算法逻辑:利用指针算术:topbase均指向同类型数组元素,差值即为两指针间的元素数量(栈中有效元素个数)。时间复杂度:O(1)。

5. 清空栈(ClearStack
void ClearStack(SqStack &S) {
    if (S.base) {  // 栈已初始化(base非空)
        S.top = S.base;  // 重置栈顶指针至栈底 → 逻辑清空(不释放内存)
    }
}

算法逻辑:“清空” 是逻辑操作,无需删除元素或释放内存,只需将top指针重置为base,后续入栈会覆盖原有元素。时间复杂度:O(1)。

6. 销毁栈(DestroyStack
void DestroyStack(SqStack &S) {
    if (S.base) {  // 栈已初始化
        delete[] S.base;  // 释放动态分配的数组内存
        S.base = S.top = nullptr;  // 指针置空,避免野指针
        S.stacksize = 0;  // 容量清零
        S.increment = 0;  // 扩容增量清零
    }
}

算法逻辑:“销毁” 是物理操作,释放base指向的动态内存(彻底删除所有元素),并将所有指针和属性重置,避免内存泄漏。时间复杂度:O (1)(内存释放操作视为常数时间)。

7. 入栈(Push
bool Push(SqStack &S, SElemType e) {
    // 栈满时尝试扩容,若扩容失败则入栈失败
    if (StackFull(S) && !ExpandStack(S)) {
        cerr << "栈已满且扩容失败,无法入栈!" << endl;
        return false;
    }
    *S.top++ = e;  // 先将元素e存入top指向的位置,再将top指针后移一位
    return true;
}

算法逻辑

  1. 检查栈是否已满:若满则调用ExpandStack扩容,扩容失败则返回false
  2. 入栈操作:将元素e存入top当前指向的位置,然后top指针后移(指向新的栈顶空位)。核心细节*S.top++ = e 等价于 *S.top = e; S.top++;,符合栈顶指针 “先存后移” 的规则。时间复杂度:O (1)(无扩容时);O (n)(扩容时,需复制原数组元素,n 为当前栈容量)。
8. 出栈(Pop
bool Pop(SqStack &S, SElemType &e) {
    if (StackEmpty(S)) {  // 空栈无法出栈
        cerr << "栈为空,无法出栈!" << endl;
        return false;
    }
    e = *--S.top;  // 先将top指针前移一位,再取出该位置的元素
    return true;
}

算法逻辑

  1. 检查栈是否为空:空栈则返回false
  2. 出栈操作:top指针先前移一位(指向栈顶元素),再将该元素的值通过引用e返回。核心细节e = *--S.top 等价于 S.top--; e = *S.top;,符合栈顶指针 “先移后取” 的规则。时间复杂度:O(1)。
9. 获取栈顶元素(GetTop
bool GetTop(SqStack S, SElemType &e) {
    if (StackEmpty(S)) {  // 空栈无栈顶元素
        cerr << "栈为空,无栈顶元素!" << endl;
        return false;
    }
    e = *(S.top - 1);  // 栈顶元素在top指针的前一个位置
    return true;
}

算法逻辑:栈顶元素位于top指针的前一个位置(因top指向栈顶元素的下一个空位),直接通过S.top - 1访问,不移动top指针(与出栈的区别)。时间复杂度:O(1)。

三、扩展操作算法

1. 栈扩容(ExpandStack
bool ExpandStack(SqStack &S) {
    // 分配新内存:原容量 + 扩容增量
    SElemType *newBase = new SElemType[S.stacksize + S.increment];
    if (!newBase) {  // 内存分配失败
        cerr << "内存分配失败,栈扩容失败!" << endl;
        return false;
    }
    // 复制原栈元素到新内存(字节数 = 原容量 * 元素大小)
    memcpy(newBase, S.base, S.stacksize * sizeof(SElemType));
    delete[] S.base;  // 释放原内存
    // 更新指针和容量:top指针位置 = 新基地址 + 原元素个数(top - base)
    S.top = newBase + (S.top - S.base);
    S.base = newBase;  // 新基地址
    S.stacksize += S.increment;  // 容量增加
    cout << "栈已扩容,新容量:" << S.stacksize << endl;
    return true;
}

算法逻辑:当栈满时,通过 “重新分配更大内存→复制原元素→释放旧内存→更新指针” 实现动态扩容:

  1. 分配大小为stacksize + increment的新内存;
  2. memcpy复制原数组所有元素到新内存(保证数据不丢失);
  3. 释放原内存,避免泄漏;
  4. 更新base为新内存地址,top为新地址 + 原元素个数(保持栈顶位置不变),stacksize增加。时间复杂度:O (n)(n 为当前栈容量,因需复制所有元素)。空间复杂度:O (n + increment)(新内存大小)。
2. 栈遍历(TraverseStack
void TraverseStack(SqStack S, void (*visit)(SElemType)) {
    if (StackEmpty(S)) {
        cout << "栈为空,无元素可遍历!" << endl;
        return;
    }
    SElemType *p = S.base;  // 从栈底开始遍历
    cout << "栈元素(从栈底到栈顶):";
    while (p < S.top) {  // 遍历至栈顶(top前一个位置)
        visit(*p++);  // 调用回调函数处理元素(如打印),指针后移
        cout << " ";
    }
    cout << endl;
}
// 回调函数:打印元素
void PrintElem(SElemType e) {
    cout << e;
}

算法逻辑:从栈底(base)到栈顶(top前一个位置)依次访问元素,通过回调函数visit处理元素(此处为打印):

  • 遍历顺序:栈底→栈顶(与栈的 “后进先出” 特性无关,仅为完整访问所有元素);
  • 灵活性:通过不同的visit函数可实现多种遍历操作(如求和、查找等)。时间复杂度:O (n)(n 为栈长度,需访问每个元素)。
3. 栈复制(CopyStack
bool CopyStack(SqStack S, SqStack &T) {
    DestroyStack(T);  // 先销毁T的原有数据,避免内存泄漏
    // 为T分配与S相同的容量和扩容增量
    T.increment = S.increment;
    T.stacksize = S.stacksize;
    T.base = new SElemType[T.stacksize];
    if (!T.base) {  // 内存分配失败
        cerr << "内存分配失败,栈复制失败!" << endl;
        return false;
    }
    // 复制元素:T的元素个数 = S的元素个数(top - base)
    T.top = T.base + (S.top - S.base);
    memcpy(T.base, S.base, (S.top - S.base) * sizeof(SElemType));
    return true;
}

算法逻辑:将栈S的所有元素和属性复制到栈T,保证TS完全一致:

  1. 先销毁T原有数据(避免内存泄漏);
  2. T分配与S相同的容量和扩容增量;
  3. 复制S的元素到T(通过memcpy),并设置T.top使元素个数与S相同。时间复杂度:O (n)(n 为S的长度,需复制所有元素)。
4. 栈比较(CompareStack
bool CompareStack(SqStack S, SqStack T) {
    if (StackLength(S) != StackLength(T)) {  // 长度不同则直接不等
        return false;
    }
    // 逐个比较元素(从栈底到栈顶)
    SElemType *p = S.base, *q = T.base;
    while (p < S.top && q < T.top) {
        if (*p++ != *q++) {  // 有一个元素不同则不等
            return false;
        }
    }
    return true;  // 长度相同且所有元素相同
}

算法逻辑:判断两个栈是否 “完全相等”(元素序列和长度均相同):

  1. 先比较长度:长度不同则直接返回false
  2. 再逐个比较元素(从栈底到栈顶):若所有元素对应相等则返回true,否则false时间复杂度:O (n)(n 为栈长度,最坏情况需比较所有元素)。

四、典型应用:进制转换(Conversion

void Conversion(int num, int base) {
    if (base < 2 || base > 16) {  // 校验进制合法性(2-16进制)
        cerr << "进制必须在2-16之间!" << endl;
        return;
    }
    SqStack stack;
    InitStack(stack);
    int n = num;
    char digits[] = "0123456789ABCDEF";  // 16进制字符映射表
    // 特殊处理:0的转换
    if (n == 0) {
        Push(stack, 0);
    } else {
        bool isNegative = false;
        if (n < 0) {  // 处理负数(先转为正数,最后加负号)
            isNegative = true;
            n = -n;
        }
        // 核心:除基取余法,余数入栈(后出栈即得转换结果)
        while (n > 0) {
            Push(stack, n % base);  // 余数入栈
            n = n / base;  // 商继续计算
        }
        if (isNegative) {  // 负数标记
            cout << "-";
        }
    }
    // 出栈并打印结果(栈中余数的逆序即转换结果)
    cout << num << " 转换为 " << base << " 进制是:";
    SElemType e;
    while (Pop(stack, e)) {
        cout << digits[e];  // 用映射表输出字符(如10→A)
    }
    cout << endl;
    DestroyStack(stack);  // 销毁临时栈
}

算法逻辑:利用栈的 “后进先出” 特性实现十进制到base进制(2-16)的转换,核心是 “除基取余法”:

  1. 原理:十进制数num除以base,余数为base进制的低位,商继续除以base,直到商为 0;最后将余数逆序排列即得结果(栈恰好可实现 “逆序”)。
  2. 步骤
    • 处理特殊情况:num=0直接入栈 0;
    • 处理负数:先转为正数,转换后加负号;
    • 除基取余:n = num,循环计算n % base(余数入栈)和n = n / base(商);
    • 出栈输出:栈中余数的出栈顺序即为转换结果的正确顺序(因先入栈的余数是低位,后出栈)。
  3. 字符映射:用digits数组将 10-15 映射为 'A'-'F'(支持 16 进制)。

时间复杂度:O (logₖn)(n 为十进制数大小,k 为目标进制,循环次数为 n 除以 k 的次数)。

五、顺序栈的基本操作的代码完整实现

(一)C++代码
#include 
#include 
#include   // 引入Windows系统头文件
using namespace std;
#define MAXSIZE 100    // 初始栈容量
#define INCREMENT 10   // 栈扩容增量
// 栈元素类型定义(可根据需要修改为其他类型)
typedef int SElemType;
// 顺序栈结构定义
typedef struct {
    SElemType *base;  // 栈底指针
    SElemType *top;   // 栈顶指针(指向栈顶元素的下一个位置)
    int stacksize;    // 当前栈的最大容量
    int increment;    // 扩容增量(可动态调整)
} SqStack;
// 函数声明
void InitStack(SqStack &S, int incr = INCREMENT);    // 初始化栈(可指定扩容增量)
bool StackEmpty(SqStack S);                          // 判断栈是否为空
bool StackFull(SqStack S);                           // 判断栈是否已满
int StackLength(SqStack S);                          // 获取栈长度
void ClearStack(SqStack &S);                         // 清空栈
void DestroyStack(SqStack &S);                       // 销毁栈
bool Push(SqStack &S, SElemType e);                  // 入栈(支持自动扩容)
bool Pop(SqStack &S, SElemType &e);                  // 出栈(通过引用返回元素)
bool GetTop(SqStack S, SElemType &e);                // 获取栈顶元素(通过引用返回)
void TraverseStack(SqStack S, void (*visit)(SElemType)); // 遍历栈元素
bool ExpandStack(SqStack &S);                        // 栈扩容
bool CopyStack(SqStack S, SqStack &T);               // 复制栈(S复制到T)
bool CompareStack(SqStack S, SqStack T);             // 比较两个栈是否相等
void Conversion(int num, int base);                  // 应用:进制转换(利用栈)
void PrintElem(SElemType e);                         // 声明PrintElem函数,用于遍历
// 测试函数
int main() {
    SetConsoleOutputCP(CP_UTF8);  // 强制控制台使用UTF-8解析输出
    SqStack S, T;
    SElemType e;
    // 初始化栈
    InitStack(S, 20); // 自定义扩容增量为20
    cout << "初始化栈S完成,初始容量:" << S.stacksize << endl;
    // 测试入栈
    cout << "\n=== 入栈测试 ===" << endl;
    for (int i = 1; i <= 150; i++) { // 超过初始容量,测试扩容
        if (Push(S, i)) {
            if (i % 30 == 0) { // 每30个元素打印一次状态
                cout << "已入栈" << i << "个元素,当前栈长度:" << StackLength(S) << endl;
            }
        }
    }
    // 测试遍历
    cout << "\n=== 遍历测试 ===" << endl;
    TraverseStack(S, PrintElem);
    // 测试栈顶元素
    cout << "\n=== 栈顶元素测试 ===" << endl;
    if (GetTop(S, e)) {
        cout << "当前栈顶元素:" << e << endl;
    }
    // 测试出栈
    cout << "\n=== 出栈测试 ===" << endl;
    for (int i = 0; i < 5; i++) {
        if (Pop(S, e)) {
            cout << "出栈元素:" << e << ",剩余栈长度:" << StackLength(S) << endl;
        }
    }
    // 测试复制栈
    cout << "\n=== 复制栈测试 ===" << endl;
    if (CopyStack(S, T)) {
        cout << "栈S复制到栈T成功!" << endl;
        cout << "栈T的元素:";
        TraverseStack(T, PrintElem);
    }
    // 测试比较栈
    cout << "\n=== 比较栈测试 ===" << endl;
    cout << "栈S和栈T是否相等:" << (CompareStack(S, T) ? "是" : "否") << endl;
    Push(T, 999); // 修改栈T
    cout << "栈T添加元素999后,是否相等:" << (CompareStack(S, T) ? "是" : "否") << endl;
    // 测试清空栈
    cout << "\n=== 清空栈测试 ===" << endl;
    ClearStack(S);
    cout << "清空栈S后,栈是否为空:" << (StackEmpty(S) ? "是" : "否") << endl;
    // 测试进制转换应用
    cout << "\n=== 进制转换测试 ===" << endl;
    Conversion(123, 2);   // 十进制123转二进制
    Conversion(255, 16);  // 十进制255转十六进制
    Conversion(-100, 8);  // 十进制-100转八进制
    Conversion(0, 10);    // 十进制0转十进制
    // 销毁栈
    DestroyStack(S);
    DestroyStack(T);
    cout << "\n所有栈已销毁,程序结束!" << endl;
    return 0;
}
// 初始化栈
void InitStack(SqStack &S, int incr) {
    S.base = new SElemType[MAXSIZE];
    if (!S.base) {
        cerr << "内存分配失败,栈初始化失败!" << endl;
        exit(EXIT_FAILURE);
    }
    S.top = S.base;
    S.stacksize = MAXSIZE;
    S.increment = (incr > 0) ? incr : INCREMENT; // 确保扩容增量为正数
}
// 判断栈是否为空
bool StackEmpty(SqStack S) {
    return (S.base == S.top);
}
// 判断栈是否已满
bool StackFull(SqStack S) {
    return (S.top - S.base == S.stacksize);
}
// 获取栈长度
int StackLength(SqStack S) {
    return (S.top - S.base);
}
// 清空栈
void ClearStack(SqStack &S) {
    if (S.base) {
        S.top = S.base; // 仅需重置栈顶指针
    }
}
// 销毁栈
void DestroyStack(SqStack &S) {
    if (S.base) {
        delete[] S.base;  // 释放堆内存
        S.base = S.top = nullptr; // 避免野指针
        S.stacksize = 0;
        S.increment = 0;
    }
}
// 栈扩容
bool ExpandStack(SqStack &S) {
    SElemType *newBase = new SElemType[S.stacksize + S.increment];
    if (!newBase) {
        cerr << "内存分配失败,栈扩容失败!" << endl;
        return false;
    }
    // 复制原有元素
    memcpy(newBase, S.base, S.stacksize * sizeof(SElemType));
    // 释放旧内存
    delete[] S.base;
    // 更新栈指针和容量
    S.top = newBase + (S.top - S.base);
    S.base = newBase;
    S.stacksize += S.increment;
    cout << "栈已扩容,新容量:" << S.stacksize << endl;
    return true;
}
// 入栈(支持自动扩容)
bool Push(SqStack &S, SElemType e) {
    // 栈满时尝试扩容
    if (StackFull(S) && !ExpandStack(S)) {
        cerr << "栈已满且扩容失败,无法入栈!" << endl;
        return false;
    }
    *S.top++ = e; // 先赋值后移动栈顶指针
    return true;
}
// 出栈(通过引用返回元素)
bool Pop(SqStack &S, SElemType &e) {
    if (StackEmpty(S)) {
        cerr << "栈为空,无法出栈!" << endl;
        return false;
    }
    e = *--S.top; // 先移动栈顶指针后取值
    return true;
}
// 获取栈顶元素(通过引用返回)
bool GetTop(SqStack S, SElemType &e) {
    if (StackEmpty(S)) {
        cerr << "栈为空,无栈顶元素!" << endl;
        return false;
    }
    e = *(S.top - 1); // 栈顶指针前一个位置是栈顶元素
    return true;
}
// 遍历栈元素(从栈底到栈顶)
void TraverseStack(SqStack S, void (*visit)(SElemType)) {
    if (StackEmpty(S)) {
        cout << "栈为空,无元素可遍历!" << endl;
        return;
    }
    SElemType *p = S.base;
    cout << "栈元素(从栈底到栈顶):";
    while (p < S.top) {
        visit(*p++);
        cout << " ";
    }
    cout << endl;
}
// 显示元素的函数(用于遍历)
void PrintElem(SElemType e) {
    cout << e;
}
// 复制栈(将栈S复制到栈T)
bool CopyStack(SqStack S, SqStack &T) {
    // 先销毁T的原有数据
    DestroyStack(T);
    // 初始化T,容量与S相同
    T.increment = S.increment;
    T.stacksize = S.stacksize;
    T.base = new SElemType[T.stacksize];
    if (!T.base) {
        cerr << "内存分配失败,栈复制失败!" << endl;
        return false;
    }
    // 复制元素
    T.top = T.base + (S.top - S.base);
    memcpy(T.base, S.base, (S.top - S.base) * sizeof(SElemType));
    return true;
}
// 比较两个栈是否相等(元素序列和长度均相同)
bool CompareStack(SqStack S, SqStack T) {
    // 长度不同则直接不等
    if (StackLength(S) != StackLength(T)) {
        return false;
    }
    // 逐个比较元素
    SElemType *p = S.base, *q = T.base;
    while (p < S.top && q < T.top) {
        if (*p++ != *q++) {
            return false;
        }
    }
    return true;
}
// 应用:利用栈实现进制转换(十进制转base进制,base在2-16之间)
void Conversion(int num, int base) {
    if (base < 2 || base > 16) {
        cerr << "进制必须在2-16之间!" << endl;
        return;
    }
    SqStack stack;
    InitStack(stack);
    int n = num;
    char digits[] = "0123456789ABCDEF"; // 16进制以下的数字字符
    // 特殊情况:0的转换
    if (n == 0) {
        Push(stack, 0);
    } else {
        // 处理负数
        bool isNegative = false;
        if (n < 0) {
            isNegative = true;
            n = -n;
        }
        // 取余入栈
        while (n > 0) {
            Push(stack, n % base);
            n = n / base;
        }
        // 负数标记
        if (isNegative) {
            cout << "-";
        }
    }
    // 出栈并打印结果
    cout << num << " 转换为 " << base << " 进制是:";
    SElemType e;
    while (Pop(stack, e)) {
        cout << digits[e];
    }
    cout << endl;
    DestroyStack(stack);
}
(二)Python代码
class SqStack:
    def __init__(self, increment=10):
        """初始化栈"""
        self.MAXSIZE = 100  # 初始栈容量
        self.base = [0] * self.MAXSIZE  # 栈底(用列表模拟动态数组)
        self.top = 0  # 栈顶指针(指向栈顶元素的下一个位置,初始为0)
        self.stacksize = self.MAXSIZE  # 当前栈的最大容量
        self.increment = increment if increment > 0 else 10  # 扩容增量
    def is_empty(self):
        """判断栈是否为空"""
        return self.top == 0
    def is_full(self):
        """判断栈是否已满"""
        return self.top == self.stacksize
    def length(self):
        """获取栈长度"""
        return self.top
    def clear(self):
        """清空栈"""
        self.top = 0  # 仅重置栈顶指针
    def destroy(self):
        """销毁栈"""
        self.base = []
        self.top = 0
        self.stacksize = 0
        self.increment = 0
    def expand(self):
        """栈扩容"""
        try:
            # 创建新的更大容量的列表
            new_base = [0] * (self.stacksize + self.increment)
            # 复制原有元素
            for i in range(self.stacksize):
                new_base[i] = self.base[i]
            # 更新栈属性
            self.base = new_base
            self.stacksize += self.increment
            print(f"栈已扩容,新容量:{self.stacksize}")
            return True
        except MemoryError:
            print("内存分配失败,栈扩容失败!")
            return False
    def push(self, e):
        """入栈(支持自动扩容)"""
        # 栈满时尝试扩容
        if self.is_full() and not self.expand():
            print("栈已满且扩容失败,无法入栈!")
            return False
        self.base[self.top] = e
        self.top += 1
        return True
    def pop(self):
        """出栈(返回元素和操作结果)"""
        if self.is_empty():
            print("栈为空,无法出栈!")
            return None, False
        self.top -= 1
        return self.base[self.top], True
    def get_top(self):
        """获取栈顶元素"""
        if self.is_empty():
            print("栈为空,无栈顶元素!")
            return None, False
        return self.base[self.top - 1], True
    def traverse(self, visit_func):
        """遍历栈元素(从栈底到栈顶)"""
        if self.is_empty():
            print("栈为空,无元素可遍历!")
            return
        print("栈元素(从栈底到栈顶):", end="")
        for i in range(self.top):
            visit_func(self.base[i])
            print(" ", end="")
        print()
def print_elem(e):
    """用于遍历的打印函数"""
    print(e, end="")
def copy_stack(s):
    """复制栈(s复制到新栈)"""
    t = SqStack(s.increment)
    # 销毁原有数据(在Python中只需重置即可)
    t.base = [0] * s.stacksize
    t.stacksize = s.stacksize
    t.top = s.top
    # 复制元素
    for i in range(s.top):
        t.base[i] = s.base[i]
    return t
def compare_stack(s, t):
    """比较两个栈是否相等"""
    if s.length() != t.length():
        return False
    for i in range(s.top):
        if s.base[i] != t.base[i]:
            return False
    return True
def conversion(num, base):
    """应用:利用栈实现进制转换(十进制转base进制,base在2-16之间)"""
    if base < 2 or base > 16:
        print("进制必须在2-16之间!")
        return
    stack = SqStack()
    n = num
    digits = "0123456789ABCDEF"  # 16进制以下的数字字符
    # 特殊情况:0的转换
    if n == 0:
        stack.push(0)
    else:
        # 处理负数
        is_negative = False
        if n < 0:
            is_negative = True
            n = -n
        # 取余入栈
        while n > 0:
            stack.push(n % base)
            n = n // base
        # 负数标记
        if is_negative:
            print("-", end="")
    # 出栈并打印结果
    print(f"{num} 转换为 {base} 进制是:", end="")
    while not stack.is_empty():
        elem, _ = stack.pop()
        print(digits[elem], end="")
    print()
# 测试函数
def main():
    # 初始化栈
    s = SqStack(20)  # 自定义扩容增量为20
    print(f"初始化栈S完成,初始容量:{s.stacksize}")
    # 测试入栈
    print("\n=== 入栈测试 ===")
    for i in range(1, 151):  # 超过初始容量,测试扩容
        if s.push(i):
            if i % 30 == 0:  # 每30个元素打印一次状态
                print(f"已入栈{i}个元素,当前栈长度:{s.length()}")
    # 测试遍历
    print("\n=== 遍历测试 ===")
    s.traverse(print_elem)
    # 测试栈顶元素
    print("\n=== 栈顶元素测试 ===")
    top_elem, success = s.get_top()
    if success:
        print(f"当前栈顶元素:{top_elem}")
    # 测试出栈
    print("\n=== 出栈测试 ===")
    for _ in range(5):
        elem, success = s.pop()
        if success:
            print(f"出栈元素:{elem},剩余栈长度:{s.length()}")
    # 测试复制栈
    print("\n=== 复制栈测试 ===")
    t = copy_stack(s)
    print("栈S复制到栈T成功!")
    print("栈T的元素:", end="")
    t.traverse(print_elem)
    # 测试比较栈
    print("\n=== 比较栈测试 ===")
    print(f"栈S和栈T是否相等:{'是' if compare_stack(s, t) else '否'}")
    t.push(999)  # 修改栈T
    print(f"栈T添加元素999后,是否相等:{'是' if compare_stack(s, t) else '否'}")
    # 测试清空栈
    print("\n=== 清空栈测试 ===")
    s.clear()
    print(f"清空栈S后,栈是否为空:{'是' if s.is_empty() else '否'}")
    # 测试进制转换应用
    print("\n=== 进制转换测试 ===")
    conversion(123, 2)   # 十进制123转二进制
    conversion(255, 16)  # 十进制255转十六进制
    conversion(-100, 8)  # 十进制-100转八进制
    conversion(0, 10)    # 十进制0转十进制
    # 销毁栈
    s.destroy()
    t.destroy()
    print("\n所有栈已销毁,程序结束!")
if __name__ == "__main__":
    main()
(三)Java代码
import java.util.Arrays;
// 顺序栈类实现
public class SqStack {
    private int[] base;       // 栈底(用数组模拟)
    private int top;          // 栈顶指针(指向栈顶元素的下一个位置)
    private int stacksize;    // 当前栈的最大容量
    private int increment;    // 扩容增量
    private static final int MAXSIZE = 100;  // 初始栈容量
    private static final int DEFAULT_INCREMENT = 10;  // 默认扩容增量
    // 构造函数(可指定扩容增量)
    public SqStack(int incr) {
        this.increment = incr > 0 ? incr : DEFAULT_INCREMENT;
        this.base = new int[MAXSIZE];
        this.top = 0;
        this.stacksize = MAXSIZE;
    }
    // 默认构造函数
    public SqStack() {
        this(DEFAULT_INCREMENT);
    }
    // 判断栈是否为空
    public boolean isEmpty() {
        return top == 0;
    }
    // 判断栈是否已满
    public boolean isFull() {
        return top == stacksize;
    }
    // 获取栈长度
    public int length() {
        return top;
    }
    // 清空栈
    public void clear() {
        top = 0;  // 仅重置栈顶指针
    }
    // 销毁栈(Java中由垃圾回收机制处理,这里仅做重置)
    public void destroy() {
        base = null;
        top = 0;
        stacksize = 0;
        increment = 0;
    }
    // 栈扩容
    private boolean expand() {
        try {
            // 创建新的更大容量的数组
            int newSize = stacksize + increment;
            int[] newBase = new int[newSize];
            // 复制原有元素
            System.arraycopy(base, 0, newBase, 0, stacksize);
            // 更新栈属性
            base = newBase;
            stacksize = newSize;
            System.out.println("栈已扩容,新容量:" + stacksize);
            return true;
        } catch (OutOfMemoryError e) {
            System.err.println("内存分配失败,栈扩容失败!");
            return false;
        }
    }
    // 入栈(支持自动扩容)
    public boolean push(int e) {
        // 栈满时尝试扩容
        if (isFull() && !expand()) {
            System.err.println("栈已满且扩容失败,无法入栈!");
            return false;
        }
        base[top++] = e;
        return true;
    }
    // 出栈(返回元素,通过返回值null表示失败)
    public Integer pop() {
        if (isEmpty()) {
            System.err.println("栈为空,无法出栈!");
            return null;
        }
        return base[--top];
    }
    // 获取栈顶元素(返回元素,通过返回值null表示失败)
    public Integer getTop() {
        if (isEmpty()) {
            System.err.println("栈为空,无栈顶元素!");
            return null;
        }
        return base[top - 1];
    }
    // 遍历栈元素(从栈底到栈顶)
    public void traverse(VisitFunction visitor) {
        if (isEmpty()) {
            System.out.println("栈为空,无元素可遍历!");
            return;
        }
        System.out.print("栈元素(从栈底到栈顶):");
        for (int i = 0; i < top; i++) {
            visitor.visit(base[i]);
            System.out.print(" ");
        }
        System.out.println();
    }
    // 函数式接口:用于遍历操作
    @FunctionalInterface
    public interface VisitFunction {
        void visit(int e);
    }
    // 复制栈(复制当前栈到新栈)
    public static SqStack copyStack(SqStack s) {
        SqStack t = new SqStack(s.increment);
        // 销毁原有数据并重新初始化
        t.stacksize = s.stacksize;
        t.base = new int[t.stacksize];
        t.top = s.top;
        // 复制元素
        System.arraycopy(s.base, 0, t.base, 0, s.top);
        return t;
    }
    // 比较两个栈是否相等
    public static boolean compareStack(SqStack s, SqStack t) {
        if (s.length() != t.length()) {
            return false;
        }
        for (int i = 0; i < s.top; i++) {
            if (s.base[i] != t.base[i]) {
                return false;
            }
        }
        return true;
    }
    // 应用:利用栈实现进制转换(十进制转base进制,base在2-16之间)
    public static void conversion(int num, int base) {
        if (base < 2 || base > 16) {
            System.err.println("进制必须在2-16之间!");
            return;
        }
        SqStack stack = new SqStack();
        int n = num;
        char[] digits = "0123456789ABCDEF".toCharArray();  // 16进制以下的数字字符
        // 特殊情况:0的转换
        if (n == 0) {
            stack.push(0);
        } else {
            // 处理负数
            boolean isNegative = false;
            if (n < 0) {
                isNegative = true;
                n = -n;
            }
            // 取余入栈
            while (n > 0) {
                stack.push(n % base);
                n = n / base;
            }
            // 负数标记
            if (isNegative) {
                System.out.print("-");
            }
        }
        // 出栈并打印结果
        System.out.print(num + " 转换为 " + base + " 进制是:");
        while (!stack.isEmpty()) {
            int elem = stack.pop();
            System.out.print(digits[elem]);
        }
        System.out.println();
        stack.destroy();
    }
    // 测试函数
    public static void main(String[] args) {
        // 初始化栈
        SqStack s = new SqStack(20);  // 自定义扩容增量为20
        System.out.println("初始化栈S完成,初始容量:" + s.stacksize);
        // 测试入栈
        System.out.println("\n=== 入栈测试 ===");
        for (int i = 1; i <= 150; i++) {  // 超过初始容量,测试扩容
            if (s.push(i)) {
                if (i % 30 == 0) {  // 每30个元素打印一次状态
                    System.out.println("已入栈" + i + "个元素,当前栈长度:" + s.length());
                }
            }
        }
        // 测试遍历
        System.out.println("\n=== 遍历测试 ===");
        s.traverse(e -> System.out.print(e));
        // 测试栈顶元素
        System.out.println("\n\n=== 栈顶元素测试 ===");
        Integer topElem = s.getTop();
        if (topElem != null) {
            System.out.println("当前栈顶元素:" + topElem);
        }
        // 测试出栈
        System.out.println("\n=== 出栈测试 ===");
        for (int i = 0; i < 5; i++) {
            Integer elem = s.pop();
            if (elem != null) {
                System.out.println("出栈元素:" + elem + ",剩余栈长度:" + s.length());
            }
        }
        // 测试复制栈
        System.out.println("\n=== 复制栈测试 ===");
        SqStack t = copyStack(s);
        System.out.println("栈S复制到栈T成功!");
        System.out.print("栈T的元素:");
        t.traverse(e -> System.out.print(e));
        System.out.println();
        // 测试比较栈
        System.out.println("\n=== 比较栈测试 ===");
        System.out.println("栈S和栈T是否相等:" + (compareStack(s, t) ? "是" : "否"));
        t.push(999);  // 修改栈T
        System.out.println("栈T添加元素999后,是否相等:" + (compareStack(s, t) ? "是" : "否"));
        // 测试清空栈
        System.out.println("\n=== 清空栈测试 ===");
        s.clear();
        System.out.println("清空栈S后,栈是否为空:" + (s.isEmpty() ? "是" : "否"));
        // 测试进制转换应用
        System.out.println("\n=== 进制转换测试 ===");
        conversion(123, 2);   // 十进制123转二进制
        conversion(255, 16);  // SqStack十进制255转十六进制
        conversion(-100, 8);  // 十进制-100转八进制
        conversion(0, 10);    // 十进制0转十进制
        // 销毁栈
        s.destroy();
        t.destroy();
        System.out.println("\n所有栈已销毁,程序结束!");
    }
}

六、程序运行结果展示

(一)C++程序运行截图

(二)Python程序运行截图

(三)Java程序运行截图

七、算法整体总结

该代码通过 “动态数组 + 指针” 实现了顺序栈的完整操作,核心算法围绕栈的 “后进先出” 特性展开:

  • 基础操作:通过指针移动实现元素的入栈、出栈等,时间复杂度均为 O (1)(无扩容时);
  • 扩展操作:扩容、复制等涉及元素复制,时间复杂度为 O (n),但保证了栈的灵活性;
  • 典型应用:进制转换利用栈的逆序特性,高效实现数制转换,体现了栈在 “逆序处理” 场景中的优势。

整体设计兼顾了功能性(完整操作集)、健壮性(异常处理、内存管理)和扩展性(可修改元素类型、扩容增量),是顺序栈实现的经典案例。

posted @ 2025-10-31 17:37  gccbuaa  阅读(47)  评论(0)    收藏  举报