栈_STACK的实现

  • 栈_STACK
  • 栈的基本操作
  • 栈的代码实现
    • 栈的C语言实现
    • 栈的C实现
  • 结论

本文中的完整代码你可以在这里:

https://github.com/qeesung/algorithm/tree/master/chapter10/10-1/栈

或者这里:

顺序栈的实现:http://download.csdn.net/detail/ii1245712564/8744663

链式栈的实现:http://download.csdn.net/detail/ii1245712564/8744679

C语言实现链式栈的模板:http://download.csdn.net/detail/ii1245712564/8744691

找到!

栈_STACK

栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

这么讲似乎有点抽象,我们就将栈比作一个弹夹,子弹就好比栈中操作的数据元素,我们将子弹一个一个压入弹夹之内(压栈操作),在射击的时候,弹夹将处于弹夹最上方的子弹弹出(出栈操作)。注意,只能弹出处于弹夹最上方的元素,这这是栈操作的一种限制。

栈是一种先进后出(FILO First In Last Out)的数据结构,顾名思义,就是越早进入栈中的元素,进行出栈操作时,这个元素就会越晚被弹出来。好比最先压入弹夹中的子弹是被最后打出的,最后压入的子弹是被最先打出的。

栈的基本操作

首先定义栈的两个基本操作:

  • 压栈(Push(Stack , Ele))
  • 出栈(Pop(Stack))
  • 清空栈(Clear(Stack))
  • 得到栈顶元素(TopValue(Stack))

栈的代码实现

这里我们将采用两种方式来实现栈,一种是C++模板的形式,一种是C语言的形式,我们在C语言的实现中,仿照C++实现了一个通用栈模板


栈的C语言实现

c_stack.h

#ifndef C_STACK_h
#define C_STACK_h
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

struct stackNode_s
{
    struct stackNode_s * next;// 指向下一个节点
};
typedef struct stackNode_s * StackNode;

struct stack_s
{
    StackNode top;
    StackNode buttom;
};
typedef struct stack_s * Stack;

/** 创建一个新的栈 */
Stack createStack();
/** 压栈 */
bool push(Stack , StackNode);
/** 出栈 */
bool pop(Stack , StackNode *);
/** 得到栈顶元素的值 */
bool topValue(Stack , StackNode *);
#endif

在上面的代码里面,栈节点的结构我们只定义了一个指向下一个节点的指针,并没有任何实际的数据,这里不是错误。

c_stack.c

#include "c_stack.h"
#include <stdlib.h>
#include <stdio.h>

/** 创建一个栈 */
Stack createStack()
{
    Stack newStack = (Stack)malloc(sizeof(struct stack_s));
    if(newStack == NULL)
        return NULL;
    // 创建一个头部节点,头结点来表示栈底部
    newStack->buttom = (StackNode)malloc(sizeof(struct stackNode_s));
    if(newStack->buttom == NULL)
    {
        free(newStack);
        return NULL;
    }
    // 初始化一些数据
    newStack->buttom->next =NULL;
    newStack->top = newStack->buttom;
    return newStack;
}

/** 入栈操作 */
bool push(Stack stack , StackNode stackNode)
{
    if(stack == NULL ||       stack->top == NULL ||       stack->buttom == NULL ||       stackNode == NULL)
        return false;
    stackNode->next = NULL;

    /** 对一个stack Node 压栈 */
    stack->top->next = stackNode;
    stack->top = stackNode;
    return true;
}

/** 出栈操作 */
bool pop(Stack stack, StackNode * stackNode)
{
    if(stack == NULL ||       stack->top == NULL ||       stack->buttom == NULL ||       stackNode == NULL)
        return false;
    // 空栈
    if(stack->top == stack->buttom)
        return false;
    /** 找到top的前一个元素 */
    StackNode lastNode = stack->buttom;
    while(lastNode->next!=stack->top)
    {
        lastNode = lastNode->next;
    }

    StackNode tempNode = stack->top;
    *stackNode = tempNode;

    stack->top = lastNode;
    stack->top->next = NULL;
    return true;
}

