由于现在只学了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 0 6 #define ERROR 1 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 41 /*p->top = p->base + p->stacksize;这句是有必要加上的 42 这一个问题的关键在于 realloc 是怎么实现的,有两种情况: 43 如果有足够空间用于扩大mem_address指向的内存块,则分配额外内存,并返回mem_address。 44 这里说的是“扩大”,我们知道,realloc是从堆上分配内存的,当扩大一块内存空间时, 45 realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平。 46 也就是说,如果原先的内存大小后面还有足够的空闲空间用来分配,加上原来的空间大小= newsize。 47 那么就ok。得到的是一块连续的内存。 48 如果原先的内存大小后面没有足够的空闲空间用来分配,那么从堆中另外找一块newsize大小的内存。 49 并把原来大小内存空间中的内容复制到newsize中。返回新的mem_address指针。(数据被移动了)。老块被放回堆上。 50 如果是第二种情况的话,s->top 就不是原来的 top 了--百度百科*/ 51 52 p->stacksize += STACKINCREMENT; 53 } 54 *(p->top) = e; 55 (p->top)++; 56 return OK; 57 } 58 // 顺序栈的弹出 59 int Pop(SqStack *p,StackType *e) { 60 //若栈不空,则删除p的栈顶元素,用e返回其值 61 if (p->top == p->base) return ERROR; 62 --(p->top); 63 *e = *(p->top); 64 return OK; 65 66 67 } 68 //顺序栈的销毁 69 int DestroyStack(SqStack *p) { 70 //释放栈底空间并置空 71 free(p->base); 72 p->base = NULL; 73 p->top = NULL; 74 p->stacksize = 0; 75 76 return OK; 77 } 78 //将顺序栈置空 栈还是存在的,栈中的元素也存在,如果有栈中元素的地址任然能调用 79 int ClearStack(SqStack *p) { 80 p->top= p->base; 81 return OK; 82 } 83 //返回顺序栈的元素个数 84 int StackLength(SqStack p) { 85 //栈顶指针减去栈底指针等于长度,因为栈顶指针指向当前栈顶元素的下一个位置 86 return p.top - p.base; 87 } 88 //返回顺序栈的栈顶元素 89 int GetTop(SqStack *p, StackType *e) { 90 //若栈不为空,则用e返回p的栈顶元素 91 if (p->top > p->base) { 92 *e = *(p->top - 1); return OK; 93 } 94 else return ERROR; 95 } 96 //从栈顶到栈底对每个元素调用某个函数 97 int StackTraverse(SqStack p,void (*pfun)(StackType)/*函数指针*/){ 98 //从栈底到栈顶依次对栈中的每个元素调用函数pfun() 99 while (p.top > p.base) 100 pfun(*(p.base)++); //先调用后递增 101 printf("\n"); 102 return OK; 103 } 104 //打印栈中元素 105 void print(StackType stack) { 106 printf("%d\n", stack); 107 108 } 109 //测试栈的各种操作 110 int main() { 111 int n,i; 112 StackType *e,a; 113 SqStack *pstack,stack; 114 pstack = &stack; 115 e=(StackType*)malloc(sizeof(StackType)); //为指针e分配内存地址 116 InitStack(pstack); //初始化栈 117 118 if (EmptyStack(pstack) == 0) printf("-------栈为空-------\n"); 119 printf("请输入栈的元素个数:"); 120 scanf("%d", &n); 121 for (i = 0; i < n; i++) 122 { 123 scanf("%d", &a); 124 Push(pstack, a); 125 } 126 if (EmptyStack(pstack) == 1) printf("-------栈不为空-----\n"); 127 128 printf("栈的长度为:%d\n", StackLength(stack)); 129 printf("--------------------\n"); 130 printf("请输入一个入栈元素:"); 131 scanf("%d", &a); 132 Push(pstack, a); 133 printf("--------------------\n"); 134 printf("栈中的元素个数为:%d\n", StackLength(stack)); 135 printf("--------------------\n"); 136 GetTop(pstack, e); 137 printf("栈顶元素为:%d\n", *e); 138 printf("--------------------\n"); 139 printf("打印栈中的元素:\n"); 140 StackTraverse(stack, print); 141 printf("---弹出栈顶元素---\n"); 142 Pop(pstack, e); 143 printf("弹出的栈顶元素为:%d\n", *e); 144 printf("--------------------\n"); 145 GetTop(pstack, e); 146 printf("栈顶元素为:%d\n", *e); 147 printf("--------------------\n"); 148 printf("打印栈中的元素:\n"); 149 StackTraverse(stack, print); 150 printf("--------------------\n"); 151 152 printf("----------清空栈-------\n"); 153 if (ClearStack(pstack) == 0) printf("已清空栈\n"); 154 155 printf("----------销毁栈-------\n"); 156 if (DestroyStack(pstack) == 0) printf("已销毁栈\n"); 157 return 0; 158 159 }
写这些代码的时候还是遇到了一些问题 在这里总结一下:
第一 对于指针的使用要慎重 因为它传递进函数会改变原始数据,所以对于不需要改变
指针指向的值的情况就不要使用指针。
第二 对于指针的使用 如下定义 int *e=NULL; *e=3;
看着好像没有问题 编译也没问题 但是运行程序就出错
为什么? 没有为指针e分配内存地址 所以引用肯定错误啊(我这个逗逼错误-_-)
正确的用法应该是 int *e=NULL;e=(int*)malloc(sizeof(int)); *e=3;
我之前都是 int *e,a; e=&a; e=3; 这种用法 所以......
原文地址:https://www.cnblogs.com/mwq1024/p/10146943.html
时间: 2024-10-25 17:00:36