栈的顺序存储实现

typedef int Position;
struct SNode {
    ElementType *Data; /* 存储元素的数组 */
    Position Top;      /* 栈顶指针 */
    int MaxSize;       /* 堆栈最大容量 */
};
typedef struct SNode *Stack;
 
Stack CreateStack( int MaxSize )
{
    Stack S = (Stack)malloc(sizeof(struct SNode));
    S->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
    S->Top = -1;
    S->MaxSize = MaxSize;
    return S;
}
 
bool IsFull( Stack S )
{
    return (S->Top == S->MaxSize-1);
}
 
bool Push( Stack S, ElementType X )
{
    if ( IsFull(S) ) {
        printf("堆栈满");
        return false;
    }
    else {
        S->Data[++(S->Top)] = X;
        return true;
    }
}
 
bool IsEmpty( Stack S )
{
    return (S->Top == -1);
}
 
ElementType Pop( Stack S )
{
    if ( IsEmpty(S) ) {
        printf("堆栈空");
        return ERROR; /* ERROR是ElementType的特殊值,标志错误 */
    }
    else 
        return ( S->Data[(S->Top)--] );
}

栈的链式存储实现

typedef struct SNode *PtrToSNode;
struct SNode {
    ElementType Data;
    PtrToSNode Next;
};
typedef PtrToSNode Stack;
 
Stack CreateStack( ) 
{ /* 构建一个堆栈的头结点,返回该结点指针 */
    Stack S;
 
    S = (Stack)malloc(sizeof(struct SNode));
    S->Next = NULL;
    return S;
}
 
bool IsEmpty ( Stack S )
{ /* 判断堆栈S是否为空,若是返回true;否则返回false */
    return ( S->Next == NULL );
}
 
bool Push( Stack S, ElementType X )
{ /* 将元素X压入堆栈S */
    PtrToSNode TmpCell;
 
    TmpCell = (PtrToSNode)malloc(sizeof(struct SNode));
    TmpCell->Data = X;
    TmpCell->Next = S->Next;
    S->Next = TmpCell;
    return true;
}
 
ElementType Pop( Stack S )  
{ /* 删除并返回堆栈S的栈顶元素 */
    PtrToSNode FirstCell;
    ElementType TopElem;
 
    if( IsEmpty(S) ) {
        printf("堆栈空"); 
        return ERROR;
    }
    else {
        FirstCell = S->Next; 
        TopElem = FirstCell->Data; //TopElem是为了同时实现free()和return
        S->Next = FirstCell->Next;
        free(FirstCell);
        return TopElem;
    }
}

在一个数组中实现两个堆栈

本题要求在一个数组中实现两个堆栈。

函数接口定义:

Stack CreateStack( int MaxSize );
bool Push( Stack S, ElementType X, int Tag );
ElementType Pop( Stack S, int Tag );

其中Tag是堆栈编号,取1或2;MaxSize堆栈数组的规模;Stack结构定义如下:

typedef int Position;
struct SNode {
    ElementType *Data;
    Position Top1, Top2;
    int MaxSize;
};
typedef struct SNode *Stack;

注意:如果堆栈已满,Push函数必须输出“Stack Full”并且返回false;如果某堆栈是空的,则Pop函数必须输出“Stack Tag Empty”(其中Tag是该堆栈的编号),并且返回ERROR。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

#define ERROR 1e8
typedef int ElementType;
typedef enum { push, pop, end } Operation;
typedef enum { false, true } bool;
typedef int Position;
struct SNode {
    ElementType *Data;
    Position Top1, Top2;
    int MaxSize;
};
typedef struct SNode *Stack;

Stack CreateStack( int MaxSize );
bool Push( Stack S, ElementType X, int Tag );
ElementType Pop( Stack S, int Tag );

Operation GetOp();  /* details omitted */
void PrintStack( Stack S, int Tag ); /* details omitted */

