一.栈

1.基本概念

  • 也称堆栈,进栈和出栈都在栈顶实现,要求先进后出。
  • 初始化栈:Initstack(&s)
  • 进栈函数:push(&s,e)将元素插入到栈s中作为栈顶的元素
  • 出栈函数:pop(&s,&e)从栈s中退出栈顶元素,并将其赋值给e

2.栈的顺序存储结构

  • 栈空条件:top=-1
  • 栈满条件:top=MaxSize-1
  • 进栈e操作:top++;将e放在top处
  • 退栈操作:从top处取出e,top--
#include<stdio.h>
#include<stdib.h>
#include<io.h>
#include<math.h>#define OK 1
#define ERROR 0
#definr TRUE 1
#define FALSE 0
#define maxsize  //储存空间初始分配量//顺序栈的结构体
typedef struct
{selemtype data[maxsize];int top;//用于栈顶指针
}sqstack;          status visit(selemtype c)
{printf("%d",c);return OK;
}//构造空栈
stasus initstack(sqstacl *s)
{s->top=-1;return OK;
}//将s置空
status clearstack(sqstack *s)
{s->top=-1;return ok;
}//若栈s为空栈,则返回TRUE,否则返回FALSE
status stackempty(sqstack s)
{if (s.top==-1)return TRUE;elsereturn FALSE;
}//返回s栈的长度
int stscklength(sqstack s)
{return s.top+1;
}//若栈不为空,则用e返回s的栈顶元素,并返回OK,否则返回ERROR
ststus gettop(sqstack){if(s.top==-1)return ERROR;else   *e=s.date[s.top];return OK;
}//插入元素e为新的栈顶元素
status push(sqstack *s,selemtype e)
{if(s->top==maxsize-1)  //如果栈满了,就不能在插入元素{return ERROR;}s->top++;  //栈顶指针增加1s->data[s->top]=e;//将新插入元素赋给栈顶空间return OK;
}//若栈不为空,则删除s的顶元素,用e返回其值,并返回OK;否则返回ERROR
status pop(sqstack *s,selemtype *e)
{if(s->top==-1)return ERROR;*e=s->data[s-]
}//从栈底到栈顶依次对栈中的每个元素进行打印
status stacktraverse(sqstack s)
{int i;i=0;while(i<=s.top){visit(s.data[i++]);}printf("\n");return OK;}int main()
{int j;sqstack s;int e;if(initstack(&s)==OK)for(j=1;j<=10;j++)push(&s,j);printf("栈中元素依次为:");stacktraverse(s);pop(&s,&e);printf("栈顶元素 e=%d\n",e);printf("栈空否:%d(1:空 0:否)\n",stackempty(s));gettop(s,&e);printf("栈顶元素 e=%d 栈的长度为%d\n",e,stacklength(s));clearstack(&s);printf("清空栈后,栈空否:%d(1:空 0:否)\n",stackempty(s));return 0;
}

3.两栈共享空间

操作说明的和一个栈的类似,区别就是一个空间分为两个栈,第一个栈从头开始,第二个栈从尾开始,当两个栈相遇的时候就是栈满(不能再插入的时候)。

4.栈的链式存储结构

