闲来无事,简单用c语言实现了栈的功能,最简单的方法是用数组来实现,但是对内存的运用不够灵活,链表访问起来不够灵活,双向链表倒是可以两者兼容,但是空间使用大了点,对于要存放比较复杂的数据类型的比较大的栈,应该比较合适。也可以用指针数组,操作起来就简单许多。
这里,我用最简单的方法来实现,主要用于学习交流.r若代码中有错误或是不合理之处,欢迎指正。
main.c
#include <stdio.h>
#include "cfilo.h"
int main(void)
{
int i;
struct filo_t* myfilo = filo_create(100);
if ( get_filo_err() < 0 ) {
return 0;
}
printf("myfilo depth %d\n", myfilo->depth);
for (i = 0;i < 102; i++) {
myfilo->push(myfilo, i);
}
myfilo->print(myfilo);
for (i = 0;i < 102; i++) {
printf("myfilo pop %d\n", myfilo->pop(myfilo));
}
myfilo->print(myfilo);
return 0;
}
cfilo.h
/**
* language: c
* data structure: array
* functionality: filo
* author: jason
**/
#ifndef __CFILO_H__
#define __CFILO_H__
#define MAX_FILO_DEPTH 1024u
extern int filo_err;
struct filo_t {
unsigned int depth; //栈的深度
unsigned int free_size; //栈的可用空间
int* pfilo; //栈底指针
int* ftop; //栈顶指针
void (*push)(struct filo_t* p, int num);
int (*pop)(struct filo_t* p);
unsigned int (*get_free_size)(struct filo_t* p);
void(*print)(struct filo_t* p);
};
/**
* @detail push a num to filo
* @arg0 struct filo_t* p: point a filo
* @arg1 int num: will be push to filo
* @return void
**/
void filo_push(struct filo_t* p, int num);
/**
* @detail get the top num in filo
* @arg0 struct filo_t* p: point a filo
* @return the filo's top num
**/
int filo_pop(struct filo_t* p);
/**
* @detail get free size of filo
* @arg0 struct filo_t* p: point a filo
* @return free size of filo
**/
unsigned int filo_get_free_size(struct filo_t* p);
/**
* @detail print all num in filo
* @arg0 struct filo_t* p: point a filo
* @return void
**/
void filo_print(struct filo_t* p);
/**
* @detail create a filo
* @arg0 filo depth you need, not allowed more then MAX_FILO_DEPTH
* @return struct filo_t* p: point a filo
**/
struct filo_t *filo_create(unsigned int depth);
/**
* @detail get filo err code
* @arg void
* @return 0:succeed, <0:failed
**/
int get_filo_err(void);
#endif
cfilo.c
#include <stdio.h>
#include <stdlib.h>
#include "cfilo.h"
int filo_err = 0;
int get_filo_err(void)
{
return filo_err;
}
void filo_push(struct filo_t* p, int num)
{
if (p->free_size == 0) { // filo is full
filo_err = -1;
printf("filo is full!\n");
return;
}
if (p->ftop == NULL) { // filo is empty
p->ftop = p->pfilo;
*(p->ftop) = num;
p->free_size--;
filo_err = 0;
}
else {
p->ftop++;
*(p->ftop) = num;
p->free_size--;
filo_err = 0;
}
}
int filo_pop(struct filo_t* p)
{
if (p->free_size >= p->depth) { // filo is empty
filo_err = -1;
printf("filo is empty!\n");
return 0;
}
int ret;
if (p->ftop == p->pfilo) { // just one num left in filo
ret = *(p->ftop);
p->ftop = NULL;
p->free_size++;
filo_err = 0;
}
else {
ret = *(p->ftop);
p->ftop--;
p->free_size++;
filo_err = 0;
}
return ret;
}
unsigned int filo_get_free_size(struct filo_t* p)
{
filo_err = 0;
return p->free_size;
}
void filo_print(struct filo_t* p)
{
if (p->free_size == p->depth) {
filo_err = -1;
printf("NULL\n");
return;
}
int i;
int *pint = p->pfilo;
printf("<1>: %d\n", *pint);
for (i = 2; i <= (p->depth - p->free_size); i++) {
pint++;
printf("<%d>: %d\n", i, *pint);
}
filo_err = 0;
}
struct filo_t *filo_create(unsigned int depth)
{
if (depth > MAX_FILO_DEPTH) {
filo_err = -1;
printf("the depth out of range!\n");
return NULL;
}
struct filo_t *p = (struct filo_t *)malloc(sizeof(struct filo_t));
p->depth = depth;
p->free_size = depth;
p->ftop = NULL;
p->pfilo = (int *)malloc(sizeof(int) * depth);
p->get_free_size = filo_get_free_size;
p->pop = filo_pop;
p->push = filo_push;
p->print = filo_print;
filo_err = 0;
return p;
}