C语言写的stack能够
push的时候动态增长。每次扩大一倍:2,4,8,16,32,。
pop的时候还能自动释放地址。
#ifndef _MY_STACK_H_
#define _MY_STACK_H_
#include<stdio.h>
#include<stdlib.h>
#include<string.h> /*memset(void *s, int c, size_t n)*/
#define _DEBUG_
/*type for the stack T ,you can typedef your own*/
typedef unsigned long int T;
struct my_block_st
{
T * ptr;/*point to the allocate memory*/
struct my_block_st * pre;
int index;
size_t block_size;/*size of the current block ...*/
};
typedef struct my_block_st MY_BLOCK;
typedef struct my_block_st * MY_STACK; /*point to the last block*/
void my_stack_init_block(MY_BLOCK **block_ptr)
{
/*initially the size=1, and twice the size each time*/
(*block_ptr)->block_size = (*block_ptr)->block_size*2;
#ifdef _DEBUG_
printf("my_stack_init_block() size=%ld\n",((*block_ptr)->block_size));
#endif
(*block_ptr)->ptr =(T *)malloc(sizeof(T)* ((*block_ptr)->block_size));
#ifdef _DEBUG_
printf("new block add=%p\n",(*block_ptr)->ptr);
#endif
if((*block_ptr)->ptr==NULL)
{
printf("malloc err\n");
exit(EXIT_FAILURE);
}
(*block_ptr)->index=-1;
memset((*block_ptr)->ptr,0,sizeof((*block_ptr)->ptr));
}
void my_stack_init(MY_STACK * s)
{
#ifdef _DEBUG_
printf("my_stack_init()\n");
#endif
*s=(MY_STACK)malloc(sizeof(MY_BLOCK ));
(*s)->block_size=1;
my_stack_init_block(&(*s));
(*s)->pre=NULL;
}
void my_stack_add_block(MY_STACK *s)
{
#ifdef _DEBUG_
printf("my_stack_add_block()\n");
#endif
MY_BLOCK * ptr_block=(MY_BLOCK*)malloc(sizeof(MY_BLOCK));
ptr_block->block_size = (*s)->block_size;/*pass the current size to new block*/
my_stack_init_block(&ptr_block);
MY_BLOCK *tmp_ptr= (*s);
*s=ptr_block;
(*s)->pre=tmp_ptr;
}
int my_block_is_full(MY_BLOCK **s)
{
if(((*s)->index)==((*s)->block_size-1))
{
return 1;
}
else
return 0;
}
int my_block_is_empty(MY_STACK *s)
{
if( (*s)->index==-1)
return 1;
else
return 0;
}
int my_stack_is_empty(MY_STACK *s)
{
if( (*s)->pre==NULL && (*s)-> index==-1)
return 1;
else
return 0;
}
void my_stack_push(MY_STACK *s, T elem)
{
#ifdef _DEBUG_
printf("my_stack_push(%ld)\n",elem);
#endif
if(my_block_is_full(&(*s)))
{
my_stack_add_block(&(*s));
}
( *s)->index++;
*(( *s)->ptr+(*s)->index)=elem;
}
T my_stack_pop(MY_STACK *s)
{
#ifdef _DEBUG_
printf("my_stack_pop()\n");
#endif
if(my_stack_is_empty(&(*s)))
{
printf("err: empty stack cannot pop!\n");
return -1;
}
if(my_block_is_empty(&(*s)))
{
#ifdef _DEBUG_
printf("free %p\n ",( *s)->ptr);
#endif
free((*s)-> ptr);
*s=(*s)->pre;
}
T tmp;
tmp = *(( *s)->ptr+( *s)->index);
--(( *s)->index);
#ifdef _DEBUG_
printf("return %ld\n",tmp);
#endif
return tmp;
}
#endif /*_MY_STACK_H_*/
#include<stdio.h>
#include<stdlib.h>
#include"linked_list_stack/my_linked_list_stack.h"
int main()
{
MY_STACK stack;
my_stack_init(&stack);
my_stack_push(&stack,1);
my_stack_push(&stack,2);
my_stack_push(&stack,3);
my_stack_push(&stack,4);
printf("%ld\n",my_stack_pop(&stack));
printf("%ld\n",my_stack_pop(&stack));
printf("%ld\n",my_stack_pop(&stack));
printf("%ld\n",my_stack_pop(&stack));
return 0;
}