/** 得到栈顶元素 */
bool topValue(Stack stack , StackNode * stackNode)
{
    if(stack == NULL ||       stack->top == NULL ||       stack->buttom == NULL ||       stackNode == NULL)
        return false;
    // 空栈
    if(stack->top == stack->buttom)
        return false;
    *stackNode = stack->top;
    return true;
}

注意上面只是一个栈的模板,如果我们要添加对应的数据,那么就要实例化这个模板,下面是实例化一个int类型的栈



c_stack_int.h

#ifndef C_STACK_INT_H
#define C_STACK_INT_H

#include "c_stack.h"
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

struct int_stackNode_s
{
    StackNode stackNode;
    int data;// 这个是实际的数据
};

typedef struct int_stackNode_s * IntStackNode;

bool push_intStack(Stack , int number);
bool pop_intStack(Stack , int * number);
bool topValue_intStack(Stack , int * number);
void print_intStack(Stack);
void destory_intStack(Stack);
void clear(Stack);

#endif

基于上面的栈模板,实现对应的int栈操作

c_stack_int.c

#include "c_stack_int.h"
#include <stdlib.h>
/** 释放一个栈的递归操作函数 */
static void freeList(StackNode tempNode);

/** 压栈 */
bool push_intStack(Stack stack , int number)
{
    IntStackNode newNode = (IntStackNode)malloc(sizeof(struct int_stackNode_s));
    if(newNode == NULL)
        return false;
    newNode->data = number;
    return push(stack , (StackNode)newNode);//这里用模板里面的压栈操作来实现!
}

/** 出栈 */
bool pop_intStack(Stack stack , int * number)
{
    if(number == NULL)
        return false;
    StackNode popNode;
    if(!pop(stack , &popNode))
        return false;
    IntStackNode intPopNode = (IntStackNode)popNode;
    *number = intPopNode->data;
    free(intPopNode);
    return true;
}

/** 得到栈顶元素 */
bool topValue_intStack(Stack stack , int * number)
{
    if(number == NULL)
        return false;
    StackNode topNode;
    if(!topValue(stack , &topNode))
        return false;
    IntStackNode intTopNode = (IntStackNode)topNode;
    *number = intTopNode->data;
    return true;
}

/** 打印一个栈 */
void print_intStack(Stack stack)
{
    if(stack == NULL)
        return;
    StackNode tempNode = stack->buttom->next;
    while(tempNode!=NULL)
    {
        IntStackNode intNode = (IntStackNode)tempNode;
        printf("%d\t",intNode->data);
        tempNode = tempNode->next;
    }
    printf("\n");
}

/** 摧毁一个栈 */
void destory_intStack(Stack stack)
{
    if(stack == NULL ||       stack->buttom == NULL ||       stack->top == NULL)
        return;
    StackNode tempNode = stack->buttom;
    freeList(tempNode);
}

/** 清空一个栈 */
void clear(Stack stack)
{
    if(stack == NULL ||       stack->buttom == NULL ||       stack->top == NULL)
        return;
    StackNode tempNode = stack->buttom->next;
    freeList(tempNode);
    stack->top = stack->buttom;
}

static void freeList(StackNode tempNode)
{
    while(tempNode!=NULL)
    {
        StackNode temp = tempNode->next;
        free((IntStackNode)tempNode);
        tempNode = temp;
    }
}

注意在上面的代码里面,压栈操作和出栈操作都不是重新实现一遍,而是通过栈模板的push(),pop()操作来实现的

push_intStack()  --基于-> push(stack , (StackNode)newNode);
pop_intStack() --基于-> pop(stack , &popNode)
topValue_intStack --基于-> topValue(stack , &topNode)

测试C语言实现的栈

运行结果

test push ——————————————-

pushed 10

pushed 11

test push ——————————————-

test top ——————————————-

top data is 11

test top ——————————————-

test pop ——————————————-

get pop number 11

get pop number 10

pop failed

test pop ——————————————-

test all ——————————————-

pushed 12

top data is 12

get pop number 12

pop failed

test all ——————————————-

栈的C++实现

C++里面有一个非常好用的东西,就是模板,我们借用模板之手实现栈,下面是一个通用接口



stack.h

#ifndef STACK_H
#define STACK_H

