`轻松搞定数据结构(栈和队列篇)

数据结构(栈和队列)

    • 数据结构(栈和队列)
        • 顺序栈
        • 链式栈(不代表头结点)
          • 顺序栈和链栈的比较
      • 队列
        • 顺序队列—循环队列
        • 顺序队列—非循环队列
        • 链式队列—非循环队列
      • 应用
        • 递归和子程序调用问题
        • 表达式求值
        • 二叉树的遍历(递归非递归的转换)

顺序栈

//定义
typedef struct  SeqStack{
    int stack[MAXSIZE];
    int top;
}SeqStack;
//初始化一个栈
void initStack(SeqStack &seq){
    seq.top =-1;
}
//清空一个栈
void clearStack(SeqStack &seq){
    seq.top = -1;
}
//进栈
void push(SeqStack &seq,int data){
    if (seq.top < MAXSIZE-1) {
        seq.stack[++seq.top] = data;
    }
    else{
        PerException("the stack is full");
    }
}
//出栈
int pop(SeqStack &seq){
    int data = 0;
    if (seq.top > -1) {
        data = seq.stack[seq.top--];
    }else{
        PerException("the stack is empty");
    }
    return data;
}
//查看栈顶元素
int getTop(SeqStack seq){
    if (seq.top == -1) {
        PerException("the stack is empty");
    }
    return seq.stack[seq.top];
}
//求栈的长度
int length(SeqStack seq){
    return seq.top+1;
}
//栈是否为空
bool isEmpty(SeqStack seq){
    if (seq.top == -1) {
        return true;
    }else{
        return false;
    }
}
//栈是否为满
bool isFull(SeqStack seq){
    if (seq.top == MAXSIZE -1) {
        return true;
    }else{
        return false;
    }
}
//测试数据
int main(){
    SeqStack seq ;
    initStack(seq);
    push(seq, 3);
    push(seq, 7);
    push(seq, 9);
    push(seq, 13);
    cout<cout<cout<cout<cout<return 0;
}

链式栈(不代表头结点)


//链式栈的定义(不带头结点,头插法)
//N->H->d->b->c->R
typedef struct LSNode{
    int data;
    LSNode* next;
}LSNode ,*LinkStack;

//初始化一个栈
void initStack(LinkStack &top){
    top =nullptr;
}
//清空一个栈
void clearStack(LinkStack &top){
    while (top != nullptr) {
        LSNode* p =top;
        top = top->next;
        delete p;
    }
}
//进栈
void push(LinkStack &top,int data){
    LSNode*p = new LSNode{data,top};
    top = p;
}
//出栈
int pop(LinkStack &top){
    if (top == nullptr) {
        PerException("the stack is empty");
    }
    int res = 0;
    LSNode* p = top;
    top = top->next;
    res = p->data;
    return res;
}
//查看栈顶元素
int getTop(LinkStack top){
    if (top == nullptr) {
        PerException("the stack is empty");
    }
    return top->data;
}
//求栈的长度
int length(LinkStack top){
    int count =0;
    LSNode* p =top;
    while (p!=nullptr) {
        p = p->next;
        count++;
    }
    return count;
}
//栈是否为空
bool isEmpty(LinkStack top){
    if (top == nullptr) {
        return true;
    }
    return false;
}
//栈是否为满
bool isFull(LinkStack top){
    return false;
}
//测试数据
int main(){
    LinkStack top;
    initStack(top);
    cout<" ";
    push(top, 32);
    push(top, 2);
    push(top, 3);
    cout<" ";
    cout<" ";
    cout<" " ;
    cout<cout<return 0;
}
顺序栈和链栈的比较

实现顺序站和链战的所有基本操作的算法都只需要常数时间,
因此唯一可以比较的是空间性能。
初始时顺序栈必须确定一个固定的长度,
所以有存储元素个数的限制和空间浪费的问题。
链栈没有栈满的问题,只有当内存没有可用空间时才会出现栈满,
但是每个元素都需要一个指针域,从而产生了结构性开销。
所以当栈的使用过程中元素个数变化较大时,用链栈是适宜的;
反之,应该采用顺序栈。

队列

顺序队列—循环队列

//判断队空还是堆满的三种方式
//1牺牲一个空间2标志位3长度域(代码选择第三种)
//定义循环队列
typedef struct CQueue{
    int* queue;
    int front;
    int rear;
    int length;

}CQueue;
//初始化一个空队列
void initQueue(CQueue &cQueue){
    cQueue.queue = new int[MAXSIZE];
    cQueue.front =0;
    cQueue.rear =0;
    cQueue.length =0;
}
//清空一个队列
void clearQueue(CQueue &cQueue){
    for (int i=0; iqueue[i] =0;
    }
    cQueue.front=0;
    cQueue.rear =0;
    cQueue.length =0;
}
//插入一个元素
bool enQueue(CQueue &cQueue ,int data){
    if (cQueue.length == MAXSIZE) {
        PerException("the queue is full");
    }
    cQueue.front = cQueue.front == MAXSIZE ? 0:cQueue.front;
    cQueue.queue[cQueue.front++]=data;
    cQueue.length++;
    return true;
}
//弹出一个元素
int DeQueue(CQueue &cQueue){
    if (cQueue.length == 0) {
        PerException("the queue is empty");
    }
    cQueue.rear = cQueue.rear == MAXSIZE ? 0:cQueue.rear;
    int data = cQueue.queue[cQueue.rear++];
    cQueue.length--;
    return data;
}
//求队列的长度
int length(CQueue cQueue){
    return cQueue.length;
}
//队列是否为空
bool isEmpty(CQueue cQueue){
    return cQueue.length == 0? true:false;
}
//队列是否为满
bool isFull( CQueue cQueue){
    return cQueue.length ==MAXSIZE?true:false;
}
//测试数据
int main(){
    CQueue cQueue;
    initQueue(cQueue);
    enQueue(cQueue, 1);
    enQueue(cQueue, 2);
    enQueue(cQueue, 3);
    enQueue(cQueue, 4);
    enQueue(cQueue, 5);
    //    enQueue(cQueue, 6);
    cout<" ";
    cout<" ";
    cout<" ";
    enQueue(cQueue, 6);
    cout<" ";
    cout<" ";
    clearQueue(cQueue);
    cout<" ";
    return 0;
}

顺序队列—非循环队列

//定义循环队列
typedef struct CQueue{
    //c++没有像c 中的realloc动态从新开辟内存的函数,
    //这里使用到vector容器,实现自增长。
    //其内部的是开辟新的空间,用指针指向。
    //队头移动
    vector<int> queue;
}CQueue;
//初始化一个空队列
void initQueue(CQueue &cQueue){
}
//清空一个队列
void clearQueue(CQueue &cQueue){
    cQueue.queue.clear();
}
//插入一个元素
bool enQueue(CQueue &cQueue ,int data){
    //    cQueue.front++;
    cQueue.queue.push_back(data);
    return true;
}
//弹出一个元素
int DeQueue(CQueue &cQueue){
    int data = cQueue.queue.front();
    cQueue.queue.erase(cQueue.queue.begin());
    return data;
}
//求队列的长度
int length(CQueue cQueue){
    return (int)cQueue.queue.size();
}
//队列是否为空
bool isEmpty(CQueue cQueue){
    return cQueue.queue.size() == 0? true:false;
}
//队列是否为满
bool isFull( CQueue cQueue){
    return false;
}
//测试数据
int main(){
    CQueue cQueue;
    initQueue(cQueue);
    enQueue(cQueue, 1);
    enQueue(cQueue, 2);
    enQueue(cQueue, 3);
    enQueue(cQueue, 4);
    enQueue(cQueue, 5);
    //    enQueue(cQueue, 6);
    cout<" ";
    cout<" ";
    cout<" ";
    enQueue(cQueue, 6);
    cout<" ";
    cout<" ";
    clearQueue(cQueue);
    cout<" ";
    return 0;
}

链式队列—非循环队列

//尾插法 H->a->b->c->N
//牺牲一个节点作为头结点,用来判断队列为空
//定义
typedef struct LQNode
{   int data;
    LQNode * next;
} LQNode;

typedef struct LinkQueue
{   LQNode  *front;
    LQNode  *rear;
} LinkQueue;

//初始化一个队列
void initQueue(LinkQueue &queueLink){
    LQNode* q = new LQNode;
    q->next =nullptr;
    queueLink.front =q;
    queueLink.rear =q;
}
//清空一个队列:  ClearQueue(&Q)
void clearQueue(LinkQueue &queueLink){
    while(queueLink.front != queueLink.rear){
        LQNode* p = queueLink.front;
        queueLink.front  =p->next;
        delete p;
    }
}
//插入一个元素:  EnQueue (&Q, x)
void enQueue(LinkQueue &queueLink,int data){
    LQNode* p = new LQNode{data,nullptr};
    LQNode* q  = queueLink.rear;
    q->next =p;
    queueLink.rear = p;
}
//删除一个元素:  DeQueue(&Q, &x)
bool deQueue(LinkQueue &queueLink){
    if (queueLink.front == queueLink.rear) {
        PerException("the queue is empty");
    }
    LQNode* p = queueLink.front;
    LQNode* q = p->next;
    p->next = q->next;
    delete q;
    return true;
}
//求表的长度:  QueueLength(Q)
int length(LinkQueue queueLink){
    LQNode* p = queueLink.front;
    int count = 0;
    while (p->next != nullptr) {
        p=p->next;
        count++;
    }
    return count;
}
//队列是否为空:boolean QueueEmpty( Q )
bool isEmpty(LinkQueue queueLink){
    return queueLink.front == queueLink.rear ? true:false;
}
//队列是否为满:boolean QueueFull( Q )
bool isfull(LinkQueue queueLink){
    return false;
}
//测试数据
int main(){
    LinkQueue queueLink;
    initQueue(queueLink);
    cout<<"isEmpty:"<1);
    enQueue(queueLink, 2);
    enQueue(queueLink, 3);
    enQueue(queueLink, 4);
    cout<<"length:"<cout<<"dequeue:"<cout<<"length:"<cout<<"isEmpty:"<cout<<"isEmpty:"<5);
    cout<<"length:"<return 0;
}

应用

递归和子程序调用问题

递归和子程序的调用都是系统在压栈,每一次调用递归程序,
系统都会把该函数的所有信息(行号,函数名,参数,启用调用下次函数之前的所有数据)压入栈中

表达式求值

请参考文章:https://blog.csdn.net/opooc/article/details/81188065

二叉树的遍历(递归非递归的转换)

请参考文章:https://blog.csdn.net/opooc/article/details/81187855

你可能感兴趣的:(计算机基础,数据结构,轻松搞定,数据结构,栈,队列)