链式栈和顺式栈的区别在于,顺式栈的空间是固定的、连续的,就像数组一样;而链式栈不要求用连续存储的一块空间去存储数据,因而为了知道栈中完整的元素,需要定义两个成员,一个是数据成语存放数据,另一个是指针成员,存放下一个元素的地址(这里的链式栈就和指针类似);为了操作方便,一般将栈顶放在单链表的头部。通常对于链栈来说,不需要头结点。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#define ERROR 0
#define OK 1
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int EleType;
typedef struct StackNode {EleType data;//结点数据域struct StackNode* next;//结点指针域
}StackNode,* LinkStackPoi;
//链栈的数据结构
typedef struct LinkStack {LinkStackPoi top;//栈顶结点int count;//元素个数
}LinkStack;
//初始化
Status InitLinkStack(LinkStack* stack)
{if (!stack){return ERROR;}stack->top = NULL;stack->count = 0;return OK;
}
//清空数据,释放结点内存,实际上就是pop所有数据
Status ClearLinkStack(LinkStack* stack)
{if (!stack||!stack->count){return   ERROR;}while (stack->count){StackNode* node = stack->top;stack->top = node->next;free(node);stack->count--;}return OK;
}
//判断链栈是否为空
Status EmptyLinkStack(LinkStack* stack) {if (!stack){return ERROR;}return stack->count == 0 ? 1 : 0;
}
//获取元素个数
int GetLengthLinkStack(LinkStack* stack)
{if (!stack ){return    -1;}return stack->count;
}
Status GetTop(LinkStack* stack, StackNode** stackNode)
{if (!stack){return ERROR;}*stackNode = stack->top;//将栈顶元素的指针返回,获取指向可修改栈顶元素内容。return OK;
}
/*
弹栈
栈顶指针指向要弹出元素前置结点,然后释放弹出元素内存空间,然后count-1
*/
Status pop(LinkStack* stack,EleType *e)
{if (!stack && stack->count){return  ERROR;}StackNode* node = stack->top;*e = node->data;stack->top = node->next;//栈顶指针指向新的栈顶元素free(node);//释放元素空间stack->count--;return OK;
}
/*
压栈
先将压入元素放入到链表表中,然后再将栈顶指针指向压入的元素,然后count+1.
*/
Status push(LinkStack* stack,EleType e)
{if (!stack){return ERROR;}StackNode* node = (StackNode*)malloc(sizeof(StackNode));node->next = stack->top;//将元素加入链表中node->data = e;stack->top = node;//栈顶元素指向压入元素stack->count++;return OK;
}
void PrintfLinkStack(LinkStack* stack)
{if (!stack&&stack->count){return;}StackNode* node = stack->top;while (node){printf("%d,", node->data);node = node->next;}puts("");return;
}
int main(int argc, char *argv[])
{LinkStack stack;InitLinkStack(&stack);//初始化push(&stack, 1);push(&stack, 2);push(&stack, 3);push(&stack, 4);push(&stack, 5);puts("链栈元素:");PrintfLinkStack(&stack);printf("链栈元素个数:%d\n", GetLengthLinkStack(&stack));EleType e1,e2;pop(&stack, &e1);printf("弹出第一个元素:%d\n", e1);pop(&stack, &e2);printf("弹出第二个元素:%d\n", e2);puts("链栈元素:");PrintfLinkStack(&stack);printf("链栈元素个数:%d", GetLengthLinkStack(&stack));printf("\n");return 0;
}

5.栈的应用---递归

递归从狭义上来讲,指的是计算机科学中(也就是像各位程序猿都熟悉的那样),一个模块的程序在其内部调用自身的技巧。如果我们把这个效果视觉化就成为了「德罗斯特效应」,即图片的一部分包涵了图片本身。

斐波那契数列(Fibonacci)

递归的实现

int fibonacci(int num) {if(num < 2)return num == 0 ? 0 : 1;return fibonacci(num - 1) + fibonacci(num - 2);
}

二.队列

1.基本概念

队列是只允许在一端进行插入操作,在另一端进行删除操作的线性表。它是一种基于先进先出(First In First Out,简称FIFO)策略的集合类型。允许插入的一端称为队尾,允许删除的一端称为队头。

2.队列的顺序存储结构

与栈不同的是,队列元素的出列是在队头,即下表为0的位置。为保证队头不为空,每次出队后队列中的所有元素都得向前移动,此时时间复杂度为 O(n)。此时队列的实现和线性表的顺序存储结构完全相同;

