網易公開課學習,一個棧的實現,VC2010控制檯程序編譯通過:
//
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <assert.h>
int loglength; //棧中元素數量
int alloclength; //分配棧長度
int elemsize; //元素長度
void * elems; //棧空間
void (* freefn)(void *); //釋放內存函數
void StackNew(Stack * s,int elemsize, void (* freefn)(void *));
void StackDispose(Stack * s);
void StackPush(Stack *s,void * elemaddr);
void StackPop(Stack *s,void * elemaddr);
void StackGrow(Stack *s);
void stringfree(void * elem);
{
const char *friends[] = {"Alan","Bob","Carl","Frank","Mike"};
Stack stringStack;
//對字符串而言,壓入棧的是字符串地址,因此元素長度爲sizeof(char*)
StackNew(&stringStack,sizeof(char*),stringfree);
for(int i=0;i<5;i++)
{
char * copy = strdup(friends[i]); //在heap上分配內存
StackPush(&stringStack,©);
}
char *name;
for(int i=0;i<5;i++)
{
StackPop(&stringStack,&name);
printf("%s\n",name);
free(name); //因爲這塊內存是strdup分配的,使用完畢後必須free
}
StackDispose(&stringStack);
Stack intStack;
StackNew(&intStack,sizeof(int),NULL);
for(int i=0;i<6;i++)
{
StackPush(&intStack,(void *)&intarr[i]);
}
int val;
for(int i=0;i<6;i++)
{
StackPop(&intStack,&val);
printf("%d\n",val);
}
StackDispose(&intStack);
}
**初始化棧
*/
{
s->alloclength = 4;
s->loglength = 0;
s->elemsize = elemsize;
s->freefn = freefn;
s->elems = malloc(4*elemsize);
assert(s->elems != NULL);
}
/*
**釋放棧
*/
void StackDispose(Stack * s)
{
if(s->freefn != NULL) {
for(int i=0;i<s->loglength;i++)
{
void * elem = (char *)s->elems + i * s->elemsize;
s->freefn(elem);
}
}
free(s->elems);
}
**擴展棧
*/
void StackGrow(Stack *s)
{
s->alloclength *= 2;
s->elems = realloc(s->elems,s->alloclength*s->elemsize);
assert(s->elems != NULL);
}
/*
**將元素壓入棧
*/
void StackPush(Stack *s,void * elemaddr)
{
if(s->loglength == s->alloclength)
{
StackGrow(s);
}
void * target = (char *)s->elems + s->loglength * s->elemsize;
memcpy(target,elemaddr,s->elemsize);
s->loglength ++;
}
**彈出棧頂元素
**/
void StackPop(Stack *s,void * elemaddr)
{
s->loglength --;
void * source = (char *)s->elems + s->loglength*s->elemsize;
memcpy(elemaddr,source,s->elemsize);
}
**自定義字符串free函數
*/
void stringfree(void * elem)
{
free(*(char **)elem);
}