数据结构中栈的实现
栈是一种先进后出的(Firist In Last Out)FILO的数据结构,他只有一个入口。
Stack允许加入元素、移除元素、取得最顶端的元素。但是除了最顶端之外,栈没有其他方式取得元素。
换而言之,Stack不能遍历。
栈的形式可以想象为枪的弹夹,先进去的子弹(元素)最后打出来(弹出)。
以下为C语言实现栈的功能
用链表来完成,实际上的压栈为链表的头添加,来实现先入后出的要求。
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int nValue;
struct node*pNext;
}MyStack;
typedef struct stack
{
MyStack*pTop;
int nCount;
}Stack;
void InitStack(Stack**pStack)
{
*pStack = (Stack*)malloc(sizeof(Stack));
(*pStack)->pTop = NULL;
(*pStack)->nCount = 0;
}
void Push(Stack*pStack,int nNum)
{
if(pStack == NULL)
exit(1);
MyStack *pTemp = NULL;
pTemp = (MyStack*)(malloc(sizeof(MyStack));
pTemp->nNum = nNum;
pTemp->pNext = NULL;
if(pStack->pTop == NULL)
{
pStack->pTop = pTemp;
}
else
{
pTemp->pNext = pStack->pTop;
pStack->pTop = pTemp;
}
}
int Pop(Stack*pStack)
{
if(pStack == NULL || pStack->nCount == 0)
return -1;
MyStack*pDel = pStack->pTop;
int nNum;
nNum = pDel->nValue;
pStack->pTop = pStack->pTop->pNext;
free(pDel);
pDel = NULL;
pStack->nCount--;
return nNum;
}
void Clear(Stack*pStack)
{
if(pStack == NULL)
return;
wjile(pStack->nCount)
{
Pop(pStack);
}
return;
}
void Destory(Stack**pStack)
{
if(*pStack == NULL)
return;
else
Clear(*pStack);
free(pStack);
*pStack = NULL;
}
MyStack* GetTop(Stack*pStack)
{
if(pStack == NULL)
return NULL;
return pStack->pTop;
}
int GetCount(Stack*pStack)
{
if(pStack == NULL)
return 0;
return pStack->nCount;
}
int IsEmpty(Stack*pStack)
{
if(pStack == NULL)
return 0;
return pStack->nCount == 0 ? 1 : 0;
}
如何用两个栈完成队列?
队列(Queue)是一种先入先出(First In First Out)FIFO的数据结构,他有两个出口,一个Push,一个Pop,从尾部加入,头部输出,只能取得最顶端的元素。除了从最顶端取得元素外,没有其他的办法获得队列里的元素。
队列可以理解为一条管道,一端只能进,一端只是往外输出。
栈是先入后出如何完成先入先出的要求?
利用两个栈,当元素进来时,先判断Stack2是否为空,如果为空,
入到Stack1中。
如果不为空,把Stack2中的所有的元素Pop到Stack1中。
当需要Pop时,如果Stack1不为空,将Stack1中的元素Pop到Stack2中,再将Stack2中的元素Pop。
如果Stack1为空,直接Pop Stack2即可。
简单来说,当进行操作时,根据入队或者出队判断Stack2或Stack1是否为空栈,再去进行操作。
以下为两个栈实现队列:
typedef struct queue
{
int nCount;
Stack*pStack1;
Stack*pStack2;
}Queue;
void InitQueue(Queue**pQueue)
{
*pQueue = (Queue*)(malloc(sizeof(Queue));
InitStack((*pQueue)->pStack1);
InitStack((*pQueue)->pStack2);
}
void PushQueue(Queue*pQueue,int nNum)
{
if(pQueue == NULL)
return ;
//入队
//栈2若有元素 压入栈1 中 再压入新元素
while(IsEmpty(pQueue->pStack2)
{
//此处的Push Pop 为上文Stack完成的程序
Push( pQueue->pStack1,Pop(pQueue->pStack2) );
}
//此时栈2为空栈 可以入栈1
Push(pQueue->pStack1,nNum);
}
void PopQueue(Queue*pQueue)
{
if(pQueue == NULL)
return ;
//栈2若有元素 压入栈1 中 再利用栈2的Pop出队
while(IsEmpty(pQueue->pStack1)
{
//此处的Push Pop 为上文Stack完成的程序
Push( pQueue->pStack2,Pop(pQueue->pStack1) );
}
//栈2为空 Pop栈2
int Num == Pop(pQueue->pStack2);
return Num;
}