#include "stdio.h"
#include "stdlib.h"
#include "io.h"
#include "math.h"
#include "time.h"#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存储空间初始分配量 */typedef int Status;
typedef int QElemType; /* QElemType类型根据实际情况而定,这里假设为int *//* 循环队列的顺序存储结构 */
typedef struct
{QElemType data[MAXSIZE];int front;     /* 头指针 */int rear;      /* 尾指针,若队列不空,指向队列尾元素的下一个位置 */
}SqQueue;Status visit(QElemType c)
{printf("%d ",c);return OK;
}/* 初始化一个空队列Q */
Status InitQueue(SqQueue *Q)
{Q->front=0;Q->rear=0;return  OK;
}/* 将Q清为空队列 */
Status ClearQueue(SqQueue *Q)
{Q->front=Q->rear=0;return OK;
}/* 若队列Q为空队列,则返回TRUE,否则返回FALSE */
Status QueueEmpty(SqQueue Q)
{ if(Q.front==Q.rear) /* 队列空的标志 */return TRUE;elsereturn FALSE;
}/* 返回Q的元素个数,也就是队列的当前长度 */
int QueueLength(SqQueue Q)
{return  (Q.rear-Q.front+MAXSIZE)%MAXSIZE;
}/* 若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR */
Status GetHead(SqQueue Q,QElemType *e)
{if(Q.front==Q.rear) /* 队列空 */return ERROR;*e=Q.data[Q.front];return OK;
}/* 若队列未满,则插入元素e为Q新的队尾元素 */
Status EnQueue(SqQueue *Q,QElemType e)
{if ((Q->rear+1)%MAXSIZE == Q->front)  /* 队列满的判断 */return ERROR;Q->data[Q->rear]=e;         /* 将元素e赋值给队尾 */Q->rear=(Q->rear+1)%MAXSIZE;/* rear指针向后移一位置, *//* 若到最后则转到数组头部 */return  OK;
}/* 若队列不空,则删除Q中队头元素,用e返回其值 */
Status DeQueue(SqQueue *Q,QElemType *e)
{if (Q->front == Q->rear)           /* 队列空的判断 */return ERROR;*e=Q->data[Q->front];               /* 将队头元素赋值给e */Q->front=(Q->front+1)%MAXSIZE;   /* front指针向后移一位置, *//* 若到最后则转到数组头部 */return  OK;
}/* 从队头到队尾依次对队列Q中每个元素输出 */
Status QueueTraverse(SqQueue Q)
{ int i;i=Q.front;while((i+Q.front)!=Q.rear){visit(Q.data[i]);i=(i+1)%MAXSIZE;}printf("\n");return OK;
}int main()
{Status j;int i=0,l;QElemType d;SqQueue Q;InitQueue(&Q);printf("初始化队列后,队列空否?%u(1:空 0:否)\n",QueueEmpty(Q));printf("请输入整型队列元素(不超过%d个),-1为提前结束符: ",MAXSIZE-1);do{/* scanf("%d",&d); */d=i+100;if(d==-1)break;i++;EnQueue(&Q,d);}while(i<MAXSIZE-1);printf("队列长度为: %d\n",QueueLength(Q));printf("现在队列空否?%u(1:空 0:否)\n",QueueEmpty(Q));printf("连续%d次由队头删除元素,队尾插入元素:\n",MAXSIZE);for(l=1;l<=MAXSIZE;l++){DeQueue(&Q,&d);printf("删除的元素是%d,插入的元素:%d \n",d,l+1000);/* scanf("%d",&d); */d=l+1000;EnQueue(&Q,d);}l=QueueLength(Q);printf("现在队列中的元素为: \n");QueueTraverse(Q);printf("共向队尾插入了%d个元素\n",i+MAXSIZE);if(l-2>0)printf("现在由队头删除%d个元素:\n",l-2);while(QueueLength(Q)>2){DeQueue(&Q,&d);printf("删除的元素值为%d\n",d);}j=GetHead(Q,&d);if(j)printf("现在队头元素为: %d\n",d);ClearQueue(&Q);printf("清空队列后, 队列空否?%u(1:空 0:否)\n",QueueEmpty(Q));return 0;
}

3.队列的链式存储空间

队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已。

三.总结

栈限定仅能在栈顶进行插入和删除操作,而队列限定只能在队尾插入,在队头删除。它们都可以使用顺序存储结构和链式存储结构两种方式来实现。对于栈来说,若两个栈数据类型相同,空间需求相反,则可以使用共享数组空间的方法来实现,以提高空间利用率。

