数据结构: 栈(linked-stack & array-stack)
栈是一种特别的线性表。在栈中,只能在数据的一端(即栈顶)进行操作。最经典的解释在这个策略的例子就是
叠盘子。盘子只能一个一个不断放在之前的盘子堆上,拿盘子的时候只能从上往下一个一个拿。这两个操作,
在stack中分别对于push和pop, 即压栈和出栈。这体现了栈的后进先出(LIFO)特性。
栈的实现
stack 的实现分为两种,一种是使用数组来模拟栈,另外一种是使用链表来模拟栈。
数组实现(array stack)
首先,先来看使用数组的方法。
栈的结构为
看起来,数组的实现方式十分的简单!So easy! 当向栈中压入数据时,需要将 top 的值
加1; Too young, too naive! 考虑两个极端的情况: 在栈满时压栈,在栈空时出栈。因此
在进行 push 和 pop 操作之前需要检查栈的情况,避免溢出。
链式栈使用链表的存储形式实现,其存储不是连续的。我们首先定义 stack 的结构如下:
数组实现
链式实现
栈是一种特别的线性表。在栈中,只能在数据的一端(即栈顶)进行操作。最经典的解释在这个策略的例子就是
叠盘子。盘子只能一个一个不断放在之前的盘子堆上,拿盘子的时候只能从上往下一个一个拿。这两个操作,
在stack中分别对于push和pop, 即压栈和出栈。这体现了栈的后进先出(LIFO)特性。
栈的实现
stack 的实现分为两种,一种是使用数组来模拟栈,另外一种是使用链表来模拟栈。
数组实现(array stack)
首先,先来看使用数组的方法。
栈的结构为
#define MAX_SIZE 20 //栈内最多有几个元素
typedef int StackEntry;
typedef struct stack{
StackEntry entry[MAX_SIZE];
int top;
}Stack;
用数组实现的栈使用连续的内存地址, 为了能够知道栈顶位置,需要使用一个变量标记。
看起来,数组的实现方式十分的简单!So easy! 当向栈中压入数据时,需要将 top 的值
加1; Too young, too naive! 考虑两个极端的情况: 在栈满时压栈,在栈空时出栈。因此
在进行 push 和 pop 操作之前需要检查栈的情况,避免溢出。
int IsFull(Stack *s){
return (s->top >= MAX_SIZE);
}
int IsEmpty(Stack *s)
{
return (s->top <= 0);
}
void Push(StackEntry item, Stack *s)
{
if(IsFull(s))
return;
else
s->entry[s->top++] = item;
}
void Pop(Stack *s)
{
if(IsEmpty(s))
return ;
else
s->top--;
}
StackEntry Top(Stack *s)
{
if(!IsEmpty(s))
return s->entry[s->top-1];
else
return -1;
}
链式实现(linked stack)
链式栈使用链表的存储形式实现,其存储不是连续的。我们首先定义 stack 的结构如下:
typedef struct node
{
StackEntry val;
struct node *next;
}Node;
//push a new node onto the top of the stack (the front of the list),
//and return whether successful
int Push(int val, Node* stack)
{
Node* addNode = (Node*)malloc(sizeof(Node));
if(addNode == NULL)
{
printf("out of memory!\n");
return 0;
}
addNode->val = val;
addNode->next = stack->next;
stack->next = addNode;
return 1;
}
//pop the top node from the stack
int Pop(Node* stack)
{
if(IsEmpty(stack))
{
printf("the stack is empty!\n");
return 0;
}
Node *tmpNode = stack->next;
stack->next = tmpNode->next;
free(tmpNode);
return 1;
}
int IsEmpty(Node* stack)
{
return (stack->next == NULL);
}
//get the top value of the stack
int Top(Node* stack)
{
if(IsEmpty(stack))
{
printf("the stack is empty!\n");
return -1;
}
return (stack->next->val);
}
综合所有操作
数组实现
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 20
typedef int StackEntry;
typedef struct stack{
StackEntry entry[MAX_SIZE];
int top;
}Stack;
int IsFull(Stack *s)
{
return (s->top >= MAX_SIZE);
}
int IsEmpty(Stack *s)
{
return (s->top <= 0);
}
void Push(StackEntry item, Stack *s)
{
if(IsFull(s))
return;
else
s->entry[s->top++] = item;
}
void Pop(Stack *s)
{
if(IsEmpty(s))
return;
else
s->top--;
}
StackEntry Top(Stack *s)
{
if(!IsEmpty(s))
return s->entry[s->top-1];
else
return -1;
}
int main()
{
Stack *s = (Stack*)malloc(sizeof(Stack));
s->top = 0;
Push(1, s);
Push(2, s);
Push(3, s);
//get 3
int temp = Top(s);
printf("%d", temp);
//pop 3
Pop(s);
temp = Top(s);
printf("%d", temp);
Push(4, s);
temp = Top(s);
printf("%d", temp);
//pop 4
Pop(s);
temp = Top(s);
printf("%d", temp);
//pop 2
Pop(s);
temp = Top(s);
printf("%d", temp);
//pop 1
Pop(s);
temp = Top(s);
printf("%d", temp);
return 0;
}
链式实现
typedef struct node
{
int val;
struct node *next;
}Node;
Node* CreateEmptyStack();
int Push(int val, Node* stack);
int Pop(Node* stack);
int IsEmpty(Node* stack);
int Top(Node* stack);
int _tmain(int argc, _TCHAR* argv[])
{
Node *s = CreateEmptyStack();
Push(1, s);
Push(2, s);
Push(3, s);
int temp = Top(s);
printf("%d\n", temp);
//pop 3
Pop(s);
temp = Top(s);
printf("%d\n", temp);
//push 4
Push(4, s);
temp = Top(s);
printf("%d\n", temp);
//pop 4
Pop(s);
temp = Top(s);
printf("%d\n", temp);
//pop 2
Pop(s);
temp = Top(s);
printf("%d\n", temp);
Pop(s);
temp = Top(s);
printf("%d\n", temp);
return 0;
}
//Create a empty stack and return the address
Node* CreateEmptyStack()
{
Node* stack = (Node*)malloc(sizeof(Node));
if (stack == NULL)
{
printf("out of memory!\n");
return NULL;
}
stack->val = 0;
stack->next = NULL;
return stack;
}
//push a new node onto the top of the stack (the front of the list),
//and return whether successful
int Push(int val, Node* stack)
{
Node* addNode = (Node*)malloc(sizeof(Node));
if (addNode == NULL){
printf("out of memory!\n");
return 0;
}
addNode->val = val;
addNode->next = stack->next;
stack->next = addNode;
return 1;
}
//Pop the top node from the stack
int Pop(Node* stack)
{
if (IsEmpty(stack))
{
printf("the stack is empty!\n");
return 0;
}
Node *tmpNode = stack->next;
stack->next = tmpNode->next;
free(tmpNode);
return 1;
}
//check whehter the stack is empty
int IsEmpty(Node* stack)
{
return (stack->next == NULL);
}
//get the top value of the stack
int Top(Node* stack){
if (IsEmpty(stack))
{
printf("the stack is empty!\n");
return -1;
}
return (stack->next->val);
}