这几天总结了C语言的队列,栈的实现方法,在此总结一下:
一、栈
首先从栈开始,诚然,相信学习过数据结构的你,肯定应该知道栈是什么东西了,如果不知道也没事每一句话我就可以帮你总结--数据
只在栈顶进行插入和删除操作,数据进出栈符合先进后出或者后进先出的原则。来贴个图片,你就知道了。

  再也没有比上述图片更能贴切的描述栈了,数据结构中的栈和程序运行压栈的栈还略有区别,在此先不说那么多,继续回归正题。栈的应用很多,你最可能会用到的一个就是10进制转换2进制数了,具体怎么应用,请亲爱的你动手试试哦!
接下来我就介绍栈的几种实现方法:
1.固定栈
  固定栈是最简单的一种了,要点就2个,一是注意栈满,二是注意要符合先进后出的原则。在这两点的基础上,就可以自己动手写一个栈空间实现
程序,这里我就介绍那么多了,因为这个实在是太简单了,代码中我也都作了详细地说明。

 # include "stdio.h"
# include "stdlib.h" # define MAX_STACK_SIZE //定义栈空间的最大存储内存
# define ERROR //错误标志
# define OK typedef struct sqstack{ //封装一个结构体,包括定义的栈存储数组,栈顶和栈底标志
int stack_array[MAX_STACK_SIZE];
int top;
int bottom;
}SqStack; SqStack SqStack_Init(void) //初始化一个栈内存
{
static SqStack S;
S.top = S.bottom = ;
return S;
} int Push_Stack(SqStack *S) //压栈操作
{
int ele;
if(S->top == MAX_STACK_SIZE-)
{
return ERROR;
}
scanf("%d",&ele);
S->stack_array[S->top] = ele;
S->top+=;
return OK;
} int Pop_Stack(SqStack *S) //出栈操作
{
if(S->top != )
S->top--;
printf("%d ",S->stack_array[S->top]);
} int main(void)
{
int ele;
int i = ;
SqStack MyStack = SqStack_Init();
while()
{
system("cls");
printf("***************静态栈空间模拟实现*******************\n") ;
printf("请输入元素!(元素进栈)");
for(i=;i<;i++) //压三次栈
Push_Stack(&MyStack);
printf("元素出栈\n");
for(i=;i<;i++) //出三次栈
Pop_Stack(&MyStack);
system("pause") ;
}
return ;

2.动态链栈
这是完全采用链表的形式实现一个栈空间,稍微有点麻烦,你可以选择该栈没有上限,只要你一直输就一直开辟栈空间,
并且进行数据存储,不过这显然是不符合实际的,所以我加了个stack_size变量,为该栈设置了上限,具体的代码如下:

 # include"stdio.h"
# include "stdlib.h" # define Stack_Size typedef struct stack{
int ele;
int stack_size;
struct stack *next;
}Stack,* Pstack; //动态链栈的实现,每个节点可以存储一个栈点元素, 因此首先需要一个数据区,然后就是一个指针区,首先是一个链表,其次才是一个栈
//且应该定义一个top和bottom指针,来指向栈底,和栈顶,这样才能辅助来进行完成链栈的实现。 Pstack Top;
Pstack Bottom; void Creat_StackNode(void) //创建一个栈底。并且定义这个栈底不允许释放。
{
Top = (Pstack)malloc(sizeof(Stack));
Bottom = Top;
scanf("%d",&Top->ele); //写入栈底元素
Top->stack_size=;
Top->next = NULL;
printf("栈底建立成功\n");
} void PushStack(void)
{
Pstack pnew = (Pstack)malloc(sizeof(Stack));
pnew->next = Top; //新建一个节点,指针指向前一个节点,其实这就是在连接一个链表,然后再让Top指向新建的节点。
scanf("%d",&pnew->ele);
pnew->stack_size=Top->stack_size + ;
Top = pnew;
} void PopStack(void)
{
Pstack ptemp = Top->next; //这个其实跟链表的删除一样,因为你要释放掉这个节点,所以必须提前保存该节点的下一个指向,然后才能释放带该节点
printf("%d\n",Top->ele); //将节点元素打印出来。
free(Top); //释放节点空间,也就是出栈,
Top = ptemp; //再将top指针指向新的栈顶 。
} int main(void)
{
int sel;
int i = ;
printf("创建链栈的头节点!");
Creat_StackNode(); //这个是链栈的最底部空间,不允许释放。
while()
{
printf("请选择是压栈还是出栈!(1.入 2.出)");
scanf("%d",&sel);
if(sel == )
{
if(Top->stack_size > Stack_Size-)
printf("栈内存已满了!") ;
else
PushStack(); //将数据压入链栈
}
else if(sel == )
{
if(Top->stack_size == )
{
printf("%d\n",Top->ele);
printf("已经到达栈底,禁止继续弹出数据! ") ;
}
else
PopStack(); //将数据弹出栈
}
else
{
printf("选择输入错误,请重新输入:");
fflush(stdin) ;
}
}
return ;
}

