这篇文章更新了数据结构中栈的内容。
在第一次写这个内容的时候,又出现了一大堆内存访问冲突。
我本以为我对指针已经有深刻的了解了,经过这次我发现我还是有很多的不足。
还是没有完全理解指针。
所以对我的代码又进行了一次重构。
后来就好了,现在我来分享一下我的代码。
本文中将会看到很多int型数据我也将它称为指针。
因为我定义了一个动态内存分配的Elemtype* data,这些我称为指针的int型数据是相当于指针数组的下标。
可以通过这个下标来找到我需要的指针。
头文件“栈.h”,存放了栈的定义和它相关的函数。
//蔚明
//栈.h
#ifndef 栈_H
#define 栈_H
#pragma warning(disable:4996)//这两段声明可以使scanf()在VS中正常使用
#pragma warning(disable:6031)
#include "stdio.h"
#include "stdlib.h"
#define OK 0
#define FAIL -1
typedef char Elemtype;
typedef struct Sqstack
{
Elemtype* data;
int top, stack_maxsize;
}Sqstack;
Sqstack Init_Stack(int maxsize);//初始化一个栈。
void Clear_Stack(Sqstack* S); //清空一个栈。
void Destroy_Stack(Sqstack* S); //销毁一个栈。
int Stack_Empty(Sqstack* S); //判断判断是否为空栈。
int Stack_Full(Sqstack* S); //判断判断是否为空栈。
int Stack_Length(Sqstack* S); //计算栈的长度。
int Get_Top_Stack(Sqstack* S, Elemtype* e); //仅读取不改变栈顶元素。
int Push_Stack(Sqstack* S, Elemtype e); //压入栈顶元素。
Elemtype Pop_Stack(Sqstack* S); //d出栈顶元素。
int Stack_base_Traverse(Sqstack* S); //从栈底向栈顶对每个元素进行访问。
int Stack_top_Traverse(Sqstack* S); //从栈底向栈顶对每个元素进行访问。
#endif
下面是“栈.c”主要是栈的各种函数的定义
//蔚明
//栈.c
#include "栈.h"
Sqstack Init_Stack(int maxsize)//初始化一个栈。
{
Sqstack S={NULL,0,0};
S.stack_maxsize = maxsize;//确定最大容量
if ((S.data = (Elemtype*)malloc(S.stack_maxsize * sizeof(Elemtype))) == NULL)//分配内存
{
puts("内存分配失败!!!");
exit(1);
}
else
{
S.top =0;//栈顶指向栈底。
return S;
}
}
void Clear_Stack(Sqstack* S) //清空一个栈。
{
for (int i = 0; Stack_Empty(S) != OK; i++)//在栈为空前d出所有元素即可把栈置空
{
Pop_Stack(S);
}
}
void Destroy_Stack(Sqstack* S) //销毁一个栈。
{
free(S->data);//释放为栈分配的内存
}
int Stack_Empty(Sqstack* S) //判断判断是否为空栈。
{
if (S->top == 0) return OK;//栈顶指针指向栈第时为空栈
else return FAIL;
}
int Stack_Full(Sqstack* S) //判断判断是否为满。
{
if (Stack_Length(S) == S->stack_maxsize) return OK;//当达到栈的最大容量时即栈满。
else return FAIL;
}
int Stack_Length(Sqstack* S) //计算栈的长度。
{
return S->top;//栈顶指针的数字即为栈的长度。
}
int Get_Top_Stack(Sqstack* S, Elemtype *e) //仅读取不改变栈顶元素。
{
if (Stack_Empty(S) == OK) return FAIL;
else
{
*e = S->data[S->top-1];//返回栈顶指针指向的元素,因为栈由0开始计数所以减一,原理和数组类似。
return OK;
}
}
int Push_Stack(Sqstack* S, Elemtype e) //压入栈顶元素。
{
if (Stack_Full(S) == OK)
{
puts("栈满无法压入");
return FAIL;
}
else
{
S->data[S->top] = e;//把传进来的元素e赋给栈顶
S->top++;//栈顶指针加一
return OK;
}
}
Elemtype Pop_Stack(Sqstack* S) //d出栈顶元素。
{
if(Stack_Empty(S)==OK) exit(1);
Elemtype e = S->data[S->top-- - 1];//把栈顶元素赋给要返回的e后栈顶指针减一。
return e;
}
int Stack_base_Traverse(Sqstack* S) //从栈底向栈顶对每个元素进行访问。
{
if (Stack_Empty(S) == OK)//判断栈是否为空,此 *** 作可避免内存冲突
{
puts("这个栈是空栈!");
return FAIL;
}
else
{
int read = 0;//定义读取栈中元素的指针
puts("从栈底向栈顶对每个元素进行访问。
");
for (read = 0; read < S->top; read++)//从栈底向栈顶对每个元素进行访问。
printf("%c\t", S->data[read]);
putchar('\n');
return OK;
}
}
int Stack_top_Traverse(Sqstack* S) //从栈底向栈顶对每个元素进行访问。
{
if (Stack_Empty(S) == OK)//判断栈是否为空,此 *** 作可避免内存冲突
{
puts("这个栈是空栈!");
return FAIL;
}
else
{
int read = 0;//定义读取栈中元素的指针
puts("从栈顶向栈底对每个元素进行访问。
");
for (read = S->top - 1; read >= 0; read--)//从栈顶向栈底对每个元素进行访问。
printf("%c\t", S->data[read]);
putchar('\n');
return OK;
}
}
下面是"main.c",主要是验证“栈.c”中函数的使用是否正常
//蔚明
//main.c
#include "栈.h"
#include
void main()
{
/*验证Init_Stack(int maxsize),
Push_Stack(Sqstack * S, Elemtype e),
Stack_Full(Sqstack * S)*/
puts("验证Init_Stack(int maxsize),\nPush_Stack(Sqstack * S, Elemtype e),\nStack_Full(Sqstack * S)\n\n");
Sqstack S = Init_Stack(10);
Elemtype e = '#',ch[15];
puts("请输入要压入栈中的字符串\n");
scanf("%s", ch);
for (int i=0;i < strlen(ch); i++)
{
printf("正在压入第%d个元素\n", i);
e = ch[i];
if (Push_Stack(&S, e) != OK) puts("失败!!!");
}
/*验证Stack_base_Traverse(Sqstack * S),
Stack_top_Traverse(Sqstack * S),
Stack_Length(Sqstack* S),
Get_Top_Stack(Sqstack * S, Elemtype * e)*/
puts("验证Stack_base_Traverse(Sqstack * S),\nStack_top_Traverse(Sqstack * S),\nStack_Length(Sqstack * S),\nGet_Top_Stack(Sqstack * S, Elemtype * e)\n");
Get_Top_Stack(&S, &e);
printf("栈顶元素为%c\n", e);
printf("栈的长度为%d\n", Stack_Length(&S));
Stack_base_Traverse(&S);
Stack_top_Traverse(&S);
//验证Pop_Stack(Sqstack* S)
puts("验证Pop_Stack(Sqstack* S)\n\n");
for (int i = 0; Stack_Empty(&S) != OK; i++)
{
printf("第%d个元素:%c\n", i + 1, Pop_Stack(&S));
}
//由于刚才弹出了所有元素,现重新为栈赋值。
puts("由于刚才d出了所有元素,现重新为栈赋值。
\n");
puts("请输入要压入栈中的字符串");
scanf("%s", ch);
for (int i = 0; i < strlen(ch); i++)
{
printf("正在压入第%d个元素\n", i);
e = ch[i];
if (Push_Stack(&S, e) != OK) puts("失败!!!");
}
//赋值后
puts("赋值后\n");
Stack_top_Traverse(&S);
//验证Clear_Stack(Sqstack* S)
puts("验证Clear_Stack(Sqstack* S)\n");
Clear_Stack(&S);
puts("执行“Clear_Stack(&S);”后:\n");
Stack_top_Traverse(&S);
//释放栈的内存,验证Destroy_Stack(Sqstack * S)
puts("释放栈的内存,验证Destroy_Stack(Sqstack * S)");
Destroy_Stack(&S);
getchar();
}
运行结果如下:
经过验证都可以正常使用。
我学C语言大概半年,编写代码的手段可能比较稚嫩,如果写的比较垃圾,欢迎前辈指正。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)