数据结构之队列和栈

No.1 抽象数据类型栈的定义

栈是限定在队尾进行操作的线性表,因此对于栈来说,队尾有特殊意义,称为栈顶,表头端成为栈底,没有任何元素的栈称为空栈

特点:

  • 它是线性表
  • 这个线性表只能在栈顶操作

No.2 栈的表示

栈的先进后出原则

  • 使用栈存储数据元素,对数据元素的存和取有严格的限定,数据按照一定的顺序存储到栈中,当需要调取栈中的数据元素时,需要将该数据元素之后进栈的数据进行弹栈,该数据元素才能从栈中取出来

栈操作数据元素的方法

  • 入栈 数据元素用栈的数据结构存储起来,也叫压栈
  • 出栈 将数据元素从栈中取出来,也叫弹栈

栈的两种表示方式

  • 栈既然是一种特殊的线性表,那么它同样有线性表的两种表现形式,顺序栈和链栈

栈的上溢和下溢

  • 当栈中已经没有元素位置了,再向栈中存储数据会产生上溢,链栈不会产生上溢
  • 当栈已经是一个空栈,再继续从栈中取数据会产生下溢

No.3 实现栈

  • 顺序栈
#include <stdio.h>

//元素elem进栈
int push(int *stack, int top, int elem) {
    stack[++top] = elem;
    return top;
}

//数据元素出栈
int pop(int *stack, int top) {
    if (top == 0) {
        printf("空栈");
        return -1;
    }
    printf("弹栈元素:%d\n", stack[top]);
    top--;
    return top;
}

int main() {
    int stack[100];
    int top = 0;
    top = push(stack, top, 1);
    top = push(stack, top, 2);
    top = push(stack, top, 3);
    top = push(stack, top, 4);
    top = pop(stack, top);
    top = pop(stack, top);
    top = pop(stack, top);
    top = pop(stack, top);
    top = pop(stack, top);
    return 0;
}
  • 链栈
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

typedef struct LineStack{
    char data;
    struct LineStack * next;
}LineStack;

LineStack* push(LineStack * stack,char e){
    LineStack * line=(LineStack*)malloc(sizeof(LineStack));
    line->data=e;
    line->next=stack;
    stack=line;
    return stack;
}
LineStack * pop(LineStack * stack){
    if (stack) {
        LineStack * p=stack;
        stack=stack->next;
        printf("弹栈元素:%c ",p->data);
        if (stack) {
            printf("栈顶元素:%c\n",stack->data);
        }else{
            printf("栈已空!\n");
        }
        free(p);
    }else{
        printf("栈内没有元素!\n");
        return stack;
    }
    return stack;
}
int main() {
    LineStack * stack=NULL;
    stack=push(stack, ‘k‘);
    stack=push(stack, ‘e‘);
    stack=push(stack, ‘r‘);
    stack=push(stack, ‘n‘);
    stack=push(stack, ‘e‘);
    stack=push(stack, ‘l‘);
    stack=pop(stack);
    stack=pop(stack);
    stack=pop(stack);
    stack=pop(stack);
    stack=pop(stack);
    return 0;
}

No.4 抽象的数据类型队列的定义

  • 先进先出队列 和栈相反,队列是一种先进先出的线性表,它允许再表的一端插入数据,在另一端取出数据,这和我们日常生活中的排队打饭是一致的,最早排队的先吃到
  • 双端队列 双端队列是限定插入和删除操作在表的的两端进行的线性表,在实际应用场景中,还可以具体分为输出受限和输入受限双端队列
    • 输出受限,就是一端允许插入和删除,另一个端点允许插入
    • 输入受限就是一端允许插入和删除,另一个端点允许删除

No.5 链队列

和线性表类似,队列也有两种表示形式,用链表表示的队列成为链队列,一个链队列需要两个分别只是对头和队尾的指针

#include <stdio.h>
#include <malloc.h>
#include <windows.h>

#define TRUE 1
#define  FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2

typedef int Status;
typedef int QElemType;

typedef struct QNode {
    QElemType data;
    struct QNode *next;
} QNode, *QueuePtr;

typedef struct {
    QueuePtr front; //队头指针
    QueuePtr rear;  //队尾指针
} LinkQueue;

//构造一个空队列
Status InitQueue(LinkQueue &Q) {
    Q.front = Q.rear = (QueuePtr) malloc(sizeof(QNode));
    if (!Q.front) {
        exit(OVERFLOW);
    }
    Q.front->next = NULL;
    return OK;
}

