当前位置:主页 > c/c++教程 > C语言顺序栈 链栈

C语言中顺序栈和链栈的定义和使用详解

发布:2023-03-06 09:30:01 59


本站精选了一篇相关的编程文章,网友曾翰音根据主题投稿了本篇教程内容,涉及到C语言、顺序栈、链栈、C语言、顺序栈、C语言、链栈、C语言顺序栈 链栈相关内容,已被608网友关注,下面的电子资料对本篇知识点有更加详尽的解释。

C语言顺序栈 链栈

栈的基本内容

无论是我们接下来要讲的栈还是后面要讲到的队列,他们虽然在名字上不同于我们之前的顺序表或者单链表,但是它们本质也是线性表,只是在基本操作上没有表那么“自由”。比如:栈只能从栈顶进行插入和删除,而队列只能从对头进行删除,队尾进行插入。

举例:

叠放在一起的盘子,当想要加入新的盘子时,只能在底部或者尾部加入,删除同样也是。

空栈:

栈顶和栈底:

顺序栈

既然上文都说到“栈”和“队列”都是一种“特殊的”线性表”,那么顺序栈,顾名思义就是按照顺序存储的栈。

定义

既然是顺序存储的,那么我们依然可以和顺序表相类似,采用数组去存放!

typedef struct {
	int data[size];
	int top;//栈顶指针
}seqstack;//seqstack为结构体类型

入栈操作

对于顺序表的插入操作,我们在栈中叫做“入栈”,由于栈的特殊性,只能在栈顶进行操作。

需要提醒的是:一定是栈顶指针先进行移动,再将新插入的元素赋给栈顶空间。也就是说S.top = S.top + 1;S.data[S.top] = x;的顺序不能发生颠倒。

void Pushstack(seqstack& S)
{
	if (S.top == size)
		printf("栈满,拒绝元素继续入栈!");
	else {
		printf("请依次输入你要入栈的元素:\n");
		int x,i;
		for (i = 0; i < size; i++) {
			scanf("%d", &x);
			S.top = S.top + 1;
			S.data[S.top] = x;
			printf("入栈成功!\n");
		}
	}
}

举例:

出栈

虽然是“出栈”,但是如果后续没有入栈操作对出栈位置进行数据覆盖的话,其实出栈并不是真正意义上的“消失”,只是在逻辑上上被删除了,其实给出下标地址,依然可以找到该元素。**return S.data[S.top];**就是将该元素的值返回,以便下次能够快速找到。

int  PopStack(seqstack& S) {
	if (S.top == -1) {
		printf("栈为空,没有元素输出!");
	}
	{
		printf("当前栈顶元素为:");
		 return S.data[S.top];
		 S.top = S.top - 1;
	}
}

关于顺序栈的其他操作都是比较简单的,这里就不一一进行讲解了,需要注意的事项我会在下面的完整代码中注释出来!

顺序栈的缺点

栈的大小不可发生变化。

出栈顺序的计算方法

如上图所示:

进栈顺序为a->b->c->d->e,则对应的出栈顺序为e->d->c->b->a

但有时候出栈和进栈是穿插进行的:

举例:

这种进栈出栈穿插的方式有很多种。

由此,我们可以得出一个结论:

链栈

既然上文都说到“栈”和“队列”都是一种“特殊的”线性表”,那么链栈,顾名思义就是按照链式存储的栈。

基本实现方法和单链表相同,这里就不一一进行讲解了,需要注意的事项我会在下面的完整代码中注释出来!

链栈完整代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#define size 5
typedef struct LinkNode {
	int data;
	struct LinkNode* next;
}Linkstack;

//初始化
void Iniststack(Linkstack *L) {
	L= (LinkNode*)malloc(sizeof(LinkNode));
	if (!L->data) {
		printf("申请失败");
	}
	else
	{
		L->data = 0;
		L->next = NULL;
	}
}
//入栈
void Pushstack(Linkstack *L) {
	
	int e,x;
	printf("请输入你要创建的链栈长度:");
	scanf("%d", &x);
	printf("请输入你要入栈的元素:\n");
	for (int i = 0; i < x; i++) {
		LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode));
		scanf("%d", &e);
		s->data = e;
		s->next = L->next;
		L->next = s;
	}	
}
//出栈
int  Popstack(Linkstack* L)
{
	LinkNode* s= L->next;
	s->data = L->data;
	L->next = s->next;
	return s->data;
}
//读取栈顶元素
int  Getstack(Linkstack* L) {
	if (!L->data)
	{
		printf("栈为空!");
	}
	else {
		int e = L->next->data;
		return e;
	}
}
//输出栈中元素
void Printsatck(Linkstack* L) {
	if (!L->data)
	{
		printf("栈为空!");
	}
	else {
		LinkNode* p;
		p = L;
		printf("栈中元素如下:");
		while (p)
		{
			p = p->next;
			printf("%d", p->data);
		}
	}
}
int main() {
	Linkstack L;
	Iniststack(&L);
	Pushstack(&L);
	Popstack(&L);
	Getstack(&L);
	Printsatck(&L);
}

