栈的介绍

来源:互联网 发布:java.ext.dirs 编辑:程序博客网 时间:2024/06/07 02:17



栈和线性表很相似,不仅有顺序存储表示也有链式存储表示,而且其创建删除都一样。只是栈的操作方面有如下的特点:

(01) 栈中数据是按照"后进先出(LIFO, Last In First Out)"方式进出栈的。
(02) 向栈中添加/删除数据时,只能从栈顶进行操作。

栈通常包括的三种操作:pushpeekpop
push -- 向栈中添加元素。
peek -- 返回栈顶元素。
pop  -- 返回并删除栈顶元素的操作。


一:顺序存储表示

栈的示意图


1:栈的顺序存储结构表示:

#define STACKINITSIZE 100#define STACKINCREMENT 10typedef struct{    SElemType *base;    SElemType *top;    int stacksize;}SqStack;

这里需要注意的一点是:顺序存储只需要创建依次结构体,而这个结构体里面的指针不是指向该类型的结构体的(与链表不同),而是只想SElemType类型的数组的!创建的一个数组的信息,全在这个结构体里面表示。


2:栈的初始化

Stack stack_init(SqStack *S){    S->base = (SElemType *)malloc(STACKINITSIZE * sizeof(SElemType));    if(!(S->base))        exit(-1);    S->top = S->base;    S->stacksize = STACKINITSIZE;    return 1;}

3:取得栈顶元素

由于栈顶指针top指向栈顶元素的下一个位置,因此取元素、插入元素以及删除元素都要留意数组索引的变化。同时还要判断栈是否为空,或者是否已满,然后再进行操作。

Status get_top(SqStack S,SElemType *e){    if(S->top == S->base)        return 0;    *e = *(S->top - 1);    return 1;}

4:插入元素

Status push(SqStack *S,SElemType e){    //判断元素空间十分充足    if(S->top - S->base >= S->stacksize){        S->base = (SElemType *)realloc(S->base,                         (S->stacksize + STACKINCREMENT)*sizeof(SElemType));        if(!(s->base))            exit(-1);        S->top = S->base + S->stacksize;        S->stacksize += STACKINCREMENT;    }    *(S->top) = e;    S->top++;    return 1;}

5:删除元素

Status pop(SqStack *S,SElemType *e){    if(S->top == S->base)        return 0;    *e = *(--S->top);    return 1;}


评注:

栈、队列等其实就是一种工具,看你如何去用,如何去实现。这方式就有很多了。比如也可以用下面的方式来声明一个栈

#define MAXSIZE 200struct seqstack{       Elemtype data[MAXSIZE];       int top;};struct seqstack *s;  //定义一个指向顺序栈的指针


二:链式存储表示

当我们建立链表的时候,可以再表头插入结点也可以在表尾插入结点。那么在实现栈的时候,我们选择在表头插入结点,就能很好的实现我们想要的操作。但是,这里不需要头结点,只需要一个头指针就可以了。

1:单链表的结点

// 单向链表的“节点”struct node {    int val;    struct node* next;};// 单向链表的“表头”static struct node *phead=NULL;

2:创建结点(这里不用初始化,单链表时有表头,需要初始化)

// 创建节点,val为节点值static struct node* create_node(int val) {    struct node *pnode=NULL;    pnode = (struct node*)malloc(sizeof(struct node));    if (!pnode)        return NULL;    pnode->val = val;    pnode->next = NULL;        return pnode;}

3:插入和删除的实现

// 将val插入到链表的表头位置static struct node* push(int val) {    struct node *pnode = NULL;        pnode = create_node(val);    pnode->next = phead;    phead = pnode;        return phead;}// 删除链表的表头static int pop() {    if (!phead)    {        printf("remove failed! link is empty!");        return -1;    }        int ret;    struct node *pnode;    ret = phead->val;    pnode = phead;    phead = phead->next;    free(pnode);    return ret;}


栈的链式存储实现代码

#include <stdio.h>#include <malloc.h>/** * C 语言: 单向链表实现的栈,只能存储int数据。 * * @author skywang * @date 2013/11/07 */// 单向链表的“节点”struct node {    int val;    struct node* next;};// 单向链表的“表头”static struct node *phead=NULL;// 创建节点,val为节点值static struct node* create_node(int val) {    struct node *pnode=NULL;    pnode = (struct node*)malloc(sizeof(struct node));    if (!pnode)        return NULL;    pnode->val = val;    pnode->next = NULL;        return pnode;}// 销毁单向链表static int destroy_single_link() {    struct node *pnode=NULL;    while (phead != NULL) {        pnode = phead;        phead = phead->next;        free(pnode);    }    return 0;}// 将val插入到链表的表头位置static struct node* push(int val) {    struct node *pnode = NULL;        pnode = create_node(val);    pnode->next = phead;    phead = pnode;        return phead;}// 删除链表的表头static int pop() {    if (!phead)    {        printf("remove failed! link is empty!");        return -1;    }        int ret;    struct node *pnode;    ret = phead->val;    pnode = phead;    phead = phead->next;    free(pnode);    return ret;}// 返回链表的表头节点的值static int peek() {    if (!phead)    {        printf("peek failed! link is empty!");        return -1;    }    return phead->val;}// 返回链表中节点的个数static int size() {    int count=0;    struct node *pnode=phead;    while (pnode != NULL) {        pnode = pnode->next;        count++;    }    return count;}// 链表是否为空static int is_empty() {    return phead==NULL;}// 打印“栈”static void print_single_link(){    if (is_empty())     {        printf("stack is Empty\n");        return 0;    }    printf("stack size()=%d\n", size());    struct node *pnode=NULL;    while (phead != NULL) {        printf("%d\n", phead->val);        pnode = phead;        phead = phead->next;        free(pnode);    }}void main() {    int tmp=0;    // 将10, 20, 30 依次推入栈中    push(10);    push(20);    push(30);    //print_single_link();    // 打印栈    // 将“栈顶元素”赋值给tmp,并删除“栈顶元素”    tmp = pop();    printf("tmp=%d\n", tmp);    //print_single_link();    // 打印栈    // 只将“栈顶”赋值给tmp,不删除该元素.    tmp = peek();    printf("tmp=%d\n", tmp);    //print_single_link();    // 打印栈    push(40);    print_single_link();    // 打印栈    // 销毁栈    destroy_single_link();}



三:双向链表实现的栈,能存储任意类型的数据

推荐看:栈的图文解析


另外推荐:栈的顺序存储和链式存储

0 0
原创粉丝点击