//销毁队列
Status DestoryQueue(LinkQueue &Q) {
    while (Q.front) {
        Q.rear = Q.front->next;
        free(Q.front);
        Q.front = Q.rear;
    }
    return OK;
}

//队列入队
Status EnQueue(LinkQueue &Q, QElemType e) {
    QueuePtr p;
    p = (QueuePtr) malloc(sizeof(QNode));
    if (!p) {
        exit(OVERFLOW);
    }
    p->data = e;
    p->next = NULL;
    Q.rear->next = p;
    Q.rear = p;
    return OK;
}

Status DeQueue(LinkQueue &Q, QElemType &e) {
    QueuePtr p;
    if (Q.front == Q.rear) {
        return ERROR;
    }
    p = Q.front->next;
    e = p->data;
    Q.front->next = p->next;
    if (Q.rear == p) {
        Q.rear = Q.front;
    }
    free(p);
    return OK;
}

Status displayQueue(LinkQueue &Q) {
    QueuePtr front, rear;
    front = Q.front->next;
    rear = Q.rear;
    if (front == rear) {
        printf("空队列!\n");
        return OK;
    }
    while (front != NULL) {
        printf("%d\t", front->data);
        front = front->next;
    }
    printf("\n");
    return OK;
}

int main() {
    LinkQueue Q;
    int e;
    InitQueue(Q);
    EnQueue(Q, 10);
    EnQueue(Q, 20);
    EnQueue(Q, 30);
    EnQueue(Q, 40);
    printf("队中的元素是:\n");
    displayQueue(Q);
    DeQueue(Q, e);
    printf("出队的元素是: %d\n", e);
    printf("队中的元素是:\n");
    displayQueue(Q);
    DestoryQueue(Q);
}

No.6 循环队列

使用数组存取数据元素时,可以将数组申请的空间想象成首尾连接的环状空间使用

#include <stdio.h>
#include <malloc.h>
#include <windows.h>

#define TRUE 1
#define  FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define MAXQSIZE 100 //最大队列长度

typedef int Status;
typedef int QElemType;

typedef struct {
    QElemType *base;
    int front; //队头指针
    int rear;  //队尾指针
} SqQueue;

//构造一个空队列 Q
Status InitQueue(SqQueue &Q)
{
    Q.base = (QElemType *)malloc(MAXQSIZE*sizeof(QElemType));
    if(!Q.base) {
        exit(OVERFLOW); //存储分配
    }
    Q.front = Q.rear = 0;
    return OK;
}
Status DestroyQueue(SqQueue &Q)
{
    if(!Q.base)
    {
        printf("空队列\n");
        return OK;
    }
    free(Q.base);
    return OK;
}
int QueueLength(SqQueue Q)
{
    //返回Q的元素个数,即队列的长度
    return (Q.rear - Q.front + MAXQSIZE)%MAXQSIZE;
}
Status EnQueue(SqQueue &Q,QElemType e)
{
    //插入元素 e 为Q的新的队尾元素
    if((Q.rear+1)%MAXQSIZE == Q.front) {
        return ERROR; //队列满
    }
    Q.base[Q.rear] = e;
    Q.rear = (Q.rear + 1)%MAXQSIZE;
    return OK;
}
Status DeQueue(SqQueue &Q,QElemType &e)
{
    //若队列不空,则删除Q的队头元素,用 e 返回其值,并返回OK;
    //否知返回ERROR
    if(Q.front == Q.rear) {
        return ERROR;
    }
    e = Q.base[Q.front];
    Q.front = (Q.front + 1)%MAXQSIZE;
    return OK;
}
Status displayQueue(SqQueue &Q)
{
    int front,rear;
    front = Q.front;
    rear = Q.rear;
    if(front == rear)
    {
        printf("空队列\n");
        return OK;
    }
    while((front + 1)%MAXQSIZE != rear)
    {
        printf("%d\t",Q.base[front]);
        front++;
    }
    printf("%d\n",Q.base[front]);
    return OK;
}
int main()
{
    SqQueue Q;
    int e;
    //初始化队列
    InitQueue(Q);
    //入队
    EnQueue(Q,10);
    EnQueue(Q,20);
    EnQueue(Q,30);
    printf("循环队列中的数据为:\n");
    displayQueue(Q);
    //出队
    DeQueue(Q,e);
    printf("出队的元素是:%d\n",e);
    printf("循环队列中的数据为:\n");
    displayQueue(Q);
    //销毁队列
    DestroyQueue(Q);
    system("pause");
    return 0;
}

