数据结构与算法分析(c语言)--栈

参考《数据结构与算法分析-c语言描述》一书。

1、栈模型

栈(stack)是限制插入和删除只能在一个位置上进行的表,该位置是表的末端,叫做栈顶。对栈的基本操作有Push(进栈)和pop(出栈),前者相当于插入,后者则是删除最后插入的元素。


数据结构与算法分析(c语言)--栈_第1张图片
栈模型

2、栈的链表实现

这里我们实现的栈的链表有一个头指针,栈的定义如下:

#include 
#include 


typedef struct Node * Stack;

struct Node
{
    int val;
    Stack next;
};

判断是否是空栈:

int isEmpty(Stack s)
{
    return s -> next == NULL;
}

得到栈顶元素:

int get_top(Stack s)
{
    if (!isEmpty(s))
    {
        return s -> next -> val;
    }
    else
    {
        printf("Empty stack");
        return 0;
    }
}

push入栈:

void push(Stack s,int val)
{
    Stack tmp = (Stack)malloc(sizeof(struct Node));
    if (tmp == NULL)
    {
        printf ("out of space");
        return;
    }
    tmp -> val = val;
    tmp -> next = s -> next;
    s -> next = tmp;
}

pop出栈:

void Pop(Stack s)
{
    if (isEmpty(s))
    {
        printf("Empty Stack");
    }
    else
    {
        Stack p = s -> next;
        s -> next = p -> next;
        free(p);
    }
}

可以看到,上述的栈的操作都是常数级时间,这些例程中没有任何地方涉及到栈的大小,更不用说依赖于栈大小的循环了。这种实现方法的缺点在于malloc和free调用的开销是昂贵的。

3、栈的数组实现

另一种栈的实现方法使用了数组,唯一潜在的危害是我们需要提前声明一个数组的大小。
栈的定义如下:

#include 
#include 

typedef struct StackRecord * Stack;

#define EmptyTOS -1

struct StackRecord{
    int Capacity;
    int TopOfStack;
    int * Array;
};

栈的创建:

Stack createStack(int maxElements)
{
    Stack s = (Stack)malloc(sizeof(struct StackRecord));
    if (s==NULL)
    {
        printf("out of space");
        return NULL;
    }
    int size = maxElements * sizeof(int);
    s -> Array = (int *)malloc(size);
    if (s->Array == NULL)
    {
        printf("out of space");
        return NULL;
    }
    s->Capacity = maxElements;
    s->TopOfStack = EmptyTOS;
    return s;
}

判断是否是空栈:

int IsEmpty(Stack s)
{
    return s->TopOfStack == EmptyTOS;
}

判断是否栈是满栈:

int isFull(Stack s)
{
    return s->TopOfStack >= s->Capacity;
}

得到栈顶元素:

int get_top(Stack s)
{
    if (!IsEmpty(s))
        return s->Array[s->TopOfStack];
    printf("empty stack");
    return 0;
}

push入栈:

void Push(Stack s,int val)
{
    if(isFull(s))
        printf("Full stack");
    else
        s->Array[++s->TopOfStack] = val;
}

pop出栈:

void pop(Stack s)
{
    if(!IsEmpty(s))
        s->TopOfStack--;
    else
        printf("Empty stack");
}

4、栈的应用

1、平衡符号,即判断前后的括号是否对应:做一个空栈,读入字符直到文件尾,如果字符是一个开放符号,则将其推入栈中,如果字符是一个封闭符号,弹出栈顶元素,如果栈顶元素是对应的开放字符,继续。如果栈为空或者弹出的不是对应的开放字符,报错。
2、后缀表达式
比如公式4.99 * 1.06 + 5.99 +6.99 * 1.06的值,我们采用后缀记法,按照顺序写作:
4.99 1.06 * 5.99 + 6.99 1.06 * +
首先4.99和1.06进栈,遇到,则4.99和1.06出栈,计算结果A1进栈,随后5.99进栈,遇到+,则A1和5.99出栈,求和之后A1进栈,随后6.99和1.06进栈,遇到号二者出栈并计算结果A2进栈,遇到最后的+号,A1和A2出栈求和得到最后的结果。
3、

如果你喜欢我写的文章,可以帮忙给小编点个赞或者加个关注,我一定会互粉的!
如果大家对数据结构感兴趣,欢迎跟小编进行交流,小编微信为sxw2251,加我要写好备注哟!:


数据结构与算法分析(c语言)--栈_第2张图片
我的微信

你可能感兴趣的:(数据结构与算法分析(c语言)--栈)