数据结构--队列与栈相关推荐

  1. 数据结构-队列和栈有什么区别

    数据结构-队列和栈有什么区别 1:队列和栈是两种不同的数据结构.它们有以下区别: (1)操作的名称不同.队列的插入称为入队,队列的删除称为出队.栈的插入称为进栈,栈的删除称为出栈. (2)可操作的方式 ...

  2. 数据结构-队列和栈的那些事(三)

    一.队列和栈 什么是队列?队列是一种只能在一端插入,另外一端删除的有序线性表,队列中第一个插入也就第一个被移除,所以队列是一种先进先出的线性表: 什么是栈?栈是一种有序线性表,只能在表的一端进行插入和 ...

  3. 数据结构 —— 队列、栈、链表的区别

    一.定义 1.1.队列 队列,顾名思义,就像排队一样,排在队首的人,可以先领东西,后面的人,只能等前面人领过后才轮到自己. 队列是一种先进先出(FIFO)的数据结构. 1.2.栈 栈,可以理解为 只有 ...

  4. python优先队列,队列和栈

    打印列表的疑问 class Node:def __str__(self):return "haha"print([Node(),Node()]) print(Node()) 输出为 ...

  5. c++数据结构队列栈尸体_一本正经的聊数据结构(3):栈和队列

    前文传送门: 「一本正经的聊数据结构(1):时间复杂度」 「一本正经的聊数据结构(2):数组与向量」 引言 前一篇内容我们介绍了数组和向量,虽然说向量是数组的一个升级版,但是在另一个维度上,他们都属于 ...

  6. 简单数据结构(队列 栈 树 堆 )

    基础知识 基本概念 程序 = 算法 + 数据结构数据结构是计算机存储.组织数据的方式.数据结构是指相互之间存在一种或多种特定关系的数据元素的集合.通常情况下,精心选择的数据结构可以带来更高的运行或者存 ...

  7. SDUT-2449_数据结构实验之栈与队列十:走迷宫

    数据结构实验之栈与队列十:走迷宫 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 一个由n * m 个格子组成的迷宫,起 ...

  8. sdut 2088 数据结构实验之栈与队列十一:refresh的停车场

    数据结构实验之栈与队列十一:refresh的停车场 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem ...

  9. sdut 1479 数据结构实验之栈与队列九:行编辑器

    数据结构实验之栈与队列九:行编辑器 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Descript ...

最新文章

  1. EJB3.1 JBoss7.1 Eclipse3.7
  2. 不得不了解系列之限流
  3. 《北京作家》·史铁生·维格拉姆
  4. 初级Java开发工程师!绝密文档,面试手册全面突击!!!秋招已经到来
  5. 随机化快速排序+快速选择 复杂度证明+运行测试
  6. 一般处理程序(ashx)和页面处理程序(aspx)的区别
  7. android sha1和签名证书的学习
  8. 用python海龟制图画花瓣_Python竟能画这么漂亮的花,帅呆了(代码分享)
  9. c语言编程作业 一哥是何人,PLC编程语言之争:谁才是quot;一哥quot;-简易百科
  10. css02基本选择器
  11. 天若OCR专业版软件,现可无需联网本地使用了~
  12. 【项目管理/PMP/第六版/新考纲】纯干货!项目发展史/项目定义/项目集/项目组合/十五至尊图
  13. 第一节 电 电流 电压 电路 基本电子元件
  14. mysql执行计划explain介绍_MySQL中的执行计划explain详解
  15. Git 笔记 - git cherry-pick
  16. php给发qq消息,PHP 模拟QQ登录及发送消息实现方法
  17. 计算机组装配置(2019年 CPU及显卡天梯图)
  18. 原子的波尔模型、能量量子化、光电效应、光谱实验、量子态、角动量
  19. C#编写的Word操作类,有换页,添加表格,文本功能
  20. 047 中值定理之型四(ξ η复杂度不同,留复杂中值项);型五泰勒公式之核心关键取x0,x

热门文章

  1. oracle awr top5,ORACLE AWR简介
  2. 一个简单的《弹球游戏》
  3. Javascript中Blob介绍
  4. fix协议的服务器,Fix8
  5. 弱电转网工,我是如何通过学习考取HCIP成为职业网工
  6. 2023年4月份中旬自学考试总结
  7. 编程突然光标变粗变黑解决办法
  8. 出现 “java”不是内部或外部命令,也不是可运行程序或批处理文件的问题
  9. bootstrap按钮下拉菜单
  10. 毕业论文相关工具、格式、细节