栈是一种只能在一端进行插入或删除操作的线性表
其中允许进行插入或删除操作的一端称为栈顶(Top)
栈顶由一个栈顶指针的位置指示器(其实是1个变量,对于顺序栈就是记录栈顶元素所在数组位置标号的一个整型变量,对于链式栈就是记录栈顶元素所在结点地址的指针)它是动态变换的。
表的另一端称为栈底,栈底是固定不变的。
栈的插入和删除操作一般称为入栈和出栈。
特点:先进后出(FILO)
存储结构:顺序栈和链式栈
栈是一种在操作上稍加限制的线性表,即栈的本质是线性表;
数学性质:
当n个元素以某种顺序进栈,并且可在任意时刻出栈时,所获得的元素排序的数目N恰好满足函数
N = 1 n + 1 C 2 n n N=\frac{1}{n+1}C_{2n}^{n} N=n+11C2nn
栈空状态:st.top == -1或st.top == 0
栈满状态:st.top ==maxsize -1
因为数组下标从0开始,maxsize -1 为栈满时,栈顶元素在数组中的位置
上溢:栈满继续入栈
下溢:栈空的时候继续出栈所造成的
元素x进栈操作:
++(st.top);
st.data[st.top]=x ;
必须先移动指针,再进入元素
元素x出栈操作:
x = st.data[st.top] ;
--(st.top);
typedef struct
{
int data[maxsize];
int top;
}SqStack;
void initStack( SqStack &st)
{
st.top = -1;
}
int isEmpty(SqStack st)
{
if(st.top ==-1)
return 1;
else
return 0;
}
int push(SqStack &st , int x)
{
if(st.top == maxsize -1)
return 0;
++(st.top);
st.data[st.top] = x;
return 1;
}
int pop(SqStack &st ,int &x)
{
if(st.top == -1)
return 0;
x = st.data[st.top];
--(st.top);
return 1;
}
//定义并初始化
int stack[maxsize];
int top = -1;
//元素x进栈
stack[++top] == x;
//元素x出栈
x = stack[top--];
栈空状态:lst->next == NULL;
栈满状态:不存在栈满状态
元素进栈(由p指针所指)
p->next = lst->next;
lst->next = p
元素出栈(出栈元素保存在x中)
p = last->next;
x = p->data;
lst->next = p->next;
free(p)
typedef struct LNode
{
int data;
struct LNode *next;
}LNode;
void initStack(LNode *&lst)
{
lst = (LNode *)malloc(sizeof(LNode));
lst->next = NULL;
}
int isEmpty(LNode *lst)
{
if(lst->next == NULL)
return 1;
else
return 0;
}
void push(LNode *lst , int x)
{
LNode *p;
p = (LNode *)malloc(sizeof(LNode));
p->next = NULL;
p->data = x;
p->next = lst->next;
p->next = p;
}
int pop(LNode *lst , int &x)
{
LNode *p;
if(lst->next == NULL)
return 0;
p = lst->next;
x = p->data;
lst->next = p->next;
free(p);
return 1;
}
定义:队列是一种操作受限的线性表, 其限制为仅允许在标的一端进行插入,在表的另一端删除, 可进行插入的一端称为队尾,可进行删除的一端称为队头; 向队列中插入元素称为进队,新元素进队后就成为新的队尾元素; 从队列中删除元素称为出队,其后继元素就成为新的队头元素。
这样进过一系列的出队和进队操作之后,两个指针最终会到达数组末端,maxsize-1处,队中没有元素,但仍然无法进队,这就是“假溢出问题”
将数组组成一个环,让rear和fort沿着环走,这样就产生了循环队列,可以通过执行语句 fort = (fort +1)%maxsize 实现环形道路走。
队满:
(rear+1)%maxsize == fort : (qu.rear+1)%maxsize == qu.fort
队空:
fort == rear
元素x进队(移动队尾指针):元素入队时,先移动指针,后存入元素
qu.rear = (qu.rear + 1)%maxsize;
qu.data[qu.rear] = x;
元素x出队(移动队首指针):元素出队时,先移动指针,再取出元素
qu.fort = (qu.fort +1)%maxsize;
x = qu.data[qu.fort];
void initQueue(SqQueue &qu)
{
qu.fort = qu.rear = 0;
}
init isQueueEmpty(SqQueue qu)
{
if(qu.fort == qu.rear)
return 1;
else
return 0;
}
init enQueue(SqQueue &qu , int x)
{
if((qu.rear+1)%maxsize == qu.fort)
return 0;
qu.rear = (qu.rar+1)%maxsize;
qu.data[qu.rear] = x;
return 1;
}
int deQueue(SqQueue &qu , int &x)
{
if(qu.fort == qu.rear)
return 0;
qu.fort = (qu.fornt+1)%maxsize;
x = qu.data[qu.fornt];
return 1;
}
链队就是采用链式存储结构存储队列(这里采用单链表实现)
lqu->rear->next = p;
lqu->rear = p;
元素出队操作:(假设x存储出队元素)
p = lqu->fort;
lqu->fort = p->next;
x = p->data;
free(p);
typedef struct
{
QNode *fornt;
QNode *rear;
}LiQueue;
void initQueue(LiQueue *&lqu)
{
lqu = (LiQueue *)malloc(sizeof(LiQueue));
lqu->fornt = lqu->rear = NULL;
}
int isQueueEmpty(LiQueue *lqu)
{
if(lqu->rear == NULL || lqu->fort == NULL)
return 1;
else
return 0;
}
void enQueue(LiQueue *lqu , int x)
{
QNode *p;
p = (QNode *)malloc(sizeof(QNode));
p->data = x;
p->next NULL;
if(lqu-rear == NULL)
lqu->fornt = lqu->rear = p;
else
{
lqu->rear->next = p;
lqu->rear = p;
}
}
int deQueue(LiQueue *lqu , int &x)
{
QNode *p;
if(lqu->rear == NULL)
return 0;
else
p = lqu->fornt;
if(lqu->fornt == lqu->rear)
lqu->fornt = lqu->rear = NULL;
else
lqu->fornt = lqu->fornt->next;
x = p->data;
free(p)
return 1;
}