数据结构(2)顺序栈/链栈的基本实现(c)(详细的很)

介绍:
是计算机编程里面一种较为简单,基础的数据结构类型,又名堆栈。同线性表一样,栈的存储方式也分为顺序存储链式存储
(以单端栈为例)其大概示意图如下:
在这里插入图片描述1.栈只能从一端进入,一端出去,也就是说栈是一个半封闭的数据结构。
2.栈遵循先进先出的原则。
3.出栈和入栈只能发生在栈顶,而不能发生在栈底。
4.入栈:外部数据从栈顶进入栈里
5.出栈:栈顶数据从栈顶方向弹出
一. 顺序栈
介绍:
他的结构体存储类型:

typedef int ElementType;
typedef struct
{
    ElementType *array; //存放栈数据
    int top;	 		//栈顶
    int capacity;  		//容量
} SeqStack;

1. 创建

请设计SeqStack* createStack(int capacity)函数。
该函数创建一个空的顺序栈,并返回栈指针。
参数capacity为已分配的栈空间大小(栈可用空间为array[0,…capacity-1])。
在这里插入图片描述

SeqStack* createStack(int capacity)
{
    SeqStack *s;
    s=(SeqStack *)malloc(sizeof(SeqStack));
    if(s==NULL) return NULL;
    s->top=-1;  //初始栈顶下标为-1
    s->capacity=capacity;
    s->array=(ElementType *)malloc(capacity*sizeof(ElementType));
    return s;
}

2. 判满
请设计int full(SeqStack *S)函数。 该函数判断栈S是否满,
如果栈满则返回1,否则返回0

int full(SeqStack *S)
{
    if(S->top == S->capacity-1)
        return 1;
    return 0;
}

3. 入栈
入栈操作的前提是栈未满,而且入栈的方向是栈顶,此时栈的top应该+1;
在这里插入图片描述请设计int push(SeqStack *S, ElementType x)函数。
该函数将数据x压入栈顶,如果入栈成功返回1,否则返回0。

int push(SeqStack *S, ElementType x)
{
    if(S->top < S->capacity-1)  //判断栈是否为满
    {
        S->top++;  //栈顶下标数据+1
        S->array[S->top]=x;
        return 1;
    }
    return 0;
}

4. 出栈
出栈的前提是栈未空,出栈的方向仍然是栈顶,此时的top应该-1
在这里插入图片描述
请设计int pop(SeqStack *S)函数。
该函数将栈顶数据出栈,如果成功返回1;否则返回0。

int pop(SeqStack *S)    
{
    if(S->top>-1)    //判断不为空
    {
        S->top--;      //栈顶下标数据--
        return 1;
    }
    return 0;
}

5. 栈顶数据
输出栈顶数据,但是栈顶数据不出栈
请设计ElementType top(SeqStack *S)函数。
该函数该函数把返回栈顶数据(不出栈),已知栈非空。

ElementType top(SeqStack *S)
{
    if(S->top > -1) //不为空的栈
    {
        return S->array[S->top];  //返回栈顶数据但不出栈
    }
}

6. 清空栈
栈顶清空操作就是将所有已入栈的数据全部清空,但保留最后的空栈
请设计void clearStack(SeqStack *S)函数。
该函数清空栈中数据(保留数据空间)。

void clearStack(SeqStack *S)
{
    while(S->top > -1)  //直到栈顶下标数据为-1,代表栈已清空
    {
        S->top--;
    }
}

7. 销毁
销毁所创建的栈

请设计void destroyStack(SeqStack *S)函数。
该函数销毁栈。

void destroyStack(SeqStack *S)
{
    free(S->array);
    free(S);
    S = NULL;
}

二. 链栈(下面的图可能没贴好,海涵)
链式栈的存储结构体类型

typedef int ElementType;
typedef struct Node
{
    ElementType data;   //数据域
    struct Node *next;  //指针域
} Node, *LinkStack;
typedef struct
{
	LinkStack top;   //指向栈顶结构体的指针
	LinkSatck base;  //指向栈底结构体的指针
}LinkStackTop;

下面列举一个链栈的例子
在这里插入图片描述
1. 创建空链栈
请设计LinkStackTop* createStack()函数。
该函数创建一个不带头结点的空链栈。
在这里插入图片描述
因为是不带头结点空链栈,所以此时栈内的结构体是不存在的,就只需要创建包含top指针和base指针的结构体就可以

LinkStackTop* createStack()
{
	LinkStackTop *p=(LinkStackTop*)malloc(sizeof(LinkStackTop));
	if(p == NULL) return NULL;
	p->top = NULL;
	p->base = NULL;
	return p;
}

2. 入栈
链式栈的入栈需要注意:入栈后记得改变top指针的指向,如果原栈为空,还要考虑栈底指针
在这里插入图片描述请设计int push(LinkStackTop* S, ElementType x)函数。
该函数把x压入S的栈顶,并返回1,(已知S是不带头结点的链栈),如果申请空间失败返回0。

int push(LinkStackTop* S, ElementType x)
{
	if(S == NULL) return 0;
	LinkStack stack = (LinkStack)malloc(sizeof(Node));
	if(stack == NULL) return 0;
	stack->data = x;
	stack->next = NULL;
	if(S->base == NULL)  //起初是空链栈的时候
	{
		S->top = S->base = stack;
		return 1;
	}
	S->top->next = stack;
	S->top = stack;
	return 1;
}

3. 获取栈顶数据
请设计ElementType Top(LinkStackTop* S)函数。
该函数返回不带头节点的链栈S的栈顶数据(不出栈)。
栈为空什么也不做

ElementType Top(LinkStackTop* S)
{
	if(S->base != NULL)  //判断栈不为空
	{
		return S->top->data;
	}
}

4. 出栈
请设计int pop(LinkStackTop* S)函数。
已知S是不带头结点的链栈。
该函数把链栈S栈顶元素出栈,如果S已空,则什么都不做。
如果出栈成功返回1,否则返回0。
在这里插入图片描述

int pop(LinkStackTop* S)
{
	if(S->base!=NULL)
	{
		LinkStack mid = S->base;
		LinkStack pre = NULL; //mid的前驱
		while(1)
		{
			if(mid == S->top)
			{
				if(mid == S->base) S->base = pre;  //如果栈内只有一个数据
				else  pre->next = S->top->next;
				S->top = pre;
				free(mid); //销毁栈顶
				return 1;
			}
			pre = mid;
			mid = mid->next;
		}
	}
	return 0;
}

5. 清空栈

请设计void clearStack(LinkStackTop* S)函数。
该函数删除链栈中的所有数据节点,清除后为空链栈。

void clearStack(LinkStackTop* S)
{
	LinkStack mid = S->base;
	LinkStack pre;
	while(mid)  //从 base 到 top 全部清空
	{
		pre=mid;
		free(pre);
		mid=mid->next;
	}
	S->base = S->top = NULL;
}

6. 销毁栈
请设计void destroyStack(LinkStackTop* S)函数。
该函数销毁链栈S,已知S是不带头结点的链栈。
(S不一定是空链)

void destroyStack(LinkStackTop* S)
{
	LinkStack mid = S->base;
	LinkStack pre;
	while(mid)  //从 base 到 top 全部清空
	{
		pre=mid;
		free(pre);
		mid=mid->next;
	}
	free(S);
	S = NULL;
}

是不是感觉又学到了东西,hhhh,评论区已经划好,有问题欢迎留言!
制作不易,感谢支持,望不喜勿喷!

原创文章 19 获赞 40 访问量 1万+

猜你喜欢

转载自blog.csdn.net/YSJ367635984/article/details/105426531