栈也是一种很重要的数据结构,具备“先进后出”的特点。程序中的函数调用以及递归都涉及栈这一数据结构,熟悉栈有利于我们更好地理解函数的调用过程(主要是形参,局部变量以及函数的返回值)和递归算法的实现过程
1、栈的数据节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| typedef struct _Stack { int *pData; int size; int top; }Stack; 2、创建指定容量的栈 Stack* createStack(int MaxElements) { Stack *pStack = NULL; if (0 == MaxElements) return NULL;
pStack = (Stack *)malloc(sizeof(Stack)); assert(NULL != pStack); memset(pStack, 0, sizeof(Stack)); pStack->pData = (int *)malloc(sizeof(int)* MaxElements); if (NULL == pStack->pData) { free(pStack); pStack = NULL; } memset(pStack->pData, 0, sizeof(int)* MaxElements); pStack->size = MaxElements; pStack->top = -1; return pStack;
}
|
3、判断栈满,栈空
1 2 3 4 5 6 7 8 9
| bool isFull(Stack *pStack) { return (pStack->size == (pStack->top + 1)); }
bool isEmpty(Stack *pStack) { return (-1 == pStack->top); }
|
4、压栈操作
异常情况;
1) 栈不存在
2) 栈已满
1 2 3 4 5 6 7 8 9 10 11 12
| bool push(Stack *pStack, int value) { if (NULL == pStack) return false;
if (isFull(pStack)) return false; pStack->pData[++pStack->top] = value; return true;
}
|
5、出栈操作
异常情况:
1) 栈不存在
2) 栈为空
1 2 3 4 5 6 7 8 9 10 11 12
| bool pop(Stack *pStack, int *value) { if (NULL == pStack) return false;
if (isEmpty(pStack)) return false; *value = pStack->pData[pStack->top return true;
}
|
6、释放栈空间
类似于C++中的基类,继承类析构,先释放数据空间,再释放栈节点空间。
这里也可传递一级指针,同样可以释放栈空间内存,但是不能把栈指针设置为NULL,打印数据时也就不能进行判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| bool freeStack(Stack **ppStack) { if (NULL == *ppStack) return false;
if (NULL == (*ppStack)->pData) { free(*ppStack); *ppStack = NULL; return true; } free((*ppStack)->pData); free(*ppStack); *ppStack = NULL; return true;
}
|
7、打印栈数据
1 2 3 4 5 6 7 8 9 10 11
| void printStack(Stack *pStack) { if (pStack) { int num = pStack->top;
while (-1 != num) printf("%d\n", pStack->pData[num--]); }
}
|
这里创建的栈数据结构实质就是开辟一个指定容量的数组空间,然后设置栈顶位置时刻指向栈顶元素