文章目录
一、栈
后进先出
1.1栈的结构和初始化
1.1.1栈的顺序存储类型描述和初始化栈
栈的插入操作叫进栈,也称入栈、压栈
栈的删除操作也叫出栈。
栈的顺序结构和初始化
#define Maxsize 50
typedef struct{
ElemType data[Maxsize];
int top //栈顶指针
}SqStack;
void InitStack (Sqstack &S){
S.top = -1;
}
2.顺序栈的基本运算
1.2.1进栈
bool Push(Sqtack &S,ElemType x){
if(S.top == Maxsize -1)
return false;
S.data[++S.top] = x //先加1,再送元素入栈
return true;
}
1.2.2判断栈空
bool StackEmpty(SqStack S){
return S.top ==-1;
}
1.2.3出栈
bool Pop(SqStack &S,ElemType &x){
if(S.top == -1)
return false;
x = S.data[S.top--]; //先取栈顶元素,再栈顶指针减一
retrun true;
}
1.2.4读取栈顶元素
bool GetTop(SqStack &S,ElemType &x){
if(S.top ==-1)
return false
x = S.data[S.top];
return true;
}
二、链栈
2.1、链栈的存储结构和初始化
2.1.1链栈的存储结构
typedef struct LNode{
ElemType data;
struct Lnode *next;
}LNode;
2.1.2链栈的初始化
void initStack(LNode *&lst){ //同步修改下面的lst
lst = (LNode*)malloc(sizeof(LNode));//申请头结点
lst->next = NULL; //后继指向空
}
2.2链栈的基本运算
2.2.1判断栈空
bool isEmpty(LNode *lst){
if(lst->next ==NULL)
return true;
else
return false;
}
2.2.2进栈
void push(LNode *lst,ElmType x){
LNode *p;
p = (LNode*)malloc(sizeof(LNode));//申请一个空间用于存放进展元素
p->data = x; //数据域
p->next = lst->next; //新插入的结点指向原来的栈顶结点
lst->next = p; //头指针指向新入栈的结点
}
/*
1.声明一结点指针p
2.申请一个新节点p
3.为p的数据域赋值
4.插入p结点:将s插入到头结点与上一结点之间
*/
我们可以用一句话来帮助记忆:声明指针建结点(LNode p;p = (LNode)malloc),数值赋给数据域(s->data = x),插入头与前点间(s->next = L->next;L->next = s)。
2.2.3出栈
bool pop(LNode *lst,ElemType &X){
if(lst->next = NULL)
return false;
LNode *p;
p = lst->next; //出栈结点
x = p->data; //出栈结点的数据域
lst->next = p->next // 将栈顶结点摘下
free(p);
return true;
}
三、队列
3.1队列的存储结构
先进先出
typedef struct{
ElemType data{Maxsize}; //一维数组存放队列元素
int front, //队头指针
rear; //队尾指针
}SqQueue;
3.2循环队列:初始化,判空
3.2.1初始化
void InitQueue(SqQueue &Q){
Q.rear = Q.front = 0;
}
3.2.2判空
bool isEmpty(SqQueue Q){
return Q.rear == Q.front;
}
3.3有头结点的链式队列
3.3.1初始化
void InitQueue(LinkList &Q){
//申请头结点
Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode));
Q.front->next = NULL
}
3.3.2判空
bool isEmpty(LinkQueue Q){
if(Q.rear== Q.front)
return true;
else
return false;
}
3.3.3入队
void EnQueue(LinkQueue &Q,ElemType X){
LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode)); //申请头结点
s->data = X;
s->next = NULL;
Q.rear->next = s; //插入队尾
Q.rear = s; //更新rear
}
/*
1.申请一个新结点s
2.为s的数据域赋值
3,插入s结点,s插入尾结点
4,更新尾结点
*/
我们可以用一句话来帮助记忆:声明指针建结点(s = (LNode*)malloc),数值赋给数据域(s->data = x),插入到尾结点后成为新的尾结点(Q.rear->next = s;Q.rear = s)。
3.3.4出队
bool DeQueue(LinkQueue &Q, ElemType &X){
if(Q.front == Q.rear)
return false;
LinkNode *p = Q.front->next //队首结点
x = p->data;
//从链表上摘下结点
Q.front->next = p->next;
if(Q.rear ==p)
Q.rear = Q.front;
free(p);
return true;
}
/*
1.判断是否为空,如果队空,出队操作不存在
2.找到队首结点,即要出队的结点
3.进行删除操作,把要删除结点的前驱的后继变为被删除的结点的后继。
*/
可以用一句话来帮助记忆:判栈空(Q.front == Q.rear),找队首(p = Q.front->next),删队首(Q.front ->next = p->next)。当然,如果链表只有一个这一个结点,则直接让头指针等于尾指针使队列为空(q.rear = Q.front),再把该结点释放。