// 此类不可实例化
template <class Elem>
class Stack
{
public:
    // 清空栈
    virtual void clear() = 0;
    // 压入栈
    virtual bool push(const Elem & ele) =0;
    // 出栈
    virtual bool pop(Elem & ele)=0;
    // 得到栈顶元素
    virtual bool topValue(Elem & ele )const =0;
    // 得到栈长度
    virtual int length() const =0;
};  

#endif

子类化上面的Stack,实现对应的接口功能

arrayBaseStack.h

#ifndef ARRAYBASE_STACK_H
#define ARRAYBASE_STACK_H

#include "stack.h"

template <class Elem>
class ArrayBaseStack : public Stack<Elem>
{
private:
    int top;// 指示栈顶位置
    int size;// 指示整个栈的长度
    Elem * array;// 指示数组
public:
    ArrayBaseStack(int _size=10);
    ~ArrayBaseStack();

    // 清空栈
    void clear() ;
    // 压入栈
    bool push(const Elem & ele);
    // 出栈
    bool pop(Elem & ele);
    // 得到栈顶元素
    bool topValue(Elem & ele )const;
    // 得到栈长度
    int  length() const;
    // 打印整个栈
    void printStack() const;
}; 

#include "arrayBaseStack.cc"

#endif

在源文件中实现接口功能

arrayBaseStack.cc

#include <iostream>

template <class Elem>
ArrayBaseStack<Elem>::ArrayBaseStack(int _size):size(_size)
{
    array = new Elem[size];
    top=-1;
}

template <class Elem>
ArrayBaseStack<Elem>::~ArrayBaseStack()
{
    delete [] array;
}

template <class Elem>
void ArrayBaseStack<Elem>::clear()
{
    top = -1;
}

template <class Elem>
bool ArrayBaseStack<Elem>::push(const Elem & ele)
{
    if(top == size-1)
        return false;
    array[++top]=ele;
    return true;
}

template <class Elem>
bool ArrayBaseStack<Elem>::pop(Elem & ele)
{
    if(top == -1)
        return false;
    ele = array[top--];
    return true;
}

template <class Elem>
bool ArrayBaseStack<Elem>::topValue(Elem & ele )const
{
    if(top == -1)
        return false;
    ele = array[top];
    return true;
}

// 得到栈长度
template <class Elem>
int  ArrayBaseStack<Elem>::length() const
{
    return top+1;
}

// 打印整个栈
template <class Elem>
void ArrayBaseStack<Elem>::printStack() const
{
    for (int i = 0; i <= top; ++i)
    {
        std::cout<<array[i]<<"\t";
    }
    std::cout<<std::endl;
}

怎么样,是不是比C语言版本的容易好多


测试C++实现的栈

运行结果:

pushed 0

pushed 1

pushed 2

pushed 3

pushed 4

pushed 5

pushed 6

pushed 7

pushed 8

pushed 9

pushed 10

pushed 11

0 1 2 3 4 5 6 7 8 9 10 11

get 11

get 10

get 9

get 8

get 7

get 6

get 5

get 4

get 3

get 2

get 1

get 0

结论

C++就是比C语言好用啊!( ˉ □ ˉ )

时间: 2024-10-26 20:11:37

栈_STACK的实现的相关文章

c++:实现一个栈,包括入栈、出栈函数以及返回最小值,要求时间复杂度为O(1)

MinStakc.cpp #include<iostream> using namespace std; #include<stack> template<class T> class Stack{ public:  void Push(const T& x){                       //入栈   _stack.push(x);   if (_minstack.empty())    _minstack.push(x);   else{  

第4章 栈与队列

栈(stack)是限定仅在表尾进行插入和删除操作的线性表,即后进先出(LIFO,Last In First Out).如浏览器上的"后退"按钮. ADT 栈(stack) Data 同线性表.元素具有相同的类型,相邻元素具有前驱和后继关系. Operation Initstack(*S);初始化操作,建立一个空栈S. DestroyStack(*S);若栈存在,则销毁它. ClearStack(*S);将栈清空. StackEmpty(S);若栈为空,返回true;否则返回false.

