数据结构之栈学习(1)

(1)什么是栈

     栈是一种实现“先进后出”的存储结构。

    

(2)栈的表示

     栈有两种存储表示方法。顺序栈和链式栈

(3)栈的组成

    栈顶指针,栈底指针(还可以为栈分配一个基本的容量)

    入栈的节点要包括两部分:数据域,指针域。数据域用来存储数据;指针域用来指向另一个节点。既然入栈的节点包括两部分,则必定要用结构体来表示入栈的节点,用代码    可实现:

   

typedef struct node
{
    int data;//数据域
    struct node *pNext;//指针域
}NODE, *PNODE;

   栈中的两个指针必定要指向入栈的节点,因此指针必须与节点的数据类型相同,则栈用代码可实现:

typedef struct stack
{
    PNODE top;//栈顶指针
    PNODE buttom;//栈底指针
}STACK, *PSTACK;

(4)栈的基本操作

    1、初始化栈,即构造一个空栈。

          动态申请一块内存,并将栈顶指针和栈底指针同时指向该内存。

         

         相应函数的代码实现:

        void initStack(PSTACK ps)
       {
           ps->top = (PNODE)malloc(sizeof(NODE));
          if(NULL == ps->top)
         {
             printf("动态内存分配失败\n");
            exit(-1);
        }
        else
       {
            ps->top->pNext = NULL;//将栈顶指针指向节点的指针域赋为空
            ps->buttom = ps->top;//将栈顶指针付给栈底指针
       }
     }

    2、入栈

         入栈操作要指定需要对哪个栈操作,以及入栈的值。

         首先要动态申请内存,并将数据域赋值,然后将该节点的指针域指向栈顶指针指向的节点的地址,最后将该节点的地址付给栈顶指针。

         

          相应函数的代码实现:

          void pushStack(PSTACK ps, int val)//在ps栈中压入值val
          {
              PNODE pNew = (PNODE)malloc(sizeof(NODE));
              pNew->data = val;//将要压入的值赋给新申请的节点的数据域中
              pNew->pNext = NULL;//将新申请的节点的指针赋为空
              ///
              pNew->pNext = ps->top;
              ps->top = pNew;
          }

     3、遍历

           按照先进后出的顺序将栈中的元素输出

           首先,要定义一个PNODE类型的变量p,并将栈顶指针指向的节点的地址赋给p,然后利用p = p->pNext进行遍历。

           具体函数实现:

           void traverse(PSTACK ps)
           {
              PNODE p;
              p = ps->top;
              while(p != ps->buttom)
              {
                  printf("%d ",p->data);
                  p = p->pNext;
              } 
             printf("\n");
           }

     4、判空

          判断栈中是否含有元素。其中最为关键的:判断栈顶指针是否等于栈底指针。如果是,则栈为空;如果否,则栈不为空。

         bool empty(PSTACK ps)
         {
            if(ps->top == ps->buttom)
               return true;
           else
              return false;
         }  

     5、出栈

          首先,要判断栈中是否含有元素。若没有,则返回false;若有,才进行出栈操作。首先,申请一个PNODE类型的变量rm,并将栈顶指针指向的节点赋给它。然后将rm指向           的节点的指针域所指向的节点的地址赋给栈顶指针。此时,可以利用free函数释放内存。不要忘记将释放后的rm赋值为NULL。

          函数实现:

          bool pop(PSTACK ps, int *pval)
          {
              PNODE rm;
              if(empty(ps))
                  return false;
             else
             {
                 rm = ps->top;
                *pval = rm->data;
                 ps->top = rm->pNext;
                 free(rm);
                 rm = NULL;//当不在使用申请的内存时,记得释放。释放后应该把指向这块内存的指针指向NULL
                                      //以防程序后面不小心使用它。
                return true;
             }
         }

    6、清空栈

         将栈中的元素清除。最后,回到初始化状态。

         首先,定义两个PNODE 类型的变量p,q。其中将栈顶元素所指向的节点的地址赋给p,将p赋值为NULL。q = p->pNext表示将q指向p所指向的节点的指针域所只想和的节            点。然后将p释放,然后将q的值赋给p。在while循环中,只要p != ps->buttom则一直循环下去。直到条件满足,跳出循环。

         函数实现:

         void clear(PSTACK ps)
         {
             PNODE p = ps->top;
             PNODE q = NULL;
             while(p != ps->buttom)
            {
                q = p->pNext;
                free(p);//释放p所指向的用函数malloc所申请的空间
                p = q;
           }
          ps->top = ps->buttom;
       }

    7、栈的全部代码:

     

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct node
{
    int data;//数据域
    struct node *pNext;//指针域
}NODE, *PNODE;

typedef struct stack
{
    PNODE top;//栈顶指针
    PNODE buttom;//栈底指针
}STACK, *PSTACK;

/**初始化栈**/
void initStack(PSTACK ps)
{
    ps->top = (PNODE)malloc(sizeof(NODE));
    if(NULL == ps->top)
    {
        printf("动态内存分配失败\n");
        exit(-1);
    }
    else
    {
        ps->top->pNext = NULL;//将栈顶指针指向节点的指针域赋为空
        ps->buttom = ps->top;//将栈顶指针付给栈底指针
    }
}

/**入栈**/
void pushStack(PSTACK ps, int val)//在ps栈中压入值val
{
    PNODE pNew = (PNODE)malloc(sizeof(NODE));
    pNew->data = val;//将要压入的值赋给新申请的节点的数据域中
    pNew->pNext = NULL;//将新申请的节点的指针赋为空
    ///
    pNew->pNext = ps->top;
    ps->top = pNew;
}
/**遍历**/
void traverse(PSTACK ps)
{
    PNODE p;
    p = ps->top;

    while(p != ps->buttom)
    {
        printf("%d ",p->data);
        p = p->pNext;
    }
    printf("\n");
}

/**判空**/
bool empty(PSTACK ps)
{
    if(ps->top == ps->buttom)
        return true;
    else
        return false;
}

/**出栈**/
bool pop(PSTACK ps, int *pval)
{
    PNODE rm;
    if(empty(ps))
        return false;
    else
    {
        rm = ps->top;
        *pval = rm->data;
        ps->top = rm->pNext;
        free(rm);
        rm = NULL;//当不在使用申请的内存时,记得释放。释放后应该把指向这块内存的指针指向NULL
                  //以防程序后面不小心使用它。
        return true;
    }
}
/**清空栈**/
void clear(PSTACK ps)
{
    PNODE p = ps->top;
    PNODE q = NULL;

    while(p != ps->buttom)
    {
        q = p->pNext;
        free(p);//释放p所指向的用函数malloc所申请的空间
        p = q;
    }
    ps->top = ps->buttom;
}

void main()
{
    STACK s;
    int val;
    initStack(&s);
    /**************
    测试empty(PSTACK ps)函数
    if(empty(&s))
    {
        printf("ok");
        printf("\n");
    }
    **************/
    pushStack(&s, 1);
    pushStack(&s, 2);
    pushStack(&s, 3);
    pushStack(&s, 4);
    pushStack(&s, 5);
    traverse(&s);
    clear(&s);
    if(pop(&s, &val))
    {
        printf("出栈成功,出栈的元素为:%d\n",val);
    }
    else
    {
        printf("出栈失败\n");
    }
    traverse(&s);


    return;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值