在写链栈的时候 和 顺序栈一样 犯了两个错误: 一个是 在 入栈 和 进栈顶时候 忘记 操作 linkstack.len 了,另一个是 在写 stackClear 的时候 犯了一个 低级的内存错误。
这两个问题 都是 粗心造成的。
希望 引以为戒
在做下一个例子 :《进制转换》时,又发现了一个问题:在 stackPop 没有返回 pop元素的值。唉
最近 在 看 数据结构视频中 发现了 一个 非常 严重的错误,是结构性的错误。错误的以为 链栈 和 线性表 是一致的。其实 他们的 结构 是有一些差别的。
链栈的 后继 指针 和 线性表的 后继 指针的 指向 是 相反的,简单的说 链栈的 后继 指针 指向 前驱。这样 在 退栈的时候,不需要 循环栈,只需 stack->top = stack->top->next 就 行了,这样 时间 复杂度 为 O(1),而 如果 不这样做,时间复杂度为 O(n) ,n为栈长。真是 后知后觉。1.当你认为你懂了的时候,可能 你还不完全懂,所以要谦虚,要低调。2.温故而知新,是个好想法。
欢迎指出代码不足
下面上代码:
// LinkStack.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdlib.h>
typedef int elelmentType;
enum E_State
{
E_State_Error = 0,
E_State_Ok = 1,
};
//链表节点node
struct lStackNode
{
elelmentType data;
lStackNode * next;//跟线性表的后继的概念不一样
};
//链栈
struct linkStack
{
lStackNode * bottom;//栈底
lStackNode * top;//栈顶
int len;
};
lStackNode * makeNode(elelmentType data){
lStackNode * pNode = (lStackNode *)malloc(sizeof(lStackNode));
if (pNode != NULL)
{
pNode->data = data;
pNode->next = NULL;
}
return pNode;
}
E_State stackInit(linkStack * lStack){
//分配头节点
lStackNode * pNode = (lStackNode *) malloc(sizeof(lStackNode));
if (pNode == NULL)
{
return E_State_Error;
}
pNode->next = NULL;
//栈顶和栈底指向同一个节点时为空.
lStack->bottom = lStack->top = pNode;
lStack->len = 0;
return E_State_Ok;
}
void stackClear(linkStack * stack){
lStackNode * next = stack->top;
while (next != stack->bottom)
{
lStackNode * freeNode = next;
/*又粗心了。。。
free(freeNode);
next = next->next;*/
next = next->next;
free(freeNode);
}
stack->top = stack->bottom;
stack->len = 0;
}
void stackDestory(linkStack * stack){
stackClear(stack);
free(stack->top);
stack->top = stack->bottom = NULL;
}
E_State stackGetTop(linkStack stack,elelmentType * topData){
//链表的栈顶 指向 栈顶元素
if (stack.top != stack.bottom)
{
*topData = stack.top->data;
return E_State_Ok;
}
else
{
return E_State_Error;
}
}
int stackLen(linkStack stack){
return stack.len;
}
bool stackEmpty(linkStack stack){
return stack.top == stack.bottom ? true : false;
}
E_State stackPush(linkStack * stack,elelmentType data){
lStackNode * node = makeNode(data);
if (node != NULL)
{
/*stack->top->next = node;
stack->top = node;*/
node->next = stack->top;
stack->top = node;
stack->len++;
return E_State_Ok;
}
else{
return E_State_Error;
}
}
E_State stackPop(linkStack * stack,elelmentType * data){
if (stack->top != stack->bottom)
{
/*//首先指向第一个元素.
lStackNode * next = stack->bottom;
//修复错误。。忘记写了
*data = stack->top->data;
//找到栈顶元素的前驱
while (next->next != stack->top)
{
next = next->next;
}*/
lStackNode * freeNode = stack->top;
stack->top = stack->top->next;
free(freeNode);
//忘记加了
stack->len--;
return E_State_Ok;
}
else{
return E_State_Error;
}
}
//从栈顶到 栈底的 遍历
void stackTraverse(linkStack stack){
//首先指向第一个元素
lStackNode * next = stack.top;
printf("------------遍历开始----------\n");
while (next != stack.bottom)
{
printf("-----------%d----------\n",next->data);
next = next->next;
}
printf("------------遍历结束----------\n");
}
int _tmain(int argc, _TCHAR* argv[])
{
linkStack stack;
stackInit(&stack);
stackPush(&stack,10);
stackClear(&stack);
for (int i = 1; i < 13; i++)
{
stackPush(&stack,i);
}
elelmentType top;
stackPop(&stack,&top);
stackPop(&stack,&top);
stackTraverse(stack);
stackGetTop(stack,&top);
char * s = stackEmpty(stack) ? "true" : "false";
printf("栈长 :%d,栈顶元素为 :%d,栈是否为空:%s",stackLen(stack),top,s);
stackDestory(&stack);
return 0;
}