数据结构学习之栈

注:本文的主要目的是为了记录自己的学习过程,也方便与大家做交流。转载请注明来自:

http://blog.csdn.net/ab198604


        一般来说,在进行程序设计时需要考虑数据的存储方式,不同的数据存储方式决定了其相应的数据检索方法。通常检索数据常用的存储结构为栈和队列。下面先简单介绍下这“栈”这种存储结构的一些基本知识。

        一、栈

        栈是一种按照先进后出的数据存储结构(LIFO),它检索元素的顺序与存储元素的顺序是相反的。所谓的先进后出是指数据元素的存储与删除操作,这意味着最后一个存储的元素将会第一个被删除。举个例子,现在要把"5,4,3,2,1"存入到“栈”中,从栈的底部到顶部分别是5,4,3,2,1,当删除时,顺序为“1,2,3,4,5”。

        不说理论了,来点干货。如何实现“栈”这种数据结构呢?其实,实现栈的方法有很多,可以用顺序的线性存储结构和链式的非线性存储结构。顺序存储结构如数组的方式。链式存储结构,顾名思义,是采用链表的存储方式。采用链表的方式来实现栈不仅操作简单,而且可以使栈具有多态的特性。这是因为除了栈本身的一些操作外,它毕竟本身就是一种链表,它具有与链表的相同属性。因此还可以使用链表的一些操作。所以本文采用链表的方式来实现栈。

        二、栈的结构及接口定义

        由于栈是链表的另一种表现形式,所以对栈的结构定义可以在链表的基础上进行一次封装。如下所示:

/* 
 * filename: stack.h
 * author:zhm
 * date:2012-01-05
 */

#ifndef STACK_H
#define STACK_H

#include <stdlib.h>

#include "list.h"

typedef List Stack;//对List类型重新定义
对链表的结构定义及接口,在《数据结构学习之单向链表结构》已经说明,这里不再讲述,有需要的朋友可以登录这个地址访问相关的内容:

http://blog.csdn.net/ab198604/article/details/8253405

由上面的typedef List Stack语句就已经实现了栈结构的定义了。下面为栈的相关操作:

/* public interface */
#define stack_init list_init
#define stack_destroy list_destroy
int stack_push(Stack *stack, const void *data);
int stack_pop(Stack *stack, void **data);
#define stack_peek(stack) ((stack)->head == NULL ? NULL : (stack)->head->data)
#define stack_size list_size
        主要有栈的初始化,栈的销毁,压栈操作,入栈操作等。栈的初始化、销毁及栈元素大小获取等都是在原链表接口的基础上用#define语句进一步封装而成。

        三、栈的接口实现细节

        真正要实现的就是压栈和入栈操作了,通过调用链表的接口就能实现,看下面代码:

/*
 * filename: stack.c
 * author: zhm
 * date: 2012-01-05
 */

#include <stdlib.h>

#include "list.h"
#include "stack.h"

/* stack_push */
int stack_push(Stack *stack, const void *data)
{
    /* push the data onto the stack */
    return list_ins_next(stack, NULL, data);
}

/* stack_pop */
int stack_pop(Stack *stack, void **data)
{
    /* pop the data off the stack */
    return list_rem_next(stack, NULL, data);
}

        四、栈的应用举例

        看下面代码:

/*
 * filename: main.c
 * author:zhm
 * date: 2013-01-05
 */
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "list.h"
#include "stack.h"

/* destroy */
void destroy(void *data)
{
    printf("in destroy\n");
    free(data);
    return;
}


/* main */
int main(int argc, char **argv)
{
    Stack stack;
    int *int_ptr = NULL;
    int ret = 0;
    int i;

    stack_init(&stack, destroy);

    for(i = 0; i < 5; i++ )
    {
        int_ptr = (int *)malloc(sizeof(int));
        if( int_ptr == NULL )
            return -1;

        *int_ptr = i;
        printf("push the data: %d\n",i);
        ret = stack_push(&stack, (void *)int_ptr);
        if( ret != 0 )
            return -1;
    }
    
    printf("size of the stack is : %d\n", stack_size(&stack));

    //pop the data from top to the bottom

    for(i = stack_size(&stack); i > 0; i-- )
    {
        int_ptr = NULL;
        stack_pop(&stack, (void **)&int_ptr);
        printf("i = %d, pop the data = %d\n",i,*int_ptr);
        free(int_ptr);
    }
    
    printf("after pop size of the stack is :%d\n", stack_size(&stack));
    return 0;
}
        上述main()函数所实现的功能主要是将数据:0,1,2,3,4分别压入栈中,然后将其一一从栈顶弹出。程序经过编译运行后,结果如下所示:







        



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值