栈的基本操作
一、	实验目的
1.掌握栈的思想及其存储实现。
2.掌握栈的常见算法的程序实现。
二、	 实验内容及要求
目的要求:
1.掌握栈的思想及其存储实现。
2.掌握栈的常见算法的程序实现。
实验内容:
(1)	采用顺序存储实现栈的初始化、入栈、出栈操作。
(2)	采用链式存储实现栈的初始化、入栈、出栈操作。
(3)	在主函数中设计一个简单的菜单,分别测试上述算法。
(4)	* 综合训练:
1)	堆栈操作合法性:假设以S和X分别表示入栈和出栈操作。如果根据一个仅由S和X构成的序列,对一个空堆栈进行操作,相应操作均可行(如没有出现删除时栈空)且最后状态也是栈空,则称该序列是合法的堆栈操作序列。请编写程序,输入S和X序列,判断该序列是否合法。
2)	括号匹配检验:假设表达式中允许包括两种括号:圆括号和方括号,其嵌套的顺序随意,即()或[([][])]等为正确的格式,[(])或([())等均为不正确格式。输入一个表达式,判断其中的括号是否能正确匹配。
3)	表达式转换:算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。输入在一行中给出不含空格的中缀表达式,可包含+、-、*、\以及左右括号(),表达式不超过20个字符。在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
4)	数制的转换。即利用栈的基本操作完成十进制到8进制,16进制的转换。
Stack.h
#ifndef DACM_ZSN_STACK_H
#define DACM_ZSN_STACK_H
#define MaxSize 100 //栈的最大值
typedef int ElemType;
typedef struct {   //ElemType *base;
    //ElemType *top;
    ElemType data[MaxSize];
    int top;
} SqStack;
void InitStack(SqStack &sqStack);
bool Push(SqStack &sqStack, ElemType x);
bool Pop(SqStack &sqStack, ElemType &x);
//-----------------------
typedef struct StackNode {
    ElemType data;
    struct StackNode *next;
} StackNode;
typedef struct LinkStack {
    StackNode *top;
    int count;
} LinkStack;
LinkStack *InitLinkStack(LinkStack *s);
bool Push(LinkStack *s,ElemType e);
bool Pop(LinkStack *s,ElemType *e);
#endif //DACM_ZSN_STACK_H
Stack.cpp
#include<stdio.h>
#include"Stack.h"
#include<stdlib.h>
//栈的顺序存储结构
void InitStack(SqStack &sqStack) {
    sqStack.top = -1;
}
bool Push(SqStack &sqStack, ElemType x) {
    if (sqStack.top = MaxSize - 1)
        return false;
    sqStack.data[++sqStack.top] = x;
    return true;
}
bool Pop(SqStack &sqStack, ElemType x) {
    if (sqStack.top = -1)
        return false;
    x = sqStack.data[sqStack.top--];
    return true;
}
//栈的链式存储结构
LinkStack *InitLinkStack(LinkStack *s) {
    s = new LinkStack;
    s->top = NULL;
    s->count = 0;
    return s;
}
//入栈
bool Push(LinkStack *s, ElemType e) {
    StackNode *sn;
    sn = (StackNode *) malloc(sizeof(StackNode));//申请一个结点空间,定义并初始化指向该结点的指针sn
    sn->data = e;//把入栈的元素赋值给新结点的data
    sn->next = s->top;//把新结点的next指向上一个结点
    s->top = sn;//把top指针指向新结点,栈顶元素是新入栈的元素
    s->count++;//栈的元素个数加1
    return true;//返回入栈成功
}
//出栈
bool Pop(LinkStack *s, ElemType *e) {
    StackNode *p;//定义一个临时结点指针
    if (s->top == NULL)
        return false;//如果是空栈,直接返回出栈失败
    p = s->top;//把栈顶指针赋值给临时指针p
    *e = p->data;//把栈顶元素赋值给e指向的变量,即主调函数中需要被修改的变量
    if (p->next == NULL)//如果出栈的是最后一个元素
        s->top = NULL;//该元素出栈后,栈为空
    else
        s->top = s->top->next;//否则top指向出栈结点的下一个结点
    //这个if else也可以直接写成s->top=s->top->next;因为如果出栈的是最后一个元素,top->next本来就等于NULL
    free(p);//释放临时指针p指向的空间
    s->count--;//栈的元素减1
    return true;//返回出栈成功
}
void menu() {
    printf("1、栈的顺序存储\n");
    printf("2、栈的链式存储\n");
}
int main() {
//  顺序
//    SqStack Sq;
//    ElemType m;
//    InitStack(Sq);
//    Push(Sq, 3);
//    Push(Sq, 4);
//    Push(Sq, 5);
//  链式
//    LinkStack *Sl = NULL;
//    Sl = InitLinkStack(Sl);
//    Push(Sl, 0);
//    Push(Sl, 9);
//    Push(Sl, 8);
//    int a = 8;
//    int *p = &a;
//    Pop(Sl, p);
    int choice;
    int *pInt = &choice;
    SqStack Sq;
    ElemType m;
    LinkStack *Sl = NULL;
    Sl = InitLinkStack(Sl);
//    while (true) {
    menu();
    printf("选择您的操作:\n");
    scanf("%d", pInt);
    switch (choice) {
        case 1:
            InitStack(Sq);
            Push(Sq, 3);
            Push(Sq, 4);
            Push(Sq, 5);
            Pop(Sq, 3);
            break;
        case 2:
            Push(Sl, 0);
            Push(Sl, 9);
            Push(Sl, 8);
            int a = 8;
            int *p = &a;
            Pop(Sl, p);
            break;
    }
//    }
}
进制转换
#include <cstdio>
#include <cstdlib>
typedef struct Node {
    int data;
    struct Node *next;
} *PNode;
typedef struct Node *top, *LinkStack;//栈顶和链栈类型
LinkStack SetNullStack_Link()//创建空链栈
{
    LinkStack top = (LinkStack) malloc(sizeof(struct Node));
    if (top != NULL)//判断节点是否创建成功
    {
        top->next = NULL;//必须指定头节点为NULL,之后要用头插法插入节点
    } else {
        printf("alloc failure");//创建头节点失败
    }
    return top;
}
void Push_Link(LinkStack top, int x)//进栈,不需要判断链栈是否会溢出
{
    PNode p = (PNode) malloc(sizeof(struct Node));//申请节点空间
    if (p == NULL) {
        printf("alloc failure");
    } else//相当于链表头插法
    {
        p->data = x;//数据域赋值
        p->next = top->next;//指针域赋值
        top->next = p;//修改栈顶
    }
}
int IsNullStack_Link(LinkStack top)//判断栈是否为空
{
    if (top->next == NULL)
        return 1;//空栈
    return 0;
}
void Pop_Link(LinkStack top)//删除栈顶元素,需要判空
{
    PNode p;
    if (top->next == NULL)//判断栈是否为空
        printf("it is empty stack!");
    else {
        p = top->next;//p指向待删除的节点
        top->next = p->next;//修改栈顶指针
        free(p);//删除释放节点的空间
    }
}
int Pop_Link_Return(LinkStack top)//取栈顶元素
{
    if (IsNullStack_Link(top) == 1)//判断栈是否为空
        printf("it is empty stack!");
    else
        return top->next->data;//返回头节点后的第一个节点数据
}
void OctConversion(LinkStack sstack, int n)//实现把八进制的转换
{
    int temp;
    while (n != 0)//n是要被转换的十进制数
    {
        Push_Link(sstack, n % 8);//将余数压入栈中
        n = n / 8;//下一次循环商当作被除数
    }
    printf("Convert To Octal Result:");
    while (IsNullStack_Link(sstack) != 1)//链栈为空时停止循环
    {
        temp = Pop_Link_Return(sstack);
        printf("%d", temp);
        Pop_Link(sstack);//弹出栈顶元素
    }
}
void HexConversion(LinkStack sstack, int n)//转换为十六进制
{
    int temp;
    while (n != 0)//n是要被转换的十进制数
    {
        temp = n % 16;
        switch (temp)//当temp>=10时要进行特殊处理
        {
            case 10:
                temp = 'A';
                break;
            case 11:
                temp = 'B';
                break;
            case 12:
                temp = 'C';
                break;
            case 13:
                temp = 'D';
                break;
            case 14:
                temp = 'E';
                break;
            case 15:
                temp = 'F';
                break;
        }
        Push_Link(sstack, temp);//将元素压入栈中
        n = n / 16;
    }
    printf("Convert To Hexadecimal Result:");
    while (IsNullStack_Link(sstack) != 1) {
        temp = Pop_Link_Return(sstack);//遵循后进先出的原则
        if (temp < 10)
            printf("%d", temp);
        else
            printf("%c", temp);
        Pop_Link(sstack);
    }
}
int main() {
    int n, m;
    LinkStack stack;
    stack = SetNullStack_Link();
    printf("input which number you want to convert to octal:");
    scanf("%d", &n);
    OctConversion(stack, n);
    printf("\n");
    printf("input which number you want to convert to hexadecimal:");
    scanf("%d", &m);
    HexConversion(stack, m);
    printf("\n");
    return 0;
}
    生命依靠吸收负熵,避免了趋向平衡的衰退

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号