数据结构——栈

定义


限定仅在表尾进行插入和删除操作的线性表。(先入后出)

顺序结构


C定义

#define MAXSIZE 20

#pragma mark 顺序栈

typedef int SElemType;
typedef struct {
    SElemType data[MAXSIZE];
    int top;
}SqStack;

压栈操作

int Push(SqStack *S, SElemType e)
{
    if (S->top == MAXSIZE -1)
        return 0;
    S->data[++S->top] = e;
    return 1;
}

弹栈操作

int Pop(SqStack *S, SElemType *e)
{
    if (S->top == -1)
        return 0;
    *e = S->data[S->top--];
    return 1;
}


共享栈


共享栈可以看做是两个顺序栈倒下,栈尾相对的数据结构。通常在两个栈空间需求有相反关系时使用,例如买入就要卖出等等。

C定义

typedef struct {
    SElemType data[MAXSIZE];
    int top1;
    int top2;
}SqDoubleStack;

压栈

int PushDouble(SqDoubleStack *S, SElemType e, int stackNumber)
{
    //栈满
    if (S->top1 + 1 == S->top2)
        return 0;
    if (stackNumber == 1)
        S->data[++S->top1] = e;
    else if (stackNumber == 2)
        S->data[--S->top2] = e;
    return 1;
}

弹栈

int PopDouble(SqDoubleStack *S, SElemType *e, int stackNumber)
{
    if (stackNumber == 1)
        if (S->top1 == -1) 
            return 0;
        *e = S->data[S->top1--];
    if (stackNumber == 2)
        if (S->top2 == MAXSIZE) 
            return 0;
        *e = S->data[S->top2++];
    return 1;
}


链栈


栈的链式存储结构类似于线性表中的链式存储结构。

C定义

typedef struct StackNode{
    SElemType data;
    struct StackNode *next;
}StackNode, *LinkStackPtr;

typedef struct LinkStack{
    LinkStackPtr top;
    int count;
}LinkStack;

压栈

int PushLink(LinkStack *S,SElemType e)
{
    LinkStackPtr p = (LinkStackPtr)malloc(sizeof(StackNode));
    p->data = e;
    p->next = S->top;
    S->top = p;
    S->count++;
    return 1;
}

弹栈

int PopLink(LinkStack *S,SElemType *e)
{
    LinkStackPtr p;
    *e = S->top->data;
    p = S->top;
    S->top = S->top->next;
    free(p);
    S->count--;
    return 1;
}

对比顺序栈和链栈


两个数据结构操作都不复杂,时间复杂度相同为O(1)。
顺序栈需要固定的长度,但是存取时定位方便。
链栈要求有指针域,因此需要增加一些内存开销,但不同于顺序栈限制长度。

栈的应用 —— 递归

例如比较有名的斐波那契数列:
int Fbi(int i)
{
    if (i < 2)
        return i == 0? 0: 1;
    return Fbi(i - 1) + Fbi(i - 2);
}


原文地址:https://www.cnblogs.com/jiangu66/p/3209200.html