看数据结构写代码(9)链栈的实现

在写链栈的时候 和 顺序栈一样 犯了两个错误: 一个是 在 入栈 和 进栈顶时候 忘记 操作 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;
}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值