“抽象”《大话数据结构》第四章——栈

栈的定义

首先栈是一种线性表,他比较特殊,只能在表尾进行插入和删除操作。

栈的抽象数据类型

数据类型:
栈的每一个元素依然是结构体,有数据域,有栈顶指针。
对应操作:
1 初始化操作,建立一个空栈。
2 释放栈的分配空间
3 在栈顶插入新的元素
4 删除掉栈顶的元素
5 返回栈的元素个数

栈的顺序存储结构

根据栈的抽象数据类型,现在一一实现它。

先是数据类型:

typedefint SElemType;
typedef struct
{
	SElemType data[SIZE];
	int top;
}SQStack;

top记录的是数组data中最后面有值的元素的下标。就是栈顶指针的意思啦。

然后是进栈

1 判断是否栈满,即 top 的值是否为 (size-1),若栈满,则返回ERROR。
2 top 自增,成为下一个元素空间的下标。
3 把新的值赋给这个元素空间,然后返回操作成功标志。
代码如下:

Status push(SQStack *Stack, SElemType data)
{
	if(Stack->top == (SIZE - 1))
		return ERROR;
	Stack->top ++;
	Stack->data[Stack->top] = data;
	return OK;
}

还需要出栈

1 判断栈是不是出空了,即top是否小于0.
2 把要删除的元素赋给返回指针delete_data。
3 top自减。返回操作成功标志。
代码如下:

Status pop(SQStack *Stack, SElemType *delete_data)
{
	if(Stack->top < 0)
		return ERROR;
	*delete_data = Stack->data[Stack->top];
	Stack->top--;
	return OK;
		
}

两栈共享空间

主要是为了最大限度利用开辟的存储空间,由于是在一个数组空间内,故两个栈的数据类型必须相同。

定义数据类型

1 开辟数组空间
2 定义整型变量 top1 和 top2
代码如下:

typedef struct
{
	SElemType data[SIZE];
	int top1;
	int top2;
}SQDoubleStack;

其中 SQDoubleStack 可以用来定义结构体类型的变量。

入栈

对于共享空间的栈入栈需要注意:
1 判断栈满,top1 + 1 == top2。
2 判断是入哪个栈。
代码如下:

Status DoubleStack_push(SQDoubleStack *stack, SElemType data, int stack_number)
{
	if((stack->top1 + 1) == stack->top2)
		return ERROR;
	if(stack_number == 1)
	{
		stack->top1++;
		stack->data[stack->top1] = data;
	}
	else if(stack_number == 2)
	{
		stack->top2--;
		stack->data[stack->top2] = data;
	}
		return OK;
}

出栈

1 判断需要操作哪个栈
2 top1或者top2移动后,需要判断是否溢出
代码如下:

Status DoubleStack_pop(SQDoubleStack *stack, SElemType* delete_data, int stack_number)
{
	if(stack_number == 1)
	{
		if(--stack->top1 < 0)
		{
			stack->top1 = 0;
			return ERROR;
		}
		*delete_data = stack->data[stack->top1];
	}
	else if(stack_number == 2)
	{
		if(++stack->top2 >= SIZE)
		{
			stack->top2 = SIZE-1;
			return ERROR;
		}
		*delete_data = stack->data[stack->top2];
	}
	return OK;
}

栈的链式存储结构

栈顶放在链表的头部,栈底放在尾部。栈顶指针指向第一个结点。

定义链栈的结构代码:

typedef struct StackNode
{
	SElemType data;
	struct StackNode *next;
}StackNode,*LinkStackPtr;

typedef struct LinkStack
{
	LinkStackPtr top;
	int count;
}LinkStack;

入栈

可以根据前面的单链表插入新值的操作猜测下入栈操作:
1 需要新开辟一个结点
2 新结点的next指向top指针所指的结点(原来的第一个结点,即原来的栈顶)
3 top指向新的结点,count++
代码如下:

Status push_linkstack(LinkStack *TOP, SElemType new_data)
{
	LinkStackPtr new_node;
	new_node = (LinkStackPtr)malloc(sizeof(StackNode));
	new_node->data = new_data;
	new_node->next = TOP->top;
	TOP->top = new_node;
	TOP->count++;
	return OK;
}

出栈

同样,我们也来回顾下之前的链表删除操作,以此推出出栈:
1 *delete_data = TOP->top->data,栈顶的数据幅值给形参指针
2 delete_node = TOP->top;
3 TOP->top = TOP->top->next。栈顶元素后一个结点的地址给top指针
4 释放delete_node
5 TOP->count–
代码如下:

Status pop_linkstack(LinkStack *TOP, SElemType *delete_data)
{
	LinkStackPtr delete_node;
	if(TOP->top == NULL)
		return ERROR;
	*delete_data = TOP->top->data;
	delete_node = TOP->top;
	TOP->top = TOP->top->next;
	free(delete_node);
	TOP->count--;
	return OK;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值