链栈(栈的链式储存结构)

      链栈的操作大部分与单链表相似,只是在插入和删除上,特殊一些。

      栈顶在链表的位置:栈只是用栈顶来进行插入和删除操作,单链表有头指针,栈顶指针也是必须的,因此可以将它们两个合二为一,所以最好的把栈顶放在单链表的头部。

      由于已经有栈顶在头部,所以单链表中的头结点便失去了意义,通常对于链栈来说,是不需要头结点的

      1.我们首先定义链栈结构:

struct StackNode//定义表格
{
	SElemType data;//数据域
	StackNode* next;//指针域
};
typedef struct StackNode* LinkStackPtr;//表格指针


struct LinkStack
{
	LinkStackPtr top;//栈顶指针
	int count;//记录栈中的数据个数
};

     

      2.创建空栈(由于不需要头结点,也不像顺序栈一样要一开始开辟出总空间,所以空栈的创建很简单,只需要建立栈顶指针并初始化,再初始化用于计数的count即可)

int InitStack(LinkStack* S)//创建一个空栈
{
	
	S->top = NULL;
	S->count = 0;
	return 1;
}

     

      3.判断栈是否为空(链栈一般是不会出现栈满的情况的,所以我们只需要有判断链栈是否为空的函数即可)

int StackEmpty(LinkStack* S)//判断栈是否为空
{
	if (S->count == 0)
		return 0;
	return 1;
}

      当用于计数的count为0就说明此时链栈为空

     

      4.进栈操作(链栈与链表主要的不同之处)

void Push(LinkStack* S, SElemType e)//进栈操作
{
	LinkStackPtr g = new StackNode;//创建新的结点
	g->data = e;//向新结点中输入数据
	g->next = S->top;
	S->top = g;
	S->count++;
}

      指针top是始终指向栈顶的所以当创建的新结点作为新的栈顶后,要让top指向它

      5.输出栈中的内容(不对栈进行任何改变,只是利用while循环将其中的内容展示出来)

void printStack(LinkStack* S)//输出栈中的内容
{
	int i;
	LinkStackPtr p=S->top;//用来遍历栈
	if (S->count==0)
	{
		cout << "栈为空" << endl;
		return;
	}
	while (p)
	{
		cout << p->data << " ";
		p = p->next;
	}
	cout << endl;
}

      创建一个表格指针p初始化指向栈顶以后,便重栈顶开始遍历整个链栈

      6.出栈操作(链栈与链表主要的不同之处)

void Pop(LinkStack* S, SElemType* e)//出栈操作
{

	LinkStackPtr p;//定义一个表格指针来指向待删除的栈顶的位置
	p = S->top;
	*e = S->top->data;//将要出栈的值返回到指针e指向的空间,便于知道哪一个值进行了出栈
	S->top = S->top->next;//指向栈顶的指针top向下移
	delete(p);
	S->count--;
}

      定义SElemType* e指针是用于记录删除的数据内容,便于让用户知道删除了什么,与出栈操作关系不大。

      7.清空栈(我们用new开辟的空间是在堆区中的,必须要我们自己将内存释放,要不然会造成内存泄漏)(注意new与delete    malloc与free才是最佳拍档不能混用)

void ClearStack(LinkStack* S)//清空栈
{
	int i;
	LinkStackPtr p, q;//定义表格指针p,q来交替遍历
	p = S->top;
	while (p)
	{
		q = p->next;
		delete(p);
		p = q;
	}
	S->top = NULL;
	S->count = 0;
	cout << "栈清空完毕" << endl;
}

      清空栈记得将计数变量count变为0,栈顶指针指向空。

全部代码展示:

头文件FUNC.h

#pragma once
#include<iostream>
using namespace std;
#include<ctime>;
#define SElemType int

struct StackNode//定义表格
{
	SElemType data;//数据域
	StackNode* next;//指针域
};
typedef struct StackNode* LinkStackPtr;//表格指针


struct LinkStack
{
	LinkStackPtr top;//栈顶指针
	int count;//记录栈中的数据个数
};


int InitStack(LinkStack* S);//创建一个空栈

int StackEmpty(LinkStack* S);//判断栈是否为空

void Push(LinkStack* S, SElemType e);//进栈操作

void printStack(LinkStack* S);//输出栈中的内容

void Pop(LinkStack* S, SElemType* e);//出栈操作

void ClearStack(LinkStack* S);//清空栈

源文件FUNC.cpp

#include"FUNC.h"
int InitStack(LinkStack* S)//创建一个空栈
{
	
	S->top = NULL;
	S->count = 0;
	return 1;
}


int StackEmpty(LinkStack* S)//判断栈是否为空
{
	if (S->count == 0)
		return 0;
	return 1;
}


void Push(LinkStack* S, SElemType e)//进栈操作
{
	LinkStackPtr g = new StackNode;//创建新的结点
	g->data = e;//向新结点中输入数据
	g->next = S->top;
	S->top = g;
	S->count++;
}


void printStack(LinkStack* S)//输出栈中的内容
{
	int i;
	LinkStackPtr p=S->top;//用来遍历栈
	if (S->count==0)
	{
		cout << "栈为空" << endl;
		return;
	}
	while (p)
	{
		cout << p->data << " ";
		p = p->next;
	}
	cout << endl;
}


void Pop(LinkStack* S, SElemType* e)//出栈操作
{

	LinkStackPtr p;//定义一个表格指针来指向待删除的栈顶的位置
	p = S->top;
	*e = S->top->data;//将要出栈的值返回到指针e指向的空间,便于知道哪一个值进行了出栈
	S->top = S->top->next;//指向栈顶的指针top向下移
	delete(p);
	S->count--;
}


void ClearStack(LinkStack* S)//清空栈
{
	int i;
	LinkStackPtr p, q;//定义表格指针p,q来交替遍历
	p = S->top;
	while (p)
	{
		q = p->next;
		delete(p);
		p = q;
	}
	S->top = NULL;
	S->count = 0;
	cout << "栈清空完毕" << endl;
}

源文件text.cpp

#include"FUNC.h"
int main()
{
	LinkStack S;//定义栈S
	if (InitStack(&S) == 1)
	{
		cout << "空栈创建成功" << endl;
	}
	int DBD = 1;
	int n;
	srand((unsigned int)time(NULL));//添加随机数种子
	cout << "欢迎来到链栈的调试" << endl;
	while (DBD)
	{
		system("pause");
		system("cls");
		cout << "1.输出栈的内容  2.进栈操作  3.出栈操作  4.退出程序  5.清空栈" << endl;
		cin >> n;
		switch (n)
		{
		case 1:
		{
			printStack(&S);
			break;
		}
		case 2:
		{
			SElemType e;
			e = rand() % 100 + 1;//随机产生1-100的数到e中(e用来临时储存待插入栈的数据)
			cout << "输入的数据为:" << e << endl;
			Push(&S, e);
			break;
		}
		case 3:
		{
			if (StackEmpty(&S) == 1)
			{
				SElemType e;
				Pop(&S, &e);
				cout << "值:" << e << "已出栈" << endl;
				break;
			}
			else
			{
				cout << "栈为空" << endl;
				break;
			}
		}
		case 4:
		{
			DBD = 0;
			cout << "谢谢使用" << endl;
			break;
		}
		case 5:
		{
			if (StackEmpty(&S) == 1)
			{
				ClearStack(&S);
				break;
			}
			else
			{
				cout << "栈为空" << endl;
				break;
			}
		}
		default:
		{
			cout << "输入不合法" << endl;
			break;
		}
		}
	}
	return 0;
}

链栈完成。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小林想被监督学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值