C语言数据结构-栈的知识归纳以及栈的应用


栈是一种常见的数据结构,它的特点是先进后出(Last In First Out,LIFO),类似于我们平时用的一个栈子,一次只能放一个物品,后放的物品会覆盖之前放的物品。在计算机中,栈是一种非常重要的数据结构,用来实现函数调用、表达式求值等功能。
C语言中,栈可以用数组实现,也可以用链表实现。下面我们分别介绍一下这两种实现方法。

一. 用顺序存储结构实现栈

用顺序存储结构实现栈的方法比较简单,只需要定义一个数组和一个变量来记录栈顶的位置即可。具体实现如下:

#define MAXSIZE 100 //定义栈的最大长度
typedef struct {
    int data[MAXSIZE]; //用数组存储栈中元素
    int top; //记录栈顶的位置
} Stack;

初始化栈
void InitStack(Stack *s) {
    s->top = -1;
}
//判断栈是否为空
int IsEmpty(Stack *s) {
    return s->top == -1;
}
//判断栈是否已满
int IsFull(Stack *s) {
    return s->top == MAXSIZE-1;
}
//入栈操作
int Push(Stack *s, int x) {
    if (IsFull(s)) {
        printf("Stack is full!\n");
        return 0;
    }
    s->data[++s->top] = x;
    return 1;
}
//出栈操作
int Pop(Stack *s, int *x) {
    if (IsEmpty(s)) {
        printf("Stack is empty!\n");
        return 0;
    }
    *x = s->data[s->top--];
    return 1;
}
//获取栈顶元素
int GetTop(Stack *s, int *x) {
    if (IsEmpty(s)) {
        printf("Stack is empty!\n");
        return 0;
    }
    *x = s->data[s->top];
    return 1;
}

二. 用链表实现栈

用链表实现栈的方法比较灵活,可以随时插入和删除节点,不需要考虑栈满的问题。具体实现如下:

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<malloc.h>
typedef struct SNode
{
	int data;
	struct SNode* next;
}*StackLink, Snode;



void InitStack(StackLink* SL)
{
	(*SL) = (Snode*)malloc(sizeof(Snode));
}

void PushStack(StackLink* SL)
{
	int input = 0;
	Snode* s;
	Snode* sl;
	sl = (*SL);
	printf("请输入一个数(输入0停止输入:->)");
	scanf("%d", &input);
	while (input)
	{
		printf("入栈:->");
		printf("%d ", input);
		s = (Snode*)malloc(sizeof(Snode));
		if (s == NULL)
		{
			printf("内存分配失败\n");
		}
		if (!sl)
		{
			sl->next = s;
			s->next = NULL;
		}
		s->data = input;
		s->next = sl->next;
		sl->next = s;
		printf("请输入一个数(输入0停止输入:->)");
		scanf("%d", &input);

	}
	
	
}

void Print_stack(StackLink* SL)
{
	if (!(*SL))
	{
		printf("the stack is empty\n");
	}
	else
	{
		while ((*SL))
		{
			(*SL) = (*SL)->next;
			printf("%d ", (*SL)->data);
		}
	}
	printf("\n");
}
void PopStack(StackLink* SL)//x返回出栈的元素
{
	if (!((*SL)->next))

	{
		printf("the Stack is empty\n");
	}
	while ((*SL)->next)
	{
		free((*SL));
		(*SL) = (*SL)->next;
	}
}


int main()
{
	StackLink SL;
	InitStack(&SL);
	PushStack(&SL);

	printf("出栈:\n");
	Print_stack(&SL);

	
	PopStack(&SL);
	
	return 0;
}

1.运行测试

在这里插入图片描述

三.十进制转二进制数

十进制转二进制,八进制,十六进制数,都是利用除权取余逆序读入法
正好符合栈先进后出的特性,因为我们这里使用的是单链表,直接使用头插法即可完成

图解
在这里插入图片描述
代码实现

#define _CRT_SECURE_NO_WARNINGS 1
//
#include<stdio.h>
#include<malloc.h>
typedef struct Snode
{
	int val;
	struct Snode* next;
	struct Snode* front;
}Snode, *StackLink;


