栈和队列
一、栈和队列的概念
1、栈的概念
栈是只允许在一端进行插入或者删除操作的线性表。
栈还涉及一些概念:
栈顶: 线性表允许插入和删除元素的一端。
栈底: 固定的,不允许进行插入和删除的一端。
栈的输入输出特点是FILO(first in last out)后进先出,假如栈中有四个元素a_1,a_2,a_3,a_4已经全部按顺序入栈,则出栈的顺序是a_4,a_3,a_2,a_1。
2、栈的基本操作
栈的基本操作包括出栈,入栈,获取栈顶元素等:
- InitStack(&S) 初始化操作
- StackEmpty(S) 栈的判空
- Push(&S, x) 入栈
- Pop(&s, &x) 出栈
- GetTop(S, &x) 获取栈顶元素
- ClearStack(&S) 清空栈
3、队列的概念
队列也是一种操作受限的线性表,只允许在一端进行插入操作,另一端进行删除操作。和栈相反队列是FIFO(First In First Out)先入先出。
出队:队头元素被删除;
入队:队尾元素被插入到队列中。
栈的输入输出特点是FILO(first in last out)后进先出,假如栈中有四个元素a_1,a_2,a_3,a_4已经全部按顺序入栈,则出栈的顺序是a_1,a_2,a_3,a_4。
4、队列的基本操作
队列的基本操作有出队入队等
- InitQueue(&Q) 初始化队列
- QueueEmpty(Q) 队列判空
- EnQueue(&Q, x) 入队
- DeQueue(&Q, &x) 出队
- GetHead(Q, &x) 获取对头元素
二、栈和队列的结构定义
栈,队列和线性表相同可分为顺序和链式。
1、栈
栈可分为顺序栈和链式栈,顺序栈按照之前线性表的分类可以分为动态内存分配和静态内存分配。
静态顺序栈
#define MAX_SIZE 100
typedef int ElemType;
typedef struct
{
int top, base;
ElemType data[MAX_SIZE];
}sqStack;
动态顺序栈
#define INIT_SIZE 100
#define INCREASE_SIZE 20
typedef int ElemType;
typedef struct
{
ElemType* base;
ElemType* top;
int stackSize;
}sqStack;
链式栈
typedef int ElemType;
typedef struct StackNode
{
struct StackNode* next;
ElemType data;
}StackNode,* LinkStack;
2、队列
队列的分类相对于栈来说更多,包含顺序队列,循环队列,链式队列,双端队列,其中双端队列可以看成栈和队列的结合。
顺序队列
#define MAX_SIZE 100
typedef int ElemType;
typedef struct
{
ElemType data[MAX_SIZE];
int front, rear;
}sqQueue;
循环队列
循环队列的定义和顺序队列相同,只是操作方法不同,队列入队出队操作过程中,当队尾队尾已经抵达已分配空间的末端时,就无法在入队,但是由于之前的出队操作,队头之前的数据空间已经不再使用,就意味着队列并未真正意义上的满,因此将指针再定位回之前释放的空间加以利用。
需要说的是假若以Q.rear == Q.front判断队列满就会发生和判空相冲突,因此回退一个空间作为判断的方式:(Q.rear + 1)%MAX_SIZE = Q.front;除余是为了避免Q.rear和Q.front一个在队尾,一个在队头的情况的发生。具体代码之后会说到。
链式队列
typedef int ElemType;
typedef struct QueueNode
{
ElemType data;
struct QueueNode* next;
}QueueNode,* LinkQueue;
typedef struct
{
LinkQueue front, rear;
}Queue;
双端队列
队列是只允许一段入队,另一端出队的结构,而双端队列是允许在一端进行两种操作另一端进行一种操作的队列,分为:
输入受限双端队列:两端都可以出队,只有一端可以入队。
输出受限双端队列:两端都可以入队,只有一端可以出队。
三、具体代码
1、栈的相关操作
顺序栈入栈
//function: push a element into the stack
//parameters: S the pointer of stack
// e the element you would push into
//return: TRUE successfully
// FALSE failurely
int Push(sqStack* S, Elemtype e)
{
if(S->base == NULL)
{
return FALSE;
}
if(S->stackSize == (S->top - S->base))
{
Elemtype* tmp = (Elemtype*)realloc(S->base, sizeof(Elemtype) * (S->stackSize + INCREASE_SIZE));
if(tmp == NULL)
{
return FALSE;
}
S->base = tmp;
S->top = S->base + S->stackSize;
S->stackSize = S->stackSize + INCREASE_SIZE;
}
*S->top++ = e;
return TRUE;
}
顺序栈出栈
//function: pop a element from the top of stack
//parameters: S the pointer of stack
// e the pointer which would storage the data
//return: TRUE successfully
// FALSE failurely
int Pop(sqStack* S, Elemtype* e)
{
if(S->base == NULL || (S->top - S->base) == 0)
{
return FALSE;
}
*e = *(--S->top);
return TRUE;
}
链式栈入栈
//function: push a element into the stack
//parameters: S the pointer of stack
// e the element you would push into
//return: TRUE successfully
// FALSE failurely
int Push(LinkStack* S, Elemtype e)
{
if(S == NULL)
{
return FALSE;
}
StackNode ptr = (LinkNode)malloc(sizeof(StackNode));
ptr->data = e;
ptr->next = (*S)->next;
(*S)->next = ptr;
return TRUE;
}
链式栈出栈
//function: pop a element from the top of stack
//parameters: S the pointer of stack
// e the pointer which would storage the data
//return: TRUE successfully
// FALSE failurely
int Pop(LinkStack* S, Elemtype* e)
{
if(S == NULL && S->next == NULL)
{
return FALSE;
}
LinkStack ptr = (*S)->next;
(*S)->next = ptr->next;
*e = ptr->data;
free(ptr);
ptr = NULL;
return TRUE;
}
2、队列相关操作
顺序循环队列入队
//function: insert element into queue
//parameters: Q the pointer that points to queue
// e the element you would insert
//return: TRUE successfully
// FALSE failurely
int EnQueue(sqQueue* Q, ElemType e)
{
if(QueueLength(*Q) == MAX_SIZE)
{
return FALSE;
}
Q->data[Q->rear++] = e;
Q->rear = Q->rear % MAX_SIZE;
return TRUE;
}
顺序循环队列出队
//function: delete element from queue
//parameters: Q the pointer that points to queue
// e storage the element you would delete
//return: TRUE successfully
// FALSE failurely
int DeQueue(sqQueue* Q, ElemType* e)
{
if(QueueEmpty(*Q))
{
return FALSE;
}
*e = Q->data[Q->front++];
Q->front = Q->front % MAX_SIZE;
return TRUE;
}
链式队列入队
//function: insert element into queue
//parameters: Q the pointer that points to queue
// e the element you would insert
//return: TRUE successfully
// FALSE failurely
int EnQueue(LinkQueue* Q, ElemType e)
{
if(Q->rear == Q->front)
{
return FALSE;
}
LinkQueue ptr = (LinkQueue)malloc(sizeof(QueueNode));
ptr->data = e;
ptr->next = NULL;
Q->rear->next = ptr;
Q->rear = ptr;
return TRUE;
}
链式队列出队
//function: delete element from queue
//parameters: Q the pointer that points to queue
// e storage the element you would delete
//return: TRUE successfully
// FALSE failurely
int DeQueue(LinkQueue* Q, ElemType* e)
{
if(Q->rear == Q->front)
{
return FALSE;
}
LinkQueue ptr = Q->front;
Q->front = ptr->next;
*e = ptr->data;
free(ptr);
ptr = NULL;
return TRUE;
}
相关代码的链接:http://download.csdn.net/detail/grayondream/9731257