输出:

顺序栈完整代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#define size 5
typedef struct {
	int data[size];
	int top;
}seqstack;
//初始化操作
void InistStack(seqstack &S) {
	S.top = -1;
}
//判空操作
void IsEmpty(seqstack& S)
{
	if (S.top == -1)
		printf("目前栈为空!\n");
}
//入栈操作
void Pushstack(seqstack& S)
{
	if (S.top == size)
		printf("栈满,拒绝元素继续入栈!");
	else {
		printf("请依次输入你要入栈的元素:\n");
		int x,i;
		for (i = 0; i < size; i++) {
			scanf("%d", &x);
			S.top = S.top + 1;
			S.data[S.top] = x;
			printf("入栈成功!\n");
		}
	}
}
//读取栈顶元素
void Getstack(seqstack& S) {
	if (S.top == -1) {
		printf("栈为空,没有元素输出!");
	}
	{
		printf("当前栈顶元素为:");
		printf("%d\n", S.data[S.top]);
	}
}
//输出栈中元素
void Printstack(seqstack& S) {
	if (S.top == -1) {
		printf("栈为空,没有元素输出!");
	}
	else {
		printf("栈中元素如下:");
		for (int i = 0; i < size; i++) {
			printf("%d", S.data[i]);
		}
		printf("\n");
	}
}
//出栈
int  PopStack(seqstack& S) {
	if (S.top == -1) {
		printf("栈为空,没有元素输出!");
	}
	{
		printf("当前栈顶元素为:");
		 return S.data[S.top];
		 S.top = S.top - 1;
	}
}
//删除栈顶元素

int Deletestack(seqstack& S) {
	if (S.top == -1) {
		printf("栈为空!\n");
	}
	else
	{
		int e;
		for (int i = 0; i < size; i++) {
			e = S.data[S.top];
			S.top = S.top - 1;
			return e;
		}
		printf("所有元素已被删除!\n");
	}
}
//清栈
void Clearstack(seqstack& S) {
	S.top = -1;
	printf("栈已经被清空!\n");
}
int main() {
	seqstack S;
	int x;
	InistStack(S);
	IsEmpty(S);
	Pushstack(S);
	Getstack(S);
	Printstack(S);
	/*x=PopStack(S);*/
	Deletestack(S);
	Clearstack(S);
	Printstack(S);
}

输出:

以上就是C语言中顺序栈和链栈的定义和使用详解的详细内容,更多关于C语言顺序栈 链栈的资料请关注码农之家其它相关文章!


参考资料

相关文章

  • 详解C语言内核字符串拷贝与比较

    发布:2023-03-03

    本文将探索一下字符串的拷贝与比较,与应用层不同内核字符串拷贝与比较也需要使用内核专用的API函数,字符串的拷贝往往伴随有内核内存分配,我们将首先简单介绍内核如何分配堆空间,然后再以此为契机简介字符串的拷贝与比较


  • C语言 ffmpeg与sdl实现播放视频同时同步时钟详解

    发布:2023-03-02

    使用ffmpeg和sdl实现播放视频后,需要再实现时钟同步才能正常的播放视频,尤其是有音频的情况,我们通常需要将视频同步到音频来确保音画同步


  • C语言驱动开发之通过ReadFile与内核层通信

    发布:2023-03-02

    驱动与应用程序的通信是非常有必要的,内核中执行代码后需要将其动态显示给应用层。为了实现内核与应用层数据交互则必须有通信的方法,微软为我们提供了三种通信方式,本文先来介绍通过ReadFile系列函数实现的通信模式


  • C语言数据结构与算法之队列的实现详解

    发布:2023-03-04

    队列只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)的原则。本文将通过实例详细说说队列的实现,需要的可以学习一下


  • 用C语言求解第N项斐波那契数列问题

    发布:2023-03-13

    这篇文章主要介绍了用C语言求解第N项斐波那契数列问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教


  • C语言实现绘制绕线画的示例代码

    发布:2023-03-09

    绕线画简单点来说,就是在木板上钉一圈钉子,通过绕线进行构图,最终呈现出一幅图像。本文将用C语言实现这一效果,感兴趣的小伙伴可以尝试一下


  • C语言数据结构之双链表&循环链表&静态链表详解

    发布:2023-03-02

    这篇文章主要为大家详细介绍了C语言数据结构中双链表&循环链表&静态链表的原理与使用,文中的示例代码讲解详细,感兴趣的可以了解一下


  • C语言实现扫雷小游戏的示例代码

    发布:2023-03-06

    这篇文中主要为大家详细介绍了如何利用C语言实现经典的扫雷小游戏。扫雷小游戏主要是利用字符数组、循环语句和函数实现,感兴趣的小伙伴可以了解一下


网友讨论