数据结构栈和队列的基本操作

一、栈

后进先出

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),再把该结点释放。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值