原文地址:http://blog.51cto.com/13559120/2317645

时间: 2024-10-10 20:49:27

数据结构之队列和栈的相关文章

数据结构之队列and栈总结分析

一.前言: 数据结构中队列和栈也是常见的两个数据结构,队列和栈在实际使用场景上也是相辅相成的,下面简单总结一下,如有不对之处,多多指点交流,谢谢. 二.队列简介 队列顾名思义就是排队的意思,根据我们的实际生活不难理解,排队就是有先后顺序,先到先得,其实在程序数据结构中的队列其效果也是一样,及先进先出.    队列大概有如下一些特性: 1.操作灵活,在初始化时不需要指定其长度,其长度自动增加(默认长度为32) 注:在实际使用中,如果事先能够预估其长度,那么在初始化时指定长度,可以提高效率    

数据结构之队列、栈

队列 ---  先进先出(FIFO) 栈 ---  后进先出(LIFO) 常见操作 1.入栈(队)2.出栈(队)3.判空4.判满5.初始化6.获取队列(栈)大小

数据结构丨队列和栈

队列 先入先出的数据结构 在 FIFO 数据结构中,将首先处理添加到队列中的第一个元素. 如上图所示,队列是典型的 FIFO 数据结构.插入(insert)操作也称作入队(enqueue),新元素始终被添加在队列的末尾. 删除(delete)操作也被称为出队(dequeue). 你只能移除第一个元素. 示例 - 队列 入队:您可以单击下面的 Enqueue 以查看如何将新元素 6 添加到队列中. ? Enqueue 出队:您可以单击下面的 Dequeue 以查看将删除哪个元素. Dequeue

数据结构-使用队列实现栈

1:考点:编程实现下面的stack,并根据stack完成queue的操作 class MyStack { void push(data); void pop(&data); bool isEmpty(); } 代码如下: #include "stdafx.h" #include<malloc.h> #include <iostream> #include <assert.h> using namespace std; /*单链表的节点,dat

模板 - 数据结构 - 单调队列/单调栈

一道例题,给定一串数字,求每连续k个数字的最大.最小值. 思路:初始化一个初始长度为k的单调队列,按从左到右加入元素,同时满足这个队列中的元素是递减的(也就是假如某个数被两个距离不超过k的大于他的数夹着,他会被从队尾调出队列).得到最大值. 向右移动一格,假如队首离开范围,出队.往队尾加入元素前,把队尾的所有比它小的元素全部出队. 得到新的最大值. #include<bits/stdc++.h> using namespace std; struct Monotone_Queue{ deque

数据结构。队列。栈。hashcode

Java数据结构和算法之栈与队列

二.栈与队列 1.栈的定义 栈(Stack)是限制仅在表的一端进行插入和删除运算的线性表. (1)通常称插入.删除的这一端为栈顶(Top),另一端称为栈底(Bottom). (2)当表中没有元素时称为空栈. (3)栈为后进先出(Last In First Out)的线性表,简称为LIFO表. 栈的修改是按后进先出的原则进行. 每次删除(退栈)的总是当前栈中"最新"的元素,即最后插入(进栈)的元素,而最先插入的是被放在栈的底部,要到最后才能删除. 图1 [示例]元素是以a1,a2,-,a

算法系列(六)数据结构之表队列和栈

在http://blog.csdn.net/robertcpp/article/details/51559333一文中,我们讲了排序,这一章来介绍一下基本数据结构:表.队列.栈和它们的简单实现 一.表ADT 1.数组实现顺序表 通过对数组操作,来直接对表进行增删查改操作,这种线性表查找某个位置的元素花费的时间为O(1),但是插入删除元素花费的时间为O(n),如果对表的操作更多的是访问操作,那么选择这种实现更为合适. 下面是一个简单实现 package com.algorithm.list; im

数据结构与算法之队列、栈

除了数组.链表,线性的数据结构中还有很重要的几种结构:队列.栈. 队列,一种先进先出的数据结构(FIFO),其实队列可以看成是一个两个口的管道,从一个口进,另一个口出,先进去的必定得在另一个口先出去,否则后面的都出不去:栈,一种后进先出的数据结构(LIFO),栈更像是只有一个口的管道,只有一个开口可以进出,先进去的在底部,所以必须得让后进去的先出去,它才能出去. 实现队列和栈可以用顺序存储结构,也可以用链式存储结构.这里采用的是链表来实现,同时还有用两个栈实现一个队列和用两个队列实现一个栈的算法