二、队列
队列和栈是近似的,也是一种存储空间吧,不过它的存储与栈刚好相反,符合先进先出的原则。队列的首尾成为队首和队尾
元素在队尾实现入队,在队首实现出队,详情请看下图--形象的比喻:水从水管的一端进入,另一端出去。。

              

队列的实现有以下三种,
1.静态队列
  类似上述静态栈的构建,不过这种的入队和出队都是向一个方向进行,在有限的空间内很容易造成空间的浪费因此用途并不广泛,再次我也就不举例了,太简单了。

2.静态循环队列
  这就是 一个很好的队列实现方式了,使用循环的方式,能够节省空间,因此,使用较为广泛,实现起来也略微有点麻烦,首先来看下循环队列的结构示意图,或许你会更理解:

              

具体的代码如下,供参考,代码中也有了十分详细的注释:

 # include "stdio.h"

 # define QUEUE_SIZE 

 typedef struct  queue{
int queue_array[QUEUE_SIZE];
int front;
int rear;
}Queue,*Pqueue;
//由于队列无论是入队还是出队都是只能像一个方向增长的操作,因此单向静态队列的用途不是很大, 同场有用的是静态循环队列和动态队列。
//该部分介绍一个静态循环队列。
//静态循环队列,是一个将队头和队尾链接在一起的队列,队列空间能够循环使用,因此空间利用率高,使用比较广泛 Pqueue Init_Queue(void) //初始化一个队列
{
static Queue queue;
queue.front = ;
queue.rear = ;
return &queue;
} /*接下来就是插入都列,和出队列了,这两个操作其实并不难,唯一的难点就在于临界状态的判断,有两个临界状态, 第一个就是队首不动,空间插入满,队尾追上了队首
另外一个难点就是出队列队首追上了队尾,表示队尾已经空。因此确定了两个判断条件是 (rear+1)%size == front.表示队列满了,如果,(front)%size == front
则表示队列已经空了,并且这其中,默认rear所指向向的空间一直为空*/
void InputQueue(Pqueue MyQueue)
{
if((MyQueue->rear+)%QUEUE_SIZE == MyQueue->front) //这一步骤的运算可以称得上是神来之笔
{
printf("队列已满,不允许插入!\n");
return;
}
else
{
scanf("%d",&MyQueue->queue_array[MyQueue->rear]);
MyQueue->rear = (MyQueue->rear+)%QUEUE_SIZE;
printf("插入成功!\n");
}
} void OutPutQueue(Pqueue MyQueue)
{
if(MyQueue->front==MyQueue->rear)
{
printf("队列已空,请勿继续进行删除操作!\n");
return;
}
else
{
printf("%d\n",MyQueue->queue_array[MyQueue->front]);
MyQueue->front = (MyQueue->front+)%QUEUE_SIZE;
printf("删除成功!\n");
}
} int main(void)
{
int i = ;
int sel;
Pqueue MyQueue; MyQueue = Init_Queue();
while()
{
system("cls");
printf("请输入选择: 1.插入 2.删除!!! ");
scanf("%d",&sel); if(sel ==)
{
InputQueue(MyQueue);
sel = ;
}
else if(sel == )
{
OutPutQueue(MyQueue);
sel = ;
}
system("pause");
}
return ;
}

3.链式队列

  队列的实现同样可以使用链的方式来构建完成,一旦牵扯到链,那么队列也就非常灵活了,不多啰嗦,直接看代码。

 # include "stdio.h"
# include "stdlib.h" typedef struct queue{ //封装一个队列节点的结构体
int ele;
struct queue *next;
}Dqueue,*Pqueue; Pqueue Rear; //定义队首指针和队尾指针。
Pqueue Front; void Init_Queue(void) //初始化队的开始,该部分空间不允许释放,否则会丢失队列的指针。
{
Pqueue phead = (Pqueue)malloc(sizeof(Dqueue));
phead->next = NULL;
printf("请输入第一个队列元素:");
scanf("%d",&phead->ele);
Rear = phead; //开始时队首指针和队尾指针都指向该节点。
Front = phead;
printf("构建成功!\n");
} void Input_Queue(void) //入队操作。
{
Pqueue pnew = (Pqueue)malloc(sizeof(Dqueue));
if(pnew == NULL)
printf("空间申请失败");
else
{
scanf("%d",&pnew->ele);
pnew->next = NULL; //入队操作时一个在头结点前插入的操作,对于新申请的堆空间必须要设置其指针域和数据域,缺一不可。
Rear->next = pnew; /*该步十分关键,!!!为何这么说,它指定了新创建的前一个节点的指向是新建的节点,也就确定一条由下向上的的
链式指向,因为这一步,Bottom指针才能一次向上访问节点,进行出队操作。*/
Rear = pnew; //使队尾指针指向最末尾节点。
printf("入队成功\n");
}
} void Output(void) //出队操作
{
Pqueue ptemp;
if(Front == Rear) //这就是队空标志,只允许弹出这个节点元素,不允许改变指针指向和释放改空间,否则队列指针将没有指向,还得重新构建
{
printf("%d",Front->ele);
printf("队列已经空,请禁止继续出队\n");
}
else
{
ptemp = Front->next; //同时这也是一个释放链式节点的操作,先让暂存指针保存,释放节点的指向,
printf("%d",Front->ele); //然后打印出释放节点的节点数值
free(Front); //释放该节点
Front = ptemp; //然后重新保存暂存指针,这样队首指针就向上移动一个节点。
printf("出队成功\n");
}
} int main(void)
{
int sel;
Init_Queue(); while()
{
printf("请选择入队还是出队!1.入队 2.出队: ");
scanf("%d",&sel);
if(sel == )
{
Input_Queue();
sel = ;
}
else if(sel == )
{
Output();
sel = ;
}
}
return ;
}

  至此,栈和队列已经总结完毕,其实说难也不难,只是刚学的你,可能会稍微有点绕,希望能帮到诸位!

