学习数据结构与算法时实现的栈,参考书目《数据结构与算法分析 C语言描述》,以及在后面会分析我遇到的一个问题。
头文件:Stack.h
/*************************************
*功能:基于链表的栈,栈顶在表头
*作者:JK
*时间:2014--6-24
***************************************/
#ifndef _STACK_HEADER_H_
#define _STACK_HEADER_H_
typedef struct Node* pNode;
typedef pNode Stack;
typedef int ElementType;
struct Node
{
ElementType element;
pNode next;
};
Stack InitStack(void); // 初始化一个栈
void DeleteStack(Stack S);// 删除一个栈
void EmptyStack(Stack S); // 清空一个栈
int IsEmpty(Stack S); // 判断是否是空栈,是返回true,否返回false
void Push(ElementType E, Stack S);// 将元素E压入栈顶
ElementType Pop(Stack S); //弹出栈顶的元素
#endif // _STACK_HEADER_H_
#include <stdlib.h>
#include <stddef.h>
#include <assert.h>
#include <stdio.h>
#include "Stack.h"
Stack InitStack(void)
{
Stack S = (struct Node*)malloc(sizeof(struct Node));
assert(S != NULL);
S->next = NULL;
return S;
}
void EmptyStack(Stack S)
{
assert(S != NULL);
while (S->next != NULL)
{
Pop(S);
}
}
void DeleteStack(Stack S)
{
assert(S != NULL);
pNode p = S->next;
pNode ptmp;
while (p != NULL)
{
ptmp = p->next;
free(p);
p = ptmp;
}
free(S);
}
int IsEmpty(Stack S)
{
assert(S != NULL);
return S->next == NULL;
}
void Push(ElementType E, Stack S)
{
assert(S != NULL);
pNode p = (struct Node*)malloc(sizeof(struct Node));
assert(p != NULL);
p->element = E;
p->next = S->next;
S->next = p;
}
ElementType Pop(Stack S)
{
assert(S != NULL);
if (!IsEmpty(S))
{
ElementType e;
pNode p = S->next;
S->next = p->next;
e = p->element;
free(p);
return e;
}
printf("This Stack is empty!!!\n");
return 0;// 该返回值用来避免提示
}
主程序验证:main.c
#include <stdio.h>
#include <stdlib.h>
#include "Stack.h"
int main()
{
printf("Hello JK!\n");
Stack myStack = InitStack();
// 将0~9压入栈中,9在栈顶
int i = 0;
for (i = 0; i < 10; i++)
{
Push(i, myStack);
}
// 弹出栈顶元素
int a = Pop(myStack);
printf("栈顶元素为:%d \n", a);
DeleteStack(myStack);
return 0;
}
下面分享并分析一下我写的过程中遇到的一个低级的错误。错误的根源在于初始化栈的函数,先看看这个函数:
void InitStack(Stack S)
{
S = (struct Node*)malloc(sizeof(struct Node));
assert(S != NULL);
S->next = NULL;
}
用这个初始化函数初始化一个栈后,在运行Push函数等会操作这个栈的地方都会收到这个错误“Program received signal SIGSEGV, Segmentation fault.”,这个错误的原因一般是指针没初始化,后面在操作这个指针的时候就会出现错误。例如在主函数中:
int main()
{
Stack myStack;
InitStack(myStack);
}
myStack是一个指向节点的指针,且没初始化,即是一个野指针,通过InitStack(myStack)后,myStack还是一个野指针,因为我们直接将这个指针当作实参传给了InitStack函数,这样在调用后是不会改变该实参的,即没有初始化,其实这个道理只要学过C语言就知道的,但我为什么还是会犯这个低级错误呢,根本原因还是我理解的太肤浅了,我以为myStack是一个指针,传入指针是可以改变实参的值的,但其实不是这样的,如果本来实参就是一个指针的话,我们想改变该指针的值的话,就得传入指针的指针,好吧,到里就是这么简单,检查这个错误花了2个小时啊。一定要细致+努力啊。。。