zoukankan      html  css  js  c++  java
  • 顺序栈的基本操作(C语言)

      由于现在只学了C语言所以就写这个C语言版的栈的基本操作

    这里说一下 :网上和书上都有这种写法 int InitStack(SqStack &p)

    &p是取地址  但是这种用法好像C并不支持 ,C++才支持,所以用

    C语言写就需要使用指针

    代码如下:

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #define STACK_INIT_SIZE 100//储存空间初始分配量
      4 #define STACKINCREMENT  10//存储空间分配增量
      5 #define OK 1
      6 #define ERROR 0
      7 typedef int StackType; //栈元素类型
      8  
      9 typedef struct {
     10     StackType *base;   //在构造之前和销毁之后,base的值为NULL
     11     StackType *top;    //栈顶指针
     12     int stacksize;     //当前已分配的存储空间,以元素为单位
     13 }SqStack; //顺序栈
     14 
     15 //栈的初始化
     16 int InitStack(SqStack *p) {
     17     
     18     
     19     p->base = (StackType*)malloc(STACK_INIT_SIZE * sizeof(StackType));
     20     if (p->base == NULL)  return ERROR;  //内存分配失败
     21     p->top = p->base;     //栈顶与栈底相同表示一个空栈
     22     p->stacksize = STACK_INIT_SIZE;
     23     return OK;
     24 
     25 }
     26 //判断栈是否为空
     27 int EmptyStack(SqStack *p) {
     28     //若为空栈 则返回OK,否则返回ERROR
     29     if (p->top == p->base) return OK;
     30     else return ERROR;
     31 }
     32 //顺序栈的压入
     33 int Push(SqStack *p,StackType e) {
     34     //插入元素e为新的栈顶元素
     35     if ((p->top - p->base)>= p->stacksize)   //栈满,追加储存空间
     36     {
     37         p->base = (StackType*)realloc(p->base, (p->stacksize + STACKINCREMENT) * sizeof(StackType));
     38         if (p->base == NULL)   return ERROR;// 储存空间分配失败
     39         p->top = p->base + p->stacksize;    //可能有人觉得这句有点多余(我当时也是这么想的 后面有解释)
     40         p->stacksize += STACKINCREMENT;
     41     }
     42     *(p->top) = e;
     43     (p->top)++;
     44     return OK;
     45 }
     46  // 顺序栈的弹出     
     47 int Pop(SqStack *p,StackType *e) {
     48     //若栈不空,则删除p的栈顶元素,用e返回其值
     49     if (p->top == p->base) return ERROR;
     50     --(p->top);
     51     *e = *(p->top);
     52     return OK;
     53     
     54 
     55 }
     56 //顺序栈的销毁
     57 int DestroyStack(SqStack *p) {
     58     //释放栈底空间并置空
     59         free(p->base);
     60         p->base = NULL;
     61         p->top = NULL;
     62         p->stacksize = 0;
     63         
     64         return OK;
     65 }
     66 //将顺序栈置空 栈还是存在的,栈中的元素也存在,如果有栈中元素的地址任然能调用
     67 int ClearStack(SqStack *p) {
     68     p->top= p->base;
     69     return OK;
     70 }
     71 //返回顺序栈的元素个数
     72 int StackLength(SqStack p) {
     73     //栈顶指针减去栈底指针等于长度,因为栈顶指针指向当前栈顶元素的下一个位置
     74     return p.top - p.base;
     75 }
     76 //返回顺序栈的栈顶元素
     77 int GetTop(SqStack *p, StackType *e) {
     78     //若栈不为空,则用e返回p的栈顶元素
     79     if (p->top > p->base) {
     80         *e = *(p->top - 1); return OK;
     81     }
     82     else return ERROR;
     83 }
     84 //从栈顶到栈底对每个元素调用某个函数
     85 int StackTraverse(SqStack p,void (*pfun)(StackType)/*函数指针*/){
     86 //从栈底到栈顶依次对栈中的每个元素调用函数pfun()
     87     while (p.top > p.base)
     88     pfun(*(p.base)++);                //先调用后递增
     89     printf("
    ");
     90     return OK;
     91 }
     92 //打印栈中元素
     93 void print(StackType stack) {
     94     printf("%d
    ", stack);
     95     
     96 }
     97 //测试栈的各种操作
     98 int main() {
     99     int n,i;
    100     StackType *e,a;
    101     SqStack *pstack,stack;
    102     pstack = &stack;
    103     e=(StackType*)malloc(sizeof(StackType));    //为指针e分配内存地址
    104     InitStack(pstack);                            //初始化栈
    105 
    106     if (EmptyStack(pstack) == 1) printf("-------栈为空-------
    ");
    107     printf("请输入栈的元素个数:");
    108     scanf("%d", &n);
    109     for (i = 0; i < n; i++)
    110     {
    111         scanf("%d", &a);
    112         Push(pstack, a);
    113     }
    114     if (EmptyStack(pstack) == 0) printf("-------栈不为空-----
    ");
    115         
    116     printf("栈的长度为:%d
    ", StackLength(stack));
    117     printf("--------------------
    ");
    118     printf("请输入一个入栈元素:");
    119     scanf("%d", &a);
    120     Push(pstack, a);
    121     printf("--------------------
    ");
    122     printf("栈中的元素个数为:%d
    ", StackLength(stack));
    123     printf("--------------------
    ");
    124     GetTop(pstack, e);
    125     printf("栈顶元素为:%d
    ", *e);
    126     printf("--------------------
    ");
    127     printf("打印栈中的元素:
    ");
    128     StackTraverse(stack, print);
    129     printf("---弹出栈顶元素---
    ");
    130     Pop(pstack, e);
    131     printf("弹出的栈顶元素为:%d
    ", *e);
    132     printf("--------------------
    ");
    133     GetTop(pstack, e);
    134     printf("栈顶元素为:%d
    ", *e);
    135     printf("--------------------
    ");
    136     printf("打印栈中的元素:
    ");
    137     StackTraverse(stack, print);
    138     printf("--------------------
    ");
    139 
    140     printf("----------清空栈-------
    ");
    141     if (ClearStack(pstack) == 0)  printf("已清空栈
    ");
    142     
    143     printf("----------销毁栈-------
    ");
    144     if (DestroyStack(pstack) == 0)  printf("已销毁栈
    ");
    145     return 0;
    146    
    147 }
        

     

          第39行  p->top = p->base + p->stacksize;这句有必要加上吗?  答案是肯定的。
            这一个问题的关键在于 realloc 是怎么实现的,有两种情况:

       如果有足够空间用于扩大mem_address指向的内存块,则分配额外内存,并返回mem_address。
     这里说的是“扩大”,我们知道,realloc是从堆上分配内存的,当扩大一块内存空间时,
    realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平。
     也就是说,如果原先的内存大小后面还有足够的空闲空间用来分配,加上原来的空间大小= newsize。
    那么就ok。得到的是一块连续的内存。
       如果原先的内存大小后面没有足够的空闲空间用来分配,那么从堆中另外找一块newsize大小的内存。
     并把原来大小内存空间中的内容复制到newsize中。返回新的mem_address指针。(数据被移动了)。老块被放回堆上。
     如果是第二种情况的话,s->top 就不是原来的 top 了     --百度百科

      写这些代码的时候还是遇到了一些问题 在这里总结一下:

      第一 对于指针的使用要慎重 因为它传递进函数会改变原始数据,所以对于不需要改变

    指针指向的值的情况就不要使用指针。

      第二 对于指针的使用  如下定义 int *e=NULL; *e=3;

    看着好像没有问题  编译也没问题 但是运行程序就出错

    为什么?  没有为指针e分配内存地址 所以引用肯定错误啊(我这个逗逼错误-_-)

    正确的用法应该是 int *e=NULL;e=(int*)malloc(sizeof(int)); *e=3;

    我之前都是 int *e,a; e=&a; e=3; 这种用法 所以......

    
    
    
  • 相关阅读:
    【Codeforces 349B】Color the Fence
    【Codeforces 459D】Pashmak and Parmida's problem
    【Codeforces 467C】George and Job
    【Codeforces 161D】Distance in Tree
    【Codeforces 522A】Reposts
    【Codeforces 225C】Barcode
    【Codeforces 446A】DZY Loves Sequences
    【Codeforces 429B】Working out
    【Codeforces 478C】Table Decorations
    【Codeforces 478C】Table Decorations
  • 原文地址:https://www.cnblogs.com/mwq1024/p/10146943.html
Copyright © 2011-2022 走看看