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

在写链栈的时候 和 顺序栈一样 犯了两个错误: 一个是 在 入栈 和 进栈顶时候 忘记 操作 linkstack.len 了,另一个是 在写 stackClear 的时候 犯了一个 低级的内存错误。

这两个问题 都是 粗心造成的。

希望 引以为戒

在做下一个例子:数值转换时,又发现了一个问题:在 stackPop 没有返回 pop元素的值。唉 

欢迎指出代码不足

下面上代码:

// 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->bottom->next;
	while (next != NULL)
	{
		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;
		stack->len++;
	}
	else{
		return E_State_Error;
	}
}

E_State stackPop(linkStack * stack,elelmentType * data){
	if (stack->top != stack->bottom)
	{
		//首先指向第一个元素.
		lStackNode * next = stack->bottom;
		//找到栈顶元素的前驱
		while (next->next != stack->top)
		{
			next = next->next;
		}
		free(stack->top);
		next->next = NULL;
		stack->top = next;
		//忘记加了
		stack->len--;
		return E_State_Ok;
	}
	else{
		return E_State_Error;
	}
}
//从栈底到 栈顶的 遍历
void stackTraverse(linkStack stack){
	//首先指向第一个元素
	lStackNode * next = stack.bottom->next;
	printf("------------遍历开始----------\n");
	while (next != NULL)
	{
		printf("-----------%d----------\n",next->data);
		next = next->next;
	}
	printf("------------遍历结束----------\n");
}

int _tmain(int argc, _TCHAR* argv[])
{
	linkStack stack;
	stackInit(&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;
}

时间: 2024-10-01 06:54:22

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

看数据结构写代码(15)链式队列的实现

队列 和 栈 是 一种 受限制的 线性表.所以 他们的 实现方式 都 相差 无几.之前有过  链栈 和 链式线性表 的 实现经验,自然 写 链队 ,也毫无问题. 下面详细讲解每一段代码 的技术要点 下面是队列节点的数据结构 struct QueueNode { ElementType data; QueueNode * next; }; //生成一个节点 QueueNode * queueNodeMake(ElementType data){ QueueNode * pNode = (Queue

看数据结构写代码(13)栈的应用(四) 迷宫求解

这是一个 用 穷举法 解 迷宫问题 的一个示例,但在 效率 和 解的 最短路径上 就稍显不足了. 这 两个问题,留在 以后 空闲 时刻 解答. 欢迎指出代码不足 下面上代码: // Maze.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <stdlib.h> struct Postion { int x; int y; }; typedef int Direction; struct ElementType { P

看数据结构写代码(32) 赫夫曼树编码以及译码

杂谈:最近有点慵懒,不好不好.好几天都没写代码,原本准备上星期完结 树 这一章节的.现在 又耽误了.哎.要抓紧时间啊. 下面直接上代码: 可以到我的网盘下载源代码,或者 直接拷贝下面的源代码 运行 网盘地址:点击打开链接 // HuffmanTree.cpp : 定义控制台应用程序的入口点. //哈弗曼编码,译码 #include "stdafx.h" #include <stdlib.h> #include <cstring> enum E_State { E

看数据结构写代码(8)顺序栈的实现

欢迎指出 代码 不足之处 在写顺序栈的时候 犯了两个错误,:一个是 对栈的 认识不够清楚,栈顶指针的下一个位置为栈顶元素: 另一个是粗心,在用 realloc 分配内存的时候,忽略了元素本身的大小,只写了 元素的个数. 希望引以为戒. 上代码: // SqStack.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <stdlib.h> #include <cstdio> //故意将值设置的比较小,以测试

看数据结构写代码(10)栈的应用(一) 数值转换

首先 修正上一节 stackPop 代码的错误 E_State stackPop(linkStack * stack,elelmentType * data){ if (stack->top != stack->bottom) { //首先指向第一个元素. lStackNode * next = stack->bottom; <strong><span style="font-size:18px;color:#ff6666;">*data =

看数据结构写代码(44) 判断无向图是否有环路

在 看 严蔚敏的 数据结构 一书 7.5小节时,书上 说" 判断有向图是否存在环要不无向图复杂.对于无向图来说,深度优先遍历过程中遇到回边(即指向已访问过的顶点的边),则必定存在环路". 看的不明白,所以 网上 百度了一下. 有了思路:故写下算法 和思路,以便以后 温故. 思路: 1.一个n个顶点,e条边的 无向图,若 e>= n,必有环路. 2.若 e < n ,需要 深度 遍历,并把 父节点传入 参数中,如果 遇到 一个 节点 被访问过 并且 不是 父节点,那么 就有环

看数据结构写代码(21) 稀疏矩阵(十字链表方式)

写完 这个样例,花费了 我不少时间.大部分时间 花费在 调试 内存问题上. 比如在销毁十字链表时.多次释放节点空间,造成 _CrtIsValidHeapPointer(pUserData) 异常. 当使用malloc 分配 一个 空间时,会将这个空间的起始地址和长度 加到一个链表中去.free(p)的时候 ,会从 链表里 查找 是否 有 这个地址空间,找到了就将这个节点从链表中删除._CrtIsValidHeapPointer(pUserData)  这个函数 正是 检查 这个空间是否 在链表里

看数据结构写代码(67) 置换 _ 选择排序(完结篇)

杂谈: 严蔚敏版<数据结构(C语言版)> 一书 终于看完了.这是 一个完结,也是 一个新的开端.<算法导论> 已到手. 置换选择排序的思想 是 将 归并段 尽量 变的 更大,而不是根据 内存 大小 限制在 固定的 大小. 这样 可以 利用赫夫曼树 来 进行 最优归并树,从而 使 外存 读写次数 最少. 下面给出 具体 代码:欢迎指出代码不足. // Replace_Selcetion.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h&q

看数据结构写代码(50)伙伴系统

伙伴系统 是一种 只 可以 分配 2的 幂次方 个 空间的 ,回收 内存 时 只 合并 "伙伴空间" 的一种 动态内存管理方式. 例如 一个 空间 大小 为 64 的 内存,伙伴 系统 为 这 64 的内存  建立 一组 双向循环 链表,分别 管理着  2的 0 次方,2的1 次方幂,2的 2 次方幂...2的6次方幂的 可用空间. 即使 我们 只想分配 一个 大小 为3的 空间,系统 却 只能 返回 一个 内存 大小 为 4(2的2次方)的 一个空间. 系统 在 初始化的 时候 ,并