数据结构:栈的链式实现(C语言描述)

栈本质上是一个线性表,只不过对线性表的操作进行了限制,只可以在表的一端进行操作(插入、删除元素)。栈是一种是一种实现数据“先进后出”的存储结构,分为静态栈和动态栈,静态栈就是以数组的方式存储数据,动态栈是以链表的方式存储数据;对栈的操作算法,常用的就是压栈和出;下面将以链式的方式创建栈,并对用c语言实现栈的压栈和出栈的算法:

1.栈的创建

    在创建一个数据结构之前,必须知道这种数据结构由哪些参数组成,栈的本质既然是个链表,它必然由很多节点组成;为了实现“先进后出”这种数据结构,我们需要引进两个参数,一个是栈顶指针(pTop),始终指向栈顶元素。一个参数是栈底指针(pBottom),始终指向栈底元素。我们知道为了方便描述链表的各种操作,引进了头节点的概念,即为每个链表前面加一个头节点,但并存放有效数据;同样,为了实现栈的操作,我们同样需要一个不存放任何有效数据的节点,并且栈底指针始终指向该节点;

[cpp]  view plain  copy
  1. typedef int elementype;  
  2. //定义一个节点  
  3. typedef struct Node  
  4. {  
  5.     elementype data;  
  6.     struct Node *pNext;  
  7. }NODE,*PNODE;//  
  8. //构造一个栈  
  9. typedef struct stack  
  10. {  
  11.     PNODE pTop; //栈顶指针  
  12.     PNODE pBottom;//栈底指针  
  13. }STACK,*PSTACK;  
其中,使用了typedef关键词,typedef只是给一个数据类型提供一个别名;因此这里的NODE=struct Node ,PNODE=struct Node *;同样,STACK=struct stack ,PSTACK=struct Node *;

此时,数据类型构造出来了,接下来要创建一个空栈,这样我们才能进行栈的操作,创建栈,无非就是分配内存,内存分配有三种方式,静态存储区,栈,堆;

[cpp]  view plain  copy
  1. //创建一个空栈,里面没有任何有效数据;  
  2. void Create_Stack(PSTACK S)  
  3. {  
  4.     S->pBottom=(struct Node *)malloc(sizeof(struct Node));  
  5.     if(NULL==S->pBottom)  
  6.     {  
  7.         printf("Memory allocation failure");  
  8.         exit(-1);  
  9.     }  
  10.     S->pTop=S->pBottom;  
  11.     S->pTop->data=0;  
  12.     S->pTop->pNext=NULL;  //防止出现野指针  
  13. }  

图1 空栈示意图

2.压栈算法


图2 压栈算法示意图

压栈的伪算法:
(1).创建一个节点p,并修改节点的指针域使其指向栈顶数据元素;p->pNext=pTop;
(2)修改栈顶指针,使其指向栈顶元素,pTop=p;

程序代码:

[cpp]  view plain  copy
  1. //进栈  
  2. void Push_Stack(PSTACK S,int val)  
  3. {  
  4.     PNODE p=(struct Node *)malloc(sizeof(struct Node));  
  5.     if(NULL==p)  
  6.     {  
  7.         printf("Memory allocation failure");  
  8.         exit(-1);  
  9.     }  
  10.     p->data=val;  
  11.     p->pNext=S->pTop;  //让p的指针域指向上一个节点  
  12.     S->pTop=p;        //让pTop指针指向栈顶元素  
  13. }  

3.出栈算法


图3.出栈算法示意图

出栈伪算法:
(1).先用P指针保存要删除数据的地址,用于便于释放此节点的内存,即p=pTop;
(2).修改栈顶指针的指向,使其指向栈顶元素;pTop=pTop->pNext;

附录:程序代码

stack.h文件代码:

[cpp]  view plain  copy
  1. #ifndef __STACK_H_  
  2. #define __STACK_H_  
  3. typedef int elementype;  
  4. //定义一个节点  
  5. typedef struct Node  
  6. {  
  7.     elementype data;  
  8.     struct Node *pNext;  
  9. }NODE,*PNODE;//  
  10. //构造一个栈  
  11. typedef struct stack  
  12. {  
  13.     PNODE pTop; //栈顶指针  
  14.     PNODE pBottom;//栈底指针  
  15. }STACK,*PSTACK;  
  16. //函数声明区  
  17. void Create_Stack(PSTACK S);  
  18. void Push_Stack(PSTACK S,int val);  
  19. bool Pop_Stack(PSTACK S,int *val);  
  20. void Traverse_Stack(PSTACK S);  
  21. void Clear_Stack(PSTACK S);  
  22. #endif  

stack.c文件代码:

