C Datastructure 5 ---- stack

栈(stack)也是最基本的额数据结构之一,其实也就是特殊化的表,也就是插入和弹出元素都是在栈顶(相当于线性表的表尾)。

自从我们了解了链表这个东东以后,最大的好处就是在也不用提前用数组分配内存了,随用随取(malloc),不用就释放(free)。

所以,栈的实现也可以分为两种,不过还有一种比较少见的双栈(double stack),就是两个栈使用同一块内存区域,两个stack的
top在这个内存区域的两端,后面有详细的数据结构,看下便知。

  • stack(预先分配内存,使用数组)
  • link stack(使用链表思想实现)
  • double stack

stack github参考源码
首先是使用数组实现的普通stack

typedef int ElementType;

typedef struct
{
    ElementType data[MAX_SIZE]; 
    int top; 

}stStack;


void InitStack(stStack* stack);
BOOL IsFullStack(stStack* stack);
BOOL IsEmptyStack(stStack* stack);
BOOL Push(stStack* stack, ElementType elem);
BOOL Pop(stStack* stack, ElementType *elem);
int GetLength(stStack* stack);

比较简单,不贴具体实现了,需要详细了解的点击上面链接下载github源码。

下一个是link stack 的实现。
数据结构和接口。

typedef int ElementType;

typedef struct stStackNode
{
    ElementType data;
    struct stStackNode* next;
}stStackNode;

typedef struct
{
    stStackNode* top; 
    int length;
}stLinkStack;


void InitStack(stLinkStack* stack);
BOOL IsFullStack(stLinkStack* stack);
BOOL IsEmptyStack(stLinkStack* stack);
BOOL Push(stLinkStack* stack, ElementType elem);
BOOL Pop(stLinkStack* stack, ElementType *elem);
int GetLength(stLinkStack* stack);
void ClearStack(stLinkStack* stack);

看下push 和 pop

BOOL Push(stLinkStack* stack, ElementType elem)
{
    stStackNode* node = (stStackNode*)malloc(sizeof(stStackNode));
    node->next = stack->top;
    node->data = elem;

    stack->top = node;
    stack->length++;

    return TRUE;
}

BOOL Pop(stLinkStack* stack, ElementType *elem)
{
    stStackNode* delNode;

    if(IsEmptyStack(stack))
        return FALSE;

    delNode = stack->top;
    *elem = delNode->data;
    stack->top = delNode->next;


    free(delNode);
    stack->length--;

    return TRUE;
}

最后一个是双栈(double stack),比较简单。
数据结构和接口。

typedef int ElementType;

typedef struct
{
    ElementType data[MAX_SIZE]; 
    int top1;
    int top2; 

}stDoubleStack;


void InitStack(stDoubleStack* stack);
BOOL IsFullStack(stDoubleStack* stack);
BOOL IsEmptyStack(stDoubleStack* stack);
BOOL Push(stDoubleStack* stack,int stack_num, ElementType elem);
BOOL Pop(stDoubleStack* stack, int stack_num, ElementType *elem);
int GetLength(stDoubleStack* stack);

下面是具体实现

void InitStack(stDoubleStack* stack)
{
    stack->top1 = -1;
    stack->top2 = 1024;
}

BOOL IsFullStack(stDoubleStack* stack)
{
    return (stack->top1+1 == stack->top2);
}

BOOL IsEmptyStack(stDoubleStack* stack)
{
    return (stack->top1==-1 && stack->top2==1024);
}

BOOL Push(stDoubleStack* stack,int stack_num, ElementType elem)
{
    if(IsFullStack(stack))
        return FALSE;

    if(stack_num==1)
    {
        stack->data[++stack->top1] = elem;
        return TRUE;
    }
    else if(stack_num==2)
    {
        stack->data[--stack->top2] = elem;
        return TRUE;
    }
    else
        return FALSE;
}

BOOL Pop(stDoubleStack* stack, int stack_num, ElementType *elem)
{
    if(stack_num==1)
    {
        if(stack->top1==-1)
            return FALSE;

        *elem = stack->data[stack->top1--];
        return TRUE;
    }
    else if(stack_num==2)
    {
        if(stack->top2==1024)
            return FALSE;

        *elem = stack->data[stack->top2++];
        return TRUE;
    }
    else
        return FALSE;
}
int GetLength(stDoubleStack* stack)
{
    return stack->top1+1 + 1024-stack->top2;
}

【数据结构】求大佬帮忙看一下这个错误是怎么回事?(用栈实现带括号的多位数四则运算器)

