赞
踩
栈是一种只限定在表尾进行插入和删除操作的线性表,允许插入和删除的一段称作栈顶(top),另一端称为栈底,不含任何数据元素的称为空栈,栈的特性是后进先出
栈的存储方式有两种,一种是顺序栈一种是链表栈
顺序栈利用一组地址连续的存储单元存放自栈底到栈顶的元素,同时附设一个指针(top)指示当前栈顶的位置。
#define MaxSize 100 //定义栈中元素的最大个数
typedef struct Stack {
int data[MaxSize]; //存放栈中的元素
int top; //栈顶指针
}Stack;
链表栈常采用单链表实现,并且所有操作都是在单链表的表头进行。
typedef struct StackNode{
int data; //数据域
struct LinkNode *next; //指针域
}StackNode;
本文介绍顺序栈的实现和链表栈的实现,其中链表栈和单链表差不多,可参考此文
void InitStack(Stack* stack);
bool isEmpty(Stack* stack);
void Push(Stack* stack, int x);
void Pop(Stack* stack,int *x);
int GetTop(Stack* stack);
void Print(Stack stack);
void Destroy(Stack* stack);
将栈顶指针设置为-1就可以了(空栈)。
void InitStack(Stack* stack)
{
stack->top = -1;
}
栈顶指针为-1就是空栈,大于-1就不是空栈。
bool isEmpty(Stack* stack)
{
if (stack->top == -1)
return true;
else
return false;
}
int GetTop(Stack* stack)
{
if (isEmpty(stack))
{
printf("栈空\n");
return -1;
}
else
return stack->data[stack->top];
}
注意:遍历栈如果像我这样写,参数要注意不可是Stack*stack,不然遍历之后栈就空了。
void Print(Stack stack)
{
while (stack->top != -1)
{
printf("%4d", stack->data[stack->top--]);
}
printf("\n");
}
栈的销毁令S.top = -1即可
void Destroy(Stack* stack)
{
stack->top = -1;
}
进栈的时候栈顶指针先上移,然后在放入元素
void Push(Stack* stack, int x)
{
if (stack->top == MaxSize - 1)
{
printf("栈已经满了\n");
return;
}
stack->data[++stack->top] = x;
}
出的时候栈顶指针下移一位即可
void Pop(Stack* stack,int* x)
{
if (stack->top == - 1)
{
printf("栈已经空了\n");
return;
}
*x=stack->data[stack->top--] ;
}
测试
typedef struct Node
{
int element;
ptrToNode next;
}Node;
typedef struct Node* ptrToNode;
typedef ptrToNode Stack;
int IsEmpty(Stack s);
Stack CreatStack();
void DestroyStack(Stack s);
void MakeEmpty(Stack s);
void Push(int x, Stack s);
void Pop(Stack s);
int Top(Stack s);
void ShowStack(Stack s)
;int IsEmpty(Stack s)
{
return s->next==NULL;
}
s不是栈顶元素,s是链表的表头,第一个元素是表头后的元素s->next。
Stack CreatStack()
{
Stack s;
s = malloc(sizeof(Node));
if (s == NULL)
printf("创建栈失败\n");
else
s->next = NULL;
//MakeEmpty(s);
return s;
}
元素的进栈操作就相当于单链表的头插法。
void Push(int x, Stack s)
{
ptrToNode tempNode;
tempNode = malloc(sizeof(Node));
if (tempNode == NULL)
printf("创建临时节点失败\n");
else
{
tempNode->element = x;
tempNode->next = s->next;
s->next = tempNode;
}
}
出栈操作就相当于单链表的头删操作。
void Pop(Stack s)
{
ptrToNode firstNode;
if (IsEmpty(s))
printf("这是一个空栈\n");
else
{
firstNode = s->next;
s->next = s->next->next;
free(firstNode);
}
}
连续将栈顶元素弹出,直到为空栈
void MakeEmpty(Stack s)
{
if (s == NULL)
printf("请先使用CreateStack()创建一个栈\n");
else
{
while (!IsEmpty(s))
{
Pop(s);
}
}
}
在本篇文章中,我们详细探讨了两种实现栈的方法:循序栈和链表栈。
循序栈的优点在于其实现简单且效率高。然而,它的缺点在于需要预先确定栈的最大容量,这限制了它的灵活性。如果栈的实际大小超过了最大容量,将会导致栈溢出。
链表栈的优点在于其灵活性。由于链表节点的内存空间是动态分配的,所以链表栈的大小只受限于可用内存的大小。此外,链表栈还可以方便地进行扩容和缩容。然而,链表栈的缺点在于其实现相对复杂。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。