[cpp]  view plain  copy
  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include"stack.h"  
  4. //创建一个空栈,里面没有任何有效数据;  
  5. void Create_Stack(PSTACK S)  
  6. {  
  7.     S->pBottom=(struct Node *)malloc(sizeof(struct Node));  
  8.     if(NULL==S->pBottom)  
  9.     {  
  10.         printf("Memory allocation failure");  
  11.         exit(-1);  
  12.     }  
  13.     S->pTop=S->pBottom;  
  14.     S->pTop->data=0;  
  15.     S->pTop->pNext=NULL;  //防止出现野指针  
  16. }  
  17. //进栈  
  18. void Push_Stack(PSTACK S,int val)  
  19. {  
  20.     PNODE p=(struct Node *)malloc(sizeof(struct Node));  
  21.     if(NULL==p)  
  22.     {  
  23.         printf("Memory allocation failure");  
  24.         exit(-1);  
  25.     }  
  26.     p->data=val;  
  27.     p->pNext=S->pTop;  //让p的指针域指向上一个节点  
  28.     S->pTop=p;        //让pTop指针指向栈顶元素  
  29. }  
  30. //打印出栈里面的元素  
  31. void Traverse_Stack(PSTACK S)  
  32. {  
  33.     PNODE p=S->pTop;  
  34.     printf("栈中的元素是:\n");  
  35.     while(p!=S->pBottom)  
  36.     {  
  37.         printf("%d ",p->data);  
  38.         p=p->pNext;  
  39.     }  
  40.     printf("\n");  
  41. }  
  42. bool Is_Empty(PSTACK pS)  
  43. {  
  44.     if (pS->pTop == pS->pBottom)  
  45.         return true;  
  46.     else  
  47.         return false;  
  48. }  
  49. bool Pop_Stack(PSTACK S,int *val)  
  50. {  
  51.     if(Is_Empty(S))  
  52.         return false;  
  53.     else  
  54.     {  
  55.         PNODE p=S->pTop;  
  56.         *val=S->pTop->data;  
  57.         S->pTop=S->pTop->pNext;  //使pTop指针指向栈顶元素;  
  58.         free(p);  //释放p指针所指向的那个节点的内存;  
  59.         p=NULL;   //要养成好的习惯;  
  60.         return true;  
  61.     }  
  62. }  
  63. void Clear_Stack(PSTACK S)  
  64. {  
  65.     if(Is_Empty(S))  
  66.         return;  
  67.     else  
  68.     {  
  69.         PNODE p=NULL;  //养成一好习惯,定义指针记得初始化;  
  70.         while(S->pTop!=S->pBottom)  
  71.         {  
  72.             p=S->pTop;  
  73.             S->pTop=S->pTop->pNext;  
  74.             free(p);  
  75.             p=NULL;  
  76.         }  
  77.   
  78.     }  
  79. }  


自己添加的例子:

[cpp]  view plain  copy
  1. # include <stdio.h>
    # include <malloc.h>
    # include <stdlib.h>


    typedef struct Node
    {
    int data;
    struct Node * pNext;
    }NODE, * PNODE;


    typedef struct Stack
    {
    PNODE pTop;
    PNODE pBottom;
    }STACK, * PSTACK;  //PSTACK 等价于 struct STACK *


    void init(PSTACK);
    void push(PSTACK, int );
    void traverse(PSTACK);
    bool pop(PSTACK, int *);
    void clear(PSTACK pS);


    int main(void)
    {
    STACK S;  //STACK 等价于 struct Stack
    int val;


    init(&S);  //目的是造出一个空栈
    push(&S, 1); //压栈
    push(&S, 2);
    push(&S, 3);
    push(&S, 4);
    push(&S, 5);
    push(&S, 6);
    traverse(&S); //遍历输出

    clear(&S);
    //traverse(&S); //遍历输出


    if ( pop(&S, &val) )
    {
    printf("出栈成功,出栈的元素是%d\n", val);
    }
    else
    {
    printf("出栈失败!\n");
    }


    traverse(&S); //遍历输出


    return 0;
    }


    void init(PSTACK pS)
    {
    pS->pTop = (PNODE)malloc(sizeof(NODE));
    if (NULL == pS->pTop)
    {
    printf("动态内存分配失败!\n");
    exit(-1);
    }
    else
    {
    pS->pBottom = pS->pTop;
    pS->pTop->pNext = NULL; //pS->Bottom->pNext = NULL;
    }
    }


    void push(PSTACK pS, int val)
    {
    PNODE pNew = (PNODE)malloc(sizeof(NODE));

    pNew->data = val;
    pNew->pNext = pS->pTop; //pS->Top不能改成pS->Bottom
    pS->pTop = pNew;


    return;
    }


    void traverse(PSTACK pS)
    {
    PNODE p = pS->pTop;


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


    return;
    }


    bool empty(PSTACK pS)
    {
    if (pS->pTop == pS->pBottom)
    return true;
    else
    return false;
    }


    //把pS所指向的栈出栈一次,并把出栈的元素存入pVal形参所指向的变量中,如果出栈失败,返回false,否则返回true
    bool pop(PSTACK pS, int * pVal)
    {
    if ( empty(pS) ) //pS本身存放的就是S的地址
    {
    return false;
    }
    else
    {
    PNODE r = pS->pTop;
    *pVal = r->data;
    pS->pTop = r->pNext;
    free(r);
    r = NULL;


    return true;
    }
    }


    //clear清空
    void clear(PSTACK pS)
    {
    if (empty(pS))
    {
    return;
    }
    else
    {
    PNODE p = pS->pTop;
    PNODE q = NULL;


    while (p != pS->pBottom)
    {
    q = p->pNext;
    free(p);
    p = q;
    }
    pS->pTop = pS->pBottom;
    }
    }
  2.                   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值