数据结构--线性表--栈(8个常见操作)

一、栈的定义以及一些名词解释
栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算

栈允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为入栈(Push),删除则称为出栈(Pop)。

由于堆叠数据结构只允许在一端进行操作,因而按照先进后出(FILO, First In Last Out)的原理运作。
先进后出,个人理解类似于子弹上膛,先装入的子弹最后被打出。

二、对栈的常见操作
1、初始化栈(Init)
2、向栈里压入元素(Push)
3、得到栈顶元素内容(Pop)
4、统计栈内元素个数(GetCount)
5、清空栈(Clear)
6、得到栈顶元素(GetTop)
7、销毁栈(Destory)
8、判断栈是否为空(IsEmpty)
三、代码实现
1、想要对一个栈完成各种操作,首先你需要有一个栈,栈内需要有什么?
栈内有元素,还有指针,且最重要的元素为栈顶元素,我们只需要知道栈顶元素就能够通过它获得next,next->next, next->next->next, …
显然,我们需要一个结构体来封装我们这一个元素所具有的属性,也就是数据结构体,里面有元素的值和指针。
好了,那我们先来看一段代码

#include<stdio.h>
#include<stdlib.h>

typedef struct stack
{
    
    
	int nValue;
	struct stack*pNext;
}MyStack;

void Push (MyStack **pTop,int nNum)
{
    
    
	MyStack *pTemp = NULL;
	pTemp = (MyStack*)malloc(sizeof(MyStack));
	pTemp->nValue = nNum;
	pTemp->pNext = *pTop;
	*pTop = pTemp;
}

int Pop(MyStack **pTop)
{
    
    
	if(*pTop == NULL) return -1;
   
	MyStack *pDel = *pTop;
	int nNum = pDel->nValue;

	*pTop = (*pTop)->pNext;
	free(pDel);
	pDel = NULL;
	return nNum;
}


int main()
{
    
    
	MyStack *pTop = NULL;
	Push(&pTop,1);
	Push(&pTop,2);
	Push(&pTop,3);
	Push(&pTop,4);
	printf("%d\n",Pop(&pTop));
	printf("%d\n",Pop(&pTop));
	printf("%d\n",Pop(&pTop));
	printf("%d\n",Pop(&pTop));

	return 0;
}

这是对栈的一个Push和Pop操作
在这里插入图片描述

2、
(提前声明哦,有一些小伙伴不要看文字多就没有耐心了,其实我也这样,但是我就尽量用一些文字尽可能的让大家都懂,可能写的啰嗦,或者不太好,欢迎大家批评指正)
首先我们肯定的是我们上面这段代码是没有问题的,那让我们考虑接下来的其他操作该怎么实现,我们对每一个操作进行分析,在主函数里面定义了pTop,这就意味着只要程序没有结束以前,栈总是能用的,而我们的第7个操作栈的销毁是什么意思,是我们只要调用这个操作,栈就用不了,所以此时的销毁功能是没有办法完成的,说得更加直白一点那就是,栈用不了,就是pTop用不了,我们怎么才能决定pTop什么时候不能用呢,我们自己手动为pTop申请空间,并且初始化pTop,我们的初始化栈,其实也就是初始化栈顶pTop,在想要销毁栈的时候就free栈顶pTop,这样栈就用不了了,我们的目的也就达到了。
3、那我们要在哪里定义这个pTop,然后对它初始化进行操作呢?在其他函数里?在其他函数里定义,那我们在主函数里调用函数的时候该传什么样的参数呢?全局?也不行。那是否可以把pTop也封装在一个结构体里,想用的时候就初始化申请空间,然后指针调用进行操作,不想用就释放掉。
4、清空栈就是一直Pop,直到栈内元素个数为0,结束。判断栈是否为空也是看栈内元素个数是否为0,那么接下来最关键的就是统计栈内元素个数了,不可能count一次数一次,我们可以在结构体里除了pTop,在放一个nCount,计数变量,push的时候就++,Pop的时候就- -。
5、剩余代码实现
当然上述代码也要做出相应的改动。

#include<stdio.h>
#include<stdlib.h>

typedef struct data
{
    
    
	int nValue;
	struct data *pNext;
}MyStack;

typedef struct stack
{
    
    
	int nCount;
	MyStack *pTop;
}Stack;

void s_Init(Stack **pStack)
{
    
    
	*pStack = (Stack *)malloc(sizeof(Stack));
	(*pStack)->nCount = 0;
	(*pStack)->pTop = NULL;
}


void s_Push (Stack *pStack,int nNum)
{
    
    
	if(pStack == NULL)
	{
    
    
		printf("不存在\n");
		return;
	}

	MyStack *pTemp = NULL;
	pTemp = (MyStack*)malloc(sizeof(MyStack));
	pTemp->nValue = nNum;
	pTemp->pNext = pStack->pTop;
	pStack->pTop = pTemp;
	pStack->nCount++;
}

int s_Pop(Stack *pStack)
{
    
    
	if(pStack == NULL) exit(1);
	if(pStack->pTop == NULL) return -1;  

	MyStack *pDel = pStack->pTop;
	int nNum = pDel->nValue;

	pStack->pTop = pStack->pTop->pNext;
	free(pDel);
	pDel = NULL;
	pStack->nCount--;
	return nNum;
}

void s_Clear(Stack *pStack)
{
    
    
	if(pStack == NULL) exit(1);
	while(pStack->nCount != 0)
	{
    
    
		s_Pop(pStack);
	}
}

void s_Destory(Stack **pStack)
{
    
    
	s_Clear(*pStack);
	free(*pStack);
	*pStack = NULL;
}
int s_GetCount(Stack *pStack)
 {
    
    
     if(pStack == NULL) exit(1);
 
     return pStack->nCount;
 }
 
 MyStack *s_GetTop(Stack *pStack)
 {
    
    
     if(pStack == NULL) exit(1);
      return pStack->pTop;
 }
 int s_IsEmpty(Stack *pStack)
 {
    
    
     if(pStack == NULL) exit(1);
 
     return pStack->nCount ?0:1;
 }


int main()
{
    
    
	Stack *pStack = NULL;
	s_Init(&pStack);

	s_Push(pStack,1);
	s_Push(pStack,2);
	s_Push(pStack,3);
	s_Push(pStack,4);

	printf("%d\n",s_Pop(pStack));
	printf("%d\n",s_Pop(pStack));
	printf("%d\n",s_Pop(pStack));
	printf("%d\n",s_Pop(pStack));

	s_Destory(&pStack);
	s_Push(pStack,100);

	return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/scarificed/article/details/112544202