void initStackLink(StackLink* SL)
{
	(*SL) = (Snode*)malloc(sizeof(Snode));
}
Snode* PushStack(StackLink* SL,int* SizeNum)
{
	int tran_num = 0;
	printf("请输入一个数->");
	scanf("%d", &tran_num);

	Snode* s;
	Snode* r;
	r = (*SL);
	printf("进栈:->\t");
	while (tran_num)
	{
		int input = tran_num % 2;
		s = (Snode*)malloc(sizeof(Snode));
		s->val = input;
		printf("%d", s->val);
		s->next = NULL;
		r->next = s;
		s->front = r;
		r = s;
		(*SizeNum)++;
		tran_num = (tran_num) / 2;
	}
	printf("\n");
	return r;
}

int PopStack(StackLink* tail,int* SizeNum)
{
	if ((*tail) == NULL)
		return 0;
	else
	{
		printf("出栈:->\t");
		while ((*tail)&&(*SizeNum))
		{
			
			printf("%d", (*tail)->val);
			(*tail) = (*tail)->front;
			(*SizeNum)--;
		}
		printf("\n");
		return 1;
	}
}
int main()
{

	StackLink SL;
	int SizeNum = 0;//二进制位数
	initStackLink(&SL);
	Snode* tail = PushStack(&SL,&SizeNum);
	int ret = PopStack(&tail,&SizeNum);//判断栈是否为空
}

四.括号匹配案例

#include<string.h>
#include<stdio.h>
#define MAX_SIZE 100
typedef struct StackList
{
	int top1;//表示原始栈顶
	int top2;//新入栈元素栈顶
	char LetterArr1[MAX_SIZE];//原始
	char LetterArr2[MAX_SIZE];//新

}stacklist,Snode;


//括号匹配问题

void InitStack(stacklist* SL)
{
	SL->top1 = -1;
	SL->top2 = -1;
}

void creat_Arr(stacklist* SL)
{

	printf("输入括号字符串:([{)]}===>");
	scanf("%s", SL->LetterArr1);
	//printf("%s", SL->LetterArr1);
}


void brackets_mate(stacklist* SL)
{
	int size = strlen(SL->LetterArr1);
	for (int i = 0; i < size; i++)
	{
		//printf("i = %d\n", i);
		if (SL->LetterArr1[i] == '(' || SL->LetterArr1[i] == '[' || SL->LetterArr1[i] == '{')
		{
			//printf("%c\n", SL->LetterArr1[i]);
			SL->LetterArr2[++(SL->top2)] = SL->LetterArr1[i];
			//printf("top2 = %d\n", SL->top2);
		}
		
		else
		{
			if (SL->top2==-1)
			{
				printf("The stack is empty\n");
			}
			//printf("top2 = %d\n", SL->top2);
			char Topelem = SL->LetterArr2[SL->top2];
			//printf("size = %d\n", size);
			
			if ((SL->LetterArr1[i] ==')' && '(' == Topelem) || (SL->LetterArr1[i] == ']' && '[' == Topelem)  || (SL->LetterArr1[i] == '}' && '{' == Topelem))
			{
				//printf("newtop2 = %d\n", SL->top2);
				SL->top2--;
				//printf("newtop2 = %d\n", SL->top2);
			}
			else 
			{
				printf("the brackets mate defeat\n");
				break;
			}
		}
	}
	if (SL->top2!=-1)
	{
		printf("The brackets mate defeat\n");
	}
	else
	{
		printf("The brackets mate success\n");
	}
}
int main()
{
	stacklist SL;
	InitStack(&SL);
	creat_Arr(&SL);
	brackets_mate(&SL);
	return 0;
}

五.总结

以上是用C语言实现栈的两种方法,读者可以根据需要选择适合自己的方法。在实际应用中,栈可以用来实现表达式求值、括号匹配,十进制数转八,二,十六进制数等功能,具有广泛的应用价值。

  • 25
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 21
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Transcend oneself

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

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

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

打赏作者

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

抵扣说明:

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

余额充值