【C_Language】---队列和栈的C程序实现的更多相关文章

  1. 【三支火把】---队列和栈的C程序实现

    这几天总结了C语言的队列,栈的实现方法,在此总结一下:一.栈 首先从栈开始,诚然,相信学习过数据结构的你,肯定应该知道栈是什么东西了,如果不知道也没事每一句话我就可以帮你总结--数据只在栈顶进行插入和 ...

  2. C语言算法系列---1.队列和栈

    写在前面:在家玩了好久,实在是不知道干嘛了,突然想找些事做,现在是时候做些什么了.这些东西不见得多高深,也可能很简单,但很基础,也无法忽视.同时,也是自己学习走过的一条路. 这是开头,就写写C的队列和 ...

  3. POJ 1879 Tempus et mobilius Time and motion 队列和栈

    很简单的队列和栈的应用,不过读明白题意非常重要:(直接引用白书的题解)三个轨道,一个库.分别是分钟单位的轨道,5min单位的轨道,一小时单位的轨道,还有就是n容量的库.每过一分钟,一个小球从库里面出来 ...

  4. 深入浅出数据结构C语言版(7)——特殊的表:队列与栈

    从深入浅出数据结构(4)到(6),我们分别讨论了什么是表.什么是链表.为什么用链表以及如何用数组模拟链表(游标数组),而现在,我们要进入到对线性表(特意加了"线性"二字是因为存在多 ...

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

    一.前言: 数据结构中队列和栈也是常见的两个数据结构,队列和栈在实际使用场景上也是相辅相成的,下面简单总结一下,如有不对之处,多多指点交流,谢谢. 二.队列简介 队列顾名思义就是排队的意思,根据我们的 ...

  6. day-25-类的继承顺序-父类对子类的约束-多态-队列和栈

    一.类的继承顺序 只要继承object类就是新式类 不继承object类的都是经典类 在python3 中所有的类都继承object类,都是新式类 在python2 中不继承object的类都是经典类 ...

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

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

  8. JavaScript数据结构,队列和栈

    在JavaScript中为数组封装了大量的方法,比如:concat,pop,push,unshift,shift,forEach等,下面我将使用JavaScript提供的这些方法,实现队列和栈的操作. ...

  9. 225 Implement Stack using Queues(用队列实现栈Medium)

    题目意思:用队列实现栈,push(),pop(),top(),empty() 思路:用两个queue,pop时将一个queue的元素pop再push到另一个队列,queue只留最后一个元素,并pop, ...

随机推荐

  1. mysql 第二课 DML操作

    DML 数据操纵语句:INSERT UPDATE DELETE SELECT 主要用来对数据库的数据进行一些操作; DCL 数据定义语句:CREATE ALTER DROP  主要是用在定义或改变表的 ...

  2. Python--day40--datetime,socketserver,Threading模块分别是哪些模块的高层模块

  3. H5 拖拽元素

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 用一篇文章了解ppi,dpr,物理像素,逻辑像素,以及二倍图

    这篇文章能让你了解到什么是分辨率.dpr.dip.ppi (dpi相当于ppi,dpi用点表示物理像素密度,ppi是逻辑像素密度) 首先从最简单的ppi开始: 一部手机,有大有小,怎么知道手机的大小用 ...

  5. 【js】React-Native 初始化时报错

    一.按照官网的步骤一步一步的操作,到最后  react-native init AwesomeProject  时就是报错 报错信息如下图 然后我下载了这个模块  npm install prompt ...

  6. The solution to duplicated code

    The solution to duplicated code involves twe steps(Extraction and Invocation) that would be explaine ...

  7. vue-learning:12-vue获取模板内容的方式

    vue获取模板内容的方式 目录 outerHTML获取内容 template属性获取内容 ES6的字符串模板 <template>标签 <srcipt type="text ...

  8. CSS3 彩色渐变动效按钮

    <!DOCTYPE html> <html> <head> <title>Crayon Animate</title> <style ...

  9. 阿里云 CentOS8 Repo

    # CentOS-Base.repo # # The mirror system uses the connecting IP address of the client and the # upda ...

  10. RabbitMQ之pika模块

    发布/订阅 系统 send.py import pika import time s_conn = pika.BlockingConnection(pika.ConnectionParameters( ...