基础数据结构——栈,队列

栈的定义

栈(stack)又名堆栈,一种可以实现”先进后出”的存储结构,栈类似于箱子它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。栈的运算主要有置空栈、判栈空、判栈满、进栈、退栈、和取栈顶元素6种。

基本算法

进栈(PUSH)算法

①若TOP≥n时,则给出溢出信息,作出错处理(进栈前首先检查栈是否已满,满则溢出;不满则作②);

②置TOP=TOP+1(栈指针加1,指向进栈地址);

③S(TOP)=X,结束(X为新进栈的元素);

退栈(POP)算法

①若TOP≤0,则给出下溢信息,作出错处理(退栈前先检查是否已为空栈, 空则下溢;不空则作②);

②X=S(TOP),(退栈后的元素赋给X):

③TOP=TOP-1,结束(栈指针减1,指向栈顶)。

 
C++代码实现

#include <iostream>
#include <stdio.h>
#include <malloc.h>
 
class SqStack{
 
private:
enum { MaxSize = 100 };
 
int data[MaxSize];
 
int top;
 
public:
 
SqStack();
 
~SqStack();
 
bool isEmpty();
 
void pushInt(int x);
 
int popInt();
 
int getTop();
 
void display();
 
};
 
SqStack::SqStack()
 
{
 
	top = -1;
 
}
 
SqStack::~SqStack() {}
 
bool SqStack::isEmpty(){  //判断栈为空
 
	return(top == -1);
 
}
 
void SqStack::pushInt(int x){  //元素进栈
 
	if (top == MaxSize - 1){
		std::cout << "栈上溢出!" << std::endl;
 
	}else{
		++top;
		data[top] = x;
	}
}
 
int SqStack::popInt(){   //退栈
 
	int tmp = 0;
	if (top == -1){
		std::cout << "栈已空!" << std::endl;
	}else{
		tmp = data[top--];
	}
	return tmp;
}
 
int SqStack::getTop(){  //获得栈顶元素
 
	int tmp = 0;
	if (top == -1){
		std::cout << "栈空!" << std::endl;
	}else{
		tmp = data[top];
	}
 
	return tmp;
 
}
 
void SqStack::display(){  //打印栈里元素
 
	std::cout << "栈中元素:" << std::endl;
 
	for (int index = top; index >= 0; --index){
		std::cout << data[index] << std::endl;
 
	}
 
}
 
int main(){
 
	SqStack st;
 
	std::cout << "栈空:" << st.isEmpty() << std::endl;
 
	for (int i = 1; i < 10; i++){
		st.pushInt(i);
	}
 
	st.display();
	std::cout << "退一次栈" << std::endl;
	st.popInt();
	std::cout << "栈顶元素:" << st.getTop() << std::endl;
	st.popInt();
	st.display();
	return 0;
 
}

队列

队列定义

       队列(Queue)。队列简称队。是一种操作受限的线性表只允许在表的一端进行插入,而在表的另一端进行删除。向队列中插入元素称为入队或进队;删除元素称为出队或离队。其操作特性为先进先出(First In First Out,FIFO),并且只允许在队尾进,队头出。队列的基本操作有:初始化队列,构造一个空队列Q;判断一个队列是否为空;入队,若队列未满,则将x加入使之成为新队尾;出队,若队列非空,则将队首元素删除,并用x返回;读队头元素,若栈顶元素非空,则用x返回栈顶元素
 

 

循环队列

       将队列臆造成一个环状的空间,即把存储队列元素的表从按逻辑上视为一个环,称为循环队列。当队首指针 Q.front == MAXSIZE - 1,再前景一个位置就自动到0,这可以利用除法取余运算(%) 来实现

循环队列的操作

初始化

void InitQueue(SqQueue& Q){
    Q.front = Q.rear = 0;
}

判断队空

bool QueueEmpty(SqQueue Q){
    if( Q.front == Q.rear){
        return true;
    }
    return false;
}

入队

bool EnQueue(SqQueue& Q, ElemType x){
    if( (Q.rear + 1) % MAXSIZE == Q.front ){
        return false;
    }
    Q.data[Q.rear] = x;
    Q.rear = ( Q.rear + 1) % MAXSIZE;//队尾指针加1取模,这步操作很容易写错
    return true;    
}

出队

bool DeQueue(SqQueue& Q, ElemType &x){
    if( Q.rear == Q.front ){
        return false;
    }
    x = Q.data[Q.front];
    Q.front = (Q.front + 1) % MAXSIZE;//队头指针加1取模
    return true;
}

链式队列的基本操作

初始化

void InitQueue(LinkQueue& Q){
    //初始化时,Q.front 和 Q.rear 同时指向头结点
    Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode));
    Q.front->next = nullptr;
}

判断队空

bool QueueEmpty(LinkQueue Q){
    if( Q.front == Q.rear){
        return true;
    }
    return false;
}

入队

bool EnQueue(LinkQueue& Q, ElemType x){
    LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode));
    s->data = x;
    s->next = nullptr;
    Q.rear->next = s;
    Q.rear = s;
    return true;    
}

出队

bool DeQueue(LinkQueue& Q, ElemType &x){
    if( Q.rear == Q.front ){
        return false;
    }
    LinkNode* p = Q.front->next; //因为有头结点,所以队头节点为Q.front->next
    x = p->data;
    Q.front->next = p->next;
    if( Q.rear == p ){           //只剩一个结点,删除后变空只剩头结点
        Q.rear = Q.front;
    }
    free(p);
    return true;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DDsoup

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值