11-28
# 题目原型: 四则运算器:实现多位整数的带括号的四则运算 # # 现存问题: # 程序中出现如图所示错误,麻烦大佬指点一下原因 # ![图片说明](https://img-ask.csdn.net/upload/201811/28/1543412646_396920.jpg) # ``` #include <stdio.h> #include <stdlib.h> #define TRUE 1 #define FALSE 0 #define Stack_Size 50 typedef char StackElementType; //运算符 typedef double StackElementType_num; //运算数 typedef struct { StackElementType elem[Stack_Size]; int top; }SeqStack; //运算符栈 typedef struct { StackElementType_num elem[Stack_Size]; int top; }SeqStack_num; //运算数栈 StackElementType_num ExpEvaluation(); void InitStack(SeqStack *S); int Push(SeqStack *S,StackElementType x); int Push_num(SeqStack *S,StackElementType_num x); int Pop(SeqStack *S,StackElementType *x); int Pop_num(SeqStack *S,StackElementType_num *x); int GetTop(SeqStack *S,StackElementType *x); int GetTop_num(SeqStack *S,StackElementType_num *x); StackElementType Compare(StackElementType ch1,StackElementType ch2); StackElementType Execute(StackElementType_num a,StackElementType op,StackElementType_num b); int main() { printf("%lf",ExpEvaluation()); return(0); } StackElementType_num ExpEvaluation() { char exp[100];//用字符数组将运算表达式存起来 int i=0,count=0; printf("Please input an expression (Ending with #:)"); exp[i]=getchar(); while(exp[i]!='#') { i++;count++; exp[i]=getchar(); } SeqStack OPTR; SeqStack_num OVS; StackElementType ch,op,x; StackElementType_num a,b,v; InitStack(&OPTR); InitStack_num(&OVS); Push(&OPTR,'#'); for(i=0;i<count;i++) { ch=exp[i]; while(ch!='#'||GetTop(&OPTR,&x)!='#') { if(ch>='0'&&ch<='9')//不是操作符,是操作数,进OVS栈 { int temp; temp=ch-'0';//先把当前操作数从字符变为数字 i++; ch=exp[i]; while(ch>='0'&&ch<='9')//继续判断下一位是否为操作数 { temp=temp*10+ch-'0'; i++; ch=exp[i]; } Push_num(&OVS,temp);//压栈 } else switch(Compare(ch,GetTop(&OPTR,&x))) { case '>':Push(&OPTR,ch); i++;ch=exp[i]; case '=':Pop(&OPTR,&op);i++;ch=exp[i];break;//脱括号 case '<':Pop(&OPTR,&op);//形成运算 Pop_num(&OVS,&b); Pop_num(&OVS,&a); v=Execute(a,op,b); Push_num(&OVS,v); break; } } } v=GetTop_num(&OVS,&x); return(v); } //初始化 void InitStack(SeqStack *S) { /*构造一个空栈S*/ S->top=-1; } void InitStack_num(SeqStack_num *S) { /*构造一个空栈S*/ S->top=-1; } //进栈 int Push(SeqStack *S,StackElementType x) { if(S->top==Stack_Size-1) return(FALSE); S->top++; S->elem[S->top]=x; return(TRUE); } int Push_num(SeqStack *S,StackElementType_num x) { if(S->top==Stack_Size-1) return(FALSE); S->top++; S->elem[S->top]=x; return(TRUE); } //出栈 int Pop(SeqStack *S,StackElementType *x) { if(S->top==-1) return(FALSE); *x=S->elem[S->top]; S->top--; return(TRUE); } int Pop_num(SeqStack *S,StackElementType_num *x) { if(S->top==-1) return(FALSE); *x=S->elem[S->top]; S->top--; return(TRUE); } //读栈顶 int GetTop(SeqStack *S,StackElementType *x) { if(S->top==-1) return(FALSE); else { *x=S->elem[S->top]; return(TRUE); } } int GetTop_num(SeqStack *S,StackElementType_num *x) { if(S->top==-1) return(FALSE); else { *x=S->elem[S->top]; return(TRUE); } } //比较优先级,返回'>','<','=' StackElementType Compare(StackElementType ch1,StackElementType ch2) //ch1为还未进栈的运算符,ch2为当前运算符栈顶元素 { //'('未入栈时,优先级最高,入栈后,优先级最低 int m,n; switch(ch1) { case '(':m=6;break; case '*': case '/':m=5;break; case '+': case '-':m=4;break; case ')':m=3;break; } switch(ch2) { case '*': case '/':n=6;break; case '+': case '-':n=5;break; case ')':n=4;break; case '(':n=3;break; } if(ch1>ch2) return('>'); else if(ch1=ch2) return('='); else return('<'); } StackElementType_num Execute(StackElementType_num a,StackElementType op,StackElementType_num b) { StackElementType_num v; switch(op) { case '+':v=a+b;break; case '-':v=a-b;break; case '*':v=a*b;break; case '/':v=a/b;break; } return(v); } ```
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值