栈(Stack)是一种基本的数据结构,它是一种线性表,但只允许在固定的一端进行插入和删除操作,这一端称为栈顶(top)。栈的特点是后进先出(Last In First Out, LIFO),即最后进入栈的元素最先被取出。
栈可以用数组来实现,也可以用链表来实现。用数组实现的栈称为顺序栈,用链表实现的栈称为链式栈。
顺序栈的特点是:
- 存储空间连续。
- 提前分配固定大小的存储空间,可能会造成空间浪费,或者空间不足时需要动态扩容。
- 访问速度快,因为支持随机访问。
链式栈的特点是:
- 存储空间不连续。
- 动态分配空间,不会造成空间浪费,也不会出现空间不足的问题。
- 访问速度相对较慢,因为不支持随机访问。
以下我来讲解一下顺序栈的使用。
1.顺序栈的结构体定义
#define N 5
顺序栈结构定义
#define N 5
typedef struct
{
int a[N];//数据域 存数据
int top;//栈针
}stack_t;
顺序栈操作
1.
创建一个空的栈
===
创建一个空的顺序表
createEmptyStack
()
2.
判断栈是否为满
===
判断顺序表是否为满
isFullStack
()
3.
判断栈是否为空
===
判断顺序表是否为空
isEmptyStack
()
4.
入栈
===
在顺序表的尾巴上插入一个数据 有效元素个数
+
1
inStack
()
5.
出栈
===
删除顺序表的尾巴 尾巴里面的数据返回 有效元素个数
-
1
outStack
()
6.
获取栈顶元素
===
将顺序表的尾巴节点里面的数据域返回
getTopStack
()
7.
清空栈
===
清空顺序表
clearEmptyStack
()
2.创建一个空的栈
stack_t
*
createEmptyStack
()
{
stack_t
*
p
=
malloc
(
sizeof
(
stack_t
));
if
(
p
==
NULL
)
{
printf
(
"createEmptyStack malloc failed!!\n"
);
return
NULL
;
}
p
->
top
=
0
;
//
因为是空的栈
,
所以有效元素个数为
0
return
p
;
}
3. 判断栈是否为满,满返回1,未满返回0
int
isFullStack
(
stack_t
*
p
)
{
return
p
->
top
==
N
?
1
:
0
;
}
4. 入栈,是插入,在数组尾巴插入一个数据
int
pushStack
(
stack_t
*
p
,
int
x
)
{
//0.容错判断
if
(
isFullStack
(
p
))
{
printf
(
"isFullStack!!!\n"
);
//
栈满
,
入栈失败
return
-
1
;
}
//1.入栈
p
->
a
[
p
->
top
]
=
x
;
//2.将入栈的元素变为有效
,
有效元素个数
+1
p
->
top
++
;
return
0
;
}
5.判断是否为空 1 代表空 0代表未空
int
isEmptyStack
(
stack_t
*
p
)
{
return
p
->
top
==
0
?
1
:
0
;
}
6.出栈,将数组的尾巴元素删除,同时将删除的数据值返回
int
popStack
(
stack_t
*
p
)
{
//0.容错判断
if
(
isEmptyStack
(
p
))
{
printf
(
"isEmptyStack!!!\n"
);
//
空栈
,
出栈失败
return
-
1
;
}
//1.出栈
,
将数组的最后一个有效元素删除
p
->
top
--
;
//
有效元素个数
-1,
相当于将栈顶元素删除
//2.将出栈元素的值返回
//上面的
p->top--
之后
,p->top
里面保存的是出栈元素的下标
return
p
->
a
[
p
->
top
];
}
7. 获取栈顶元素的值
int
getTopValue
(
stack_t
*
p
)
{
return
p
->
a
[
p
->
top
-
1
];
// p->top-1
得到最后一个有效元素的下标
,
即栈顶元素的下标
}
8. 清空栈
void
clearStack
(
stack_t
*
p
)
{
p
->
top
=
0
;
//
有效元素赋值为
0
}
结语
以上就是栈的基本使用,本次代码分享到此结束,后续还会分享数据结构的知识。
最后的最后,还请大家点点赞,点点关注,谢谢大家!