int main()
{
    int N, Tag, X;
    Stack S;
    int done = 0;

    scanf("%d", &N);
    S = CreateStack(N);
    while ( !done ) {
        switch( GetOp() ) {
        case push: 
            scanf("%d %d", &Tag, &X);
            if (!Push(S, X, Tag)) printf("Stack %d is Full!\n", Tag);
            break;
        case pop:
            scanf("%d", &Tag);
            X = Pop(S, Tag);
            if ( X==ERROR ) printf("Stack %d is Empty!\n", Tag);
            break;
        case end:
            PrintStack(S, 1);
            PrintStack(S, 2);
            done = 1;
            break;
        }
    }
    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

5
Push 1 1
Pop 2
Push 2 11
Push 1 2
Push 2 12
Pop 1
Push 2 13
Push 2 14
Push 1 3
Pop 2
End

输出样例:

Stack 2 Empty
Stack 2 is Empty!
Stack Full
Stack 1 is Full!
Pop from Stack 1: 1
Pop from Stack 2: 13 12 11

Codes:

Stack CreateStack( int MaxSize )
{
    Stack S;
    S = (Stack) malloc(sizeof(struct SNode));
    S->Data = (ElementType*) malloc(sizeof( ElementType ) * MaxSize ); // **申请分配内存**
    S->MaxSize = MaxSize;
    S->Top1 = -1;
    S->Top2 = MaxSize;
    return S;
}

bool Push( Stack S, ElementType X, int Tag )
{
    if( S->Top1 == S->Top2 -1)
    {
        printf("Stack Full\n");
        return false;
    }
    else if ( Tag == 1 )
    {
        S->Data[++S->Top1] = X;
        return true;
    }
    else
    {
        S->Data[--S->Top2] = X;
        return true;
    }
}
ElementType Pop( Stack S, int Tag )
{
    if ((Tag == 1 && S->Top1 == -1) || (Tag == 2 && S->Top2 == S->MaxSize))
    {
        printf("Stack %d Empty\n", Tag);
        return ERROR;
    }
    else if(Tag == 1)
        return S->Data[S->Top1--];
    else
        return S->Data[S->Top2++];
}

Pop Sequence

Given a stack which can keep M M M numbers at most. Push N N N numbers in the order of 1, 2, 3, …, N N N and pop randomly. You are supposed to tell if a given sequence of numbers is a possible pop sequence of the stack. For example, if M M M is 5 and N N N is 7, we can obtain 1, 2, 3, 4, 5, 6, 7 from the stack, but not 3, 2, 1, 7, 5, 6, 4.

Input Specification:

Each input file contains one test case. For each case, the first line contains 3 numbers (all no more than 1000): M M M (the maximum capacity of the stack), N N N (the length of push sequence), and K K K (the number of pop sequences to be checked). Then K K K lines follow, each contains a pop sequence of N N N numbers. All the numbers in a line are separated by a space.

Output Specification:

For each pop sequence, print in one line “YES” if it is indeed a possible pop sequence of the stack, or “NO” if not.

Sample Input:

5 7 5
1 2 3 4 5 6 7
3 2 1 7 5 6 4
7 6 5 4 3 2 1
5 6 4 3 7 2 1
1 7 6 5 4 3 2

Sample Output:

YES
NO
NO
YES
NO

Codes:

#include <stdio.h>
#include <stdlib.h>

typedef struct SNode* PtrToNode;
typedef PtrToNode Stack;
typedef int ElementType;

struct SNode{
    int Capacity;
    int TopOfStack;
    ElementType *Array;
};

int Judge_Pop_Sequence(Stack S, int N);
int Push(Stack S, ElementType X);
Stack CreateStack(int Maxsize);

int main(void)
{
    int Maxsize, N, K;
    int i;
    Stack S;
    scanf("%d %d %d", &Maxsize, &N, &K);
    
    for (i=0;i<K;i++)
    {
        S = CreateStack(Maxsize);
        if( Judge_Pop_Sequence(S, N))
            printf("YES\n");
        else
            printf("NO\n");
    }
}

Stack CreateStack(int Maxsize)
{
    Stack S;
    S = (Stack) malloc(sizeof(struct SNode));
    S->Array = (ElementType*) malloc(sizeof(ElementType) * Maxsize);
    S->Capacity = Maxsize;
    S->TopOfStack = -1;
    return S;
}

int Push(Stack S, ElementType X)
{
    if(S->TopOfStack == S->Capacity - 1)
        return 0;
    else
    {
        S->Array[ ++S->TopOfStack ] = X;
        return 1;
    }
}

ElementType Pop_Top(Stack S)
{
    if (S->TopOfStack == -1)
        return 0;
    else
        return S->Array[ S->TopOfStack--];
}

int Judge_Pop_Sequence(Stack S,int N)
{
    ElementType num = 1;
    int i, j;
    ElementType a[N];
    for (i=0;i<N;i++)
        scanf("%d", &a[i]);
    j = 0;
    i = 0;
    while (j < N)
    {
        if ( S->TopOfStack == -1)
            Push(S,num++);
        if ( S->Array[S->TopOfStack] > a[i] ) break;
        while (S->Array[S->TopOfStack] < a[i] && S->TopOfStack < S->Capacity-1)
            Push(S, num++);
        if ( S->Array[S->TopOfStack] < a[i] ) break;
        if ( S->Array[S->TopOfStack] == a[i] )
        {
            Pop_Top(S);
            i++;
            j++;
        }
    }
    if (j == N) return 1;
    else return 0;
}

几个自己写的时候卡壳的地方:

  • K次循环,S每次都需要重新Create,故CreateStack(Maxsize)函数应该放在循环里面
   for (i=0;i<K;i++)
   {
       S = CreateStack(Maxsize);
       if( Judge_Pop_Sequence(S, N))
           printf("YES\n");
       else
           printf("NO\n");
   }
  • int Judge_Pop_Sequence(Stack S,int N) 函数中for循环后i有值,在进入while循环时应该重新赋值I=0
    for (i=0;i<N;i++)
        scanf("%d", &a[i]);
    j = 0;
    i = 0;
  • int Judge_Pop_Sequence(Stack S,int N)函数中while循环条件的选择: 由于打印"YES"需要成功比较N次,故以比较次数为循环条件,判断条件有:
  1. 是否为空栈(是则Push());
  2. 如果栈顶的元素大于输入元素,则直接break;
  3. 如果栈顶的元素小于输入元素,则Push(),但存在栈是否满的问题,故里面的while()循环增加一个判断栈是否满的条件(否则会进入死循环,尽管在写Push()函数的时候考虑到了栈满会return 0)再判断在至多栈满的情况下是否能够达到栈顶元素等于输入元素,若是则Pop(),更新i,j并进入下一次循环。否则break。
   while (j < N)
    {
        if ( S->TopOfStack == -1)
            Push(S,num++);
        if ( S->Array[S->TopOfStack] > a[i] ) break;
        while (S->Array[S->TopOfStack] < a[i] && S->TopOfStack < S->Capacity-1)
            Push(S, num++);
        if ( S->Array[S->TopOfStack] < a[i] ) break;
        if ( S->Array[S->TopOfStack] == a[i] )
        {
            Pop_Top(S);
            i++;
            j++;
        }
    }

Evaluate Postfix Expression

Write a program to evaluate a postfix expression. You only have to handle four kinds of operators: +, -, x, and /.

Format of functions:

ElementType EvalPostfix( char *expr );

where expr points to a string that stores the postfix expression. It is guaranteed that there is exactly one space between any two operators or operands. The function EvalPostfix is supposed to return the value of the expression. If it is not a legal postfix expression, EvalPostfix must return a special value Infinity which is defined by the judge program.

Sample program of judge:


#include <stdio.h>
#include <stdlib.h>

typedef double ElementType;
#define Infinity 1e8
#define Max_Expr 30   /* max size of expression */

ElementType EvalPostfix( char *expr );

int main()
{
    ElementType v;
    char expr[Max_Expr];
    gets(expr);
    v = EvalPostfix( expr );
    if ( v < Infinity )
        printf("%f\n", v);
    else
        printf("ERROR\n");
    return 0;
}

/* Your function will be put here */

Sample Input 1:

11 -2 5.5 * + 23 7 / -

Sample Output 1:

-3.285714

Sample Input 2:

11 -2 5.5 * + 23 0 / -

Sample Output 2:

ERROR

Sample Input 3:

11 -2 5.5 * + 23 7 / - *

Sample Output 3:

ERROR
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]提供了一个朴素的解法,使用两个来存储字符串,一个用来存储普通字符,另一个用来存储特殊字符。遍历字符串,如果是普通字符则压入第一个,如果是特殊字符则弹出第一个顶元素。最后比较两个是否相同即可判断字符串是否有效。这个解法的时间复杂度是O(M + N),空间复杂度也是O(M + N)。\[1\] 引用\[2\]提供了另一个的应用场景,即判断括号是否有效。遍历字符串,如果是左括号则压入,如果是右括号则判断和顶元素是否匹配,不匹配则返回false,匹配则弹出顶元素。最后判断是否为空即可判断括号是否有效。\[2\] 引用\[3\]也提供了一个判断括号是否有效的解法,使用来操作。遍历字符串,如果是左括号则压入,如果是右括号则判断和顶元素是否匹配,不匹配则返回false,匹配则弹出顶元素。最后判断是否为空即可判断括号是否有效。这个解法使用了HashMap来存储括号的对应关系。\[3\] 综上所述,在解决字符串相关问题中有着广泛的应用,包括判断字符串是否有效、逆波兰表达式等。在解决这些问题时,可以帮助我们保存和处理字符的顺序,从而简化问题的处理过程。 #### 引用[.reference_title] - *1* *3* [Leetcode刷题03-](https://blog.csdn.net/weixin_47802917/article/details/123007699)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v4^insert_chatgpt"}} ] [.reference_item] - *2* [leetCode-类型详解](https://blog.csdn.net/zhiyikeji/article/details/125508011)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v4^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值