七方件业金离以提领前群约会ODjdidtlwfWv

为了从不同环节,尤其与广大使用人群直接关系的环节反映质量状况,对共享自行车投放点.运营仓库.生产企业等不同环节的产品抽查,覆盖了共享自行车从成品出厂到待投放的关键环节. 该负责人称,根据新车投放情况,结合共享自行车行业市场占有分布特点,本次重点抽查了摩拜.ofo.Hellobike三个品牌的产品,占本次抽查批次总数的83.3%.其中,在天津.无锡.武汉.广州.深圳.东莞6个城市抽查了9批次摩拜产品,占产品抽查批次总数的37.5%,抽查批次合格率88.9%,抽查不合格的1批次产品为待投放于广州市的

关于栈和队列的相关问题

#include<iostream> using namespace std; #include<stack> #include<queue> #include<assert.h> //template<class T> //两个栈实现一个队列 //class StackToqueue //{ //public: // StackToqueue() // {} // void Push(const T& x) // {//始终保持让栈1进

算法导论8:数据结构——栈 2016.1.8

栈在暑假的时候接触过了,当时还写了个计算器,用的中缀表达式后缀表达式的栈操作. http://www.cnblogs.com/itlqs/p/4749998.html 今天按照算法导论上的讲解规范了一下代码.主要是栈的初始化.判断空栈.入栈.出栈.遍历栈. #include<stdio.h> #define MAXTOP 10 struct _stack { int top; int num[MAXTOP+1]; }s; void init(struct _stack &S) { S.

C++ Primer 学习笔记_23_标准模板库_stack.

C++ Primer 学习笔记_11_标准模板库_stack.queue队列容器与priority_queue优先队列容器 1.stack堆栈 stack堆栈是一个后进先出(Last In First Out,LIFO)的线性表,插入和删除元素都只能在表的一端进行.插入元素的一端称为栈顶,而另一端称为栈底.插入元素叫入栈(Push),删除元素叫出栈(Pop).下图是堆栈示意图 堆栈只提供入栈,出栈,栈顶元素访问和判断是否为空等几种方法.采用push()方法将元素入栈:采用pop()方法出栈:采用

用JS描述的数据结构及算法表示——栈和队列(基础版)

前言:找了上课时数据结构的教程来看,但是用的语言是c++,所以具体实现在网上搜大神的博客来看,我看到的大神们的博客都写得特别好,不止讲了最基本的思想和算法实现,更多的是侧重于实例运用,一边看一边在心里隐隐歌颂大神的厉害,然后别人的厉害不是我的,所以到底看得各种受打击+头昏脑涨,写这个系列是希望自己能够总结学到东一块.西一下的知识,因为水平有限+经验不足,所以在此只说最基础的思想,附上我自己的算法实现(肯定还有更优解),如果要想看进阶版的,可以在园里搜“数据结构”,各种语言实现和进阶提升的文章有很

实现一个栈,并且实现一个min函数用来找当前栈中最小的元素

题目描述:实现一个栈,并且实现一个min函数用来找当前栈中最小的元素 分析:要找到栈中最小的元素,需要借助一个辅助栈,来存放当前栈中最小的元素. 入栈的时候,第一个入栈的元素,也给辅助栈入栈,此后每次入栈的元素先与辅助栈的栈顶元素比较,如果小于或等于辅助栈的栈顶元素,则同时将该元素给辅助栈入栈. 如下图所示: 出栈的时候,如果栈顶元素与辅助栈栈顶的元素相等,则同时对辅助栈进行出栈操作 如下图所示: 这样就可以保证,辅助栈中的栈顶元素始终是当前栈中最小的元素了 代码如下: #include<ios

栈和队列常见问题及其算法和c++实现

1.实现一个栈,要求实现push,pop,Min(返回最小值的操作)的时间复杂度为O(1) 算法思想:需要设计一个辅助栈,用来存储当前栈中元素的最小值.额外需要注意push操作,第一个元素不用比较,自动成为最小值入栈,其他元素每次都要和栈顶元素进行比较,小的入栈. #include<iostream> #include<stack>      //直接用系统中的栈,不需要自己实现 using namespace std; template<class T> class