C语言实现栈的基本 *** 作(超详细注释)

C语言实现栈的基本 *** 作(超详细注释),第1张

这篇文章更新了数据结构中栈的内容。


在第一次写这个内容的时候,又出现了一大堆内存访问冲突。


我本以为我对指针已经有深刻的了解了,经过这次我发现我还是有很多的不足。


还是没有完全理解指针。


所以对我的代码又进行了一次重构。


后来就好了,现在我来分享一下我的代码。


本文中将会看到很多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语言大概半年,编写代码的手段可能比较稚嫩,如果写的比较垃圾,欢迎前辈指正。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/562866.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-02
下一篇 2022-04-02

发表评论

登录后才能评论

评论列表(0条)

保存