1.栈的概念:

栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新 元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶 元素删除掉,使其相邻的元素成为新的栈顶元素。
(Stack):是只允许在一端进行插入或删除的线性表。首先栈是一种线性表,但限定这种线性表只能在某一端进行插入和删除操作。
栈顶(Top):线性表允许进行插入删除的那一端。
栈底(Bottom):固定的,不允许进行插入和删除的另一端。
空栈:不含任何元素的空表。
栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构
特性:
它的特殊之处在于限制了这个线性表的插入和删除的位置,它始终只在栈顶进行。这也就使
得:==栈底是固定的,最先进栈的只能在栈底==
对栈的操作:
示例如下:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX_SIZE 50typedef struct{void *data[MAX_SIZE];int size;
}Stack;typedef struct{char name[15];int age;char breed[10];
}Stu;Stack *initstack(void){Stack *stack=(Stack *)malloc(sizeof(Stack));if(stack==NULL){printf("malloc error.\n");return NULL;}for(int i=0;i<MAX_SIZE;i++){stack->data[i]=NULL;}stack->size=0;return stack;
}void pushstack(Stack *stack,void *data){if(stack==NULL){return;}if(stack->size==MAX_SIZE){return;}if(data==NULL){return;}stack->data[stack->size]=data;stack->size++;
} void popstack(Stack *stack){if(stack==NULL){return;}if(stack->size==0){return;}stack->data[stack->size-1]=NULL;stack->size--;
}void *topelement(Stack *stack){if(stack==NULL){return NULL;}if(stack->size==0){return NULL;}return stack->data[stack->size-1];
}int isempty(Stack *stack){if(stack==NULL){return 0;}if(stack->size==0){return 0;}return 1;
}int sizestack(Stack *stack){if(stack==NULL){return -1;}return stack->size;
}void clearstack(Stack *stack){if(stack==NULL){return;}for(int i=0;i<stack->size;i++){stack->data[i]=NULL;}stack->size=0;
}void freestack(Stack *stack){if(stack==NULL){return;}free(stack);
}int main(){Stack *stack=initstack();Stu p1={"洛羽晨",18,"人类"};Stu p2={"虚构康",20,"不详"};Stu p3={"丁真",23,"出生"};Stu p4={"谷爱凌",22,"剑冢"};pushstack(stack,&p1);pushstack(stack,&p2);pushstack(stack,&p3);pushstack(stack,&p4);while(sizestack(stack)>0){Stu *p=(Stu *)topelement(stack);printf("name:%s,age=%d,breed=%s\n",p->name,p->age,p->breed);popstack(stack);}freestack(stack);return 0;
}

2.栈的链式存储结构:

概念:上面讲的是栈的顺序存储结构,相当于一个线性表,只是操作位置有限制。链式存储结构也就是链表形式的栈。它和链表的结构是一样的,操作方式和上面的一样。

操作:

示例如下:


#include "linkstack.h"
typedef struct
{
char name[64];
int age;
int score;
}Person;
//打印函数
void my_print(void *data)
{
Person *p=(Person *)data;
printf("name:%s age:%d score:%d\n",p->name,p->age,p->score);
}
int main()
{
//创建链表
LinkStack *stack=init_linkstack();
//获取链表长度
printf("stack 长度:%d\n",size_linkstack(stack));
//创建数据
//创建数据
Person p1={"aaa",10,80};
Person p2={"bbb",11,81};
Person p3={"ccc",12,82};
Person p4={"ddd",13,83};
//入栈
push_linkstack(stack, &p1);
push_linkstack(stack, &p2);
//打印
print_linkstack(stack, my_print);
printf("\n");
//入栈
push_linkstack(stack, &p3);
push_linkstack(stack, &p4);
//打印
print_linkstack(stack, my_print);
printf("\n");
//出栈
void *data=pop_linkstack(stack);
my_print(data);
printf("\n");
//打印
print_linkstack(stack, my_print);
printf("\n");
//获取链表长度
printf("stack 长度:%d\n",size_linkstack(stack));
//返回第一个结点
Person *p=(Person *)top_element(stack);
printf("top_element:name-%s,age-%d,score-%d\n",p->name,p->age,p->score);
//销毁
free_linkstack(stack);
return 0;
}
#include "linkstack.h"
//初始链表
LinkStack *init_linkstack(void)
{
LinkStack *stack=(LinkStack *)malloc(sizeof(LinkStack));
stack->size=0;
//头结点
stack->head=(LinkNode *)malloc(sizeof(LinkNode));
stack->head->data=NULL;
stack->head->next=NULL;
return stack;
}
//指定位置插入
void push_linkstack(LinkStack *stack, void *data)
{
if(stack == NULL)
{
return ;
}
if(data == NULL)
{
return ;
}
//创建新的结点
LinkNode *newnode=(LinkNode *)malloc(sizeof(LinkNode));
newnode->data=data;
newnode->next=NULL;
//找结点
//辅助指针变量
LinkNode *pcurrent=stack->head;
//新结点插入链表
newnode->next=pcurrent->next;
pcurrent->next=newnode;
stack->size++;
}
//删除指定位置的值
void *pop_linkstack(LinkStack *stack)
{
if(stack == NULL)
{
return NULL;
}
//找结点
//辅助指针变量
LinkNode *pcurrent=stack->head;
//删除结点
LinkNode *delnode=pcurrent->next;
pcurrent->next=delnode->next;
void *data=delnode->data;
free(delnode);
stack->size--;
return data;
}
//获取链表长度
int size_linkstack(LinkStack *stack)
{
return stack->size;
}
//返回栈顶元素数据域
void *top_element(LinkStack *stack)
{
return stack->head->next->data;
}
//打印栈内所有内容
void print_linkstack(LinkStack *stack, printlinknode print)
{
if(stack == NULL)
{
return ;
}
//辅助指针变量
LinkNode *pcurrent=stack->head->next;
while(pcurrent!=NULL)
{
print(pcurrent->data);
pcurrent=pcurrent->next;
}
}
//释放链表内存
void free_linkstack(LinkStack *stack)
{
if(stack == NULL)
{
return ;
}
//辅助指针变量
LinkNode *pcurrent=stack->head;
while(pcurrent!=NULL)
{
//缓存下一个结点
LinkNode *pnext=pcurrent->next;
free(pcurrent);
pcurrent=pnext;
}
//释放链表内存
stack->size=0;
free(stack);
}
#ifndef LINKLIST_H
#define LINKLIST_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#endif
//结点结构体
typedef struct NODE
{
void *data;
struct NODE *next;
}LinkNode;
//栈表结构体
typedef struct
{
LinkNode *head;
int size;
}LinkStack;
//打印函数指针
typedef void(*printlinknode)(void *);
//初始栈表
LinkStack *init_linkstack(void);
//入栈
void push_linkstack(LinkStack *stack, void *data);
//出栈
void *pop_linkstack(LinkStack *stack);
//获取链表长度
int size_linkstack(LinkStack *stack);
//返回第一个结点
void *top_element(LinkStack *stack);
//打印栈内结点
void print_linkstack(LinkStack *stack, printlinknode print);
//释放栈内存
void free_linkstack(LinkStack *stack);

2.队列的概念:

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进 行删除操作的端称为队头。
队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中 删除,==故队列又称为先进先出(FIFO—first in first out)线性表。
2.对队列的操作:增删改查
示例如下:
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 1024
typedef struct
{
void *data[MAX_SIZE];
int size;
}Queue;
//初始化
Queue * init_queue(void)
{
Queue *queue=(Queue *)malloc(sizeof(Queue));
for(int i=0;i<MAX_SIZE;i++)
{
queue->data[i]=NULL;
}
queue->size=0;
return queue;
}
//入队
void push_queue(Queue *queue, void *data)
{
//数组左边当做对头
if(queue==NULL)
{
return ;
}
if(data==NULL)
{
return ;
}
queue->data[queue->size]=data;
queue->size++;
}
//返回对头元素
void *front_queue(Queue *queue)
{
if(queue==NULL)
{
return NULL;
}
if(queue->size==0)
{
return NULL;
}
return queue->data[0];
}
//出队
void pop_queue(Queue *queue)
{
//需要移动元素
if(queue==NULL)
{
return ;
}
if(queue->size==0)
{
return ;
}
for(int i=0;i<queue->size-1;i++)
{
queue->data[i]=queue->data[i+1];
}
queue->size--;
}
//返回队尾元素
void *back_queue(Queue *queue)
{
if(queue==NULL)
{
return NULL;
}
if(queue->size==0)
{
return NULL;
}
return queue->data[queue->size-1];
}
//返回大小
int size_queue(Queue *queue)
{
if(queue==NULL)
{
return -1;
}
return queue->size;
}
//清空队列
void clear_queue(Queue *queue)
{
if(queue==NULL)
{
return ;
}
while(queue->size>0)
{
queue->size--;
queue->data[queue->size]=NULL;
}
}
//销毁
void free_queue(Queue *queue)
{
if(queue==NULL)
{
return ;
}
free(queue);
}
typedef struct
{
char name [64];
int age;
}Person;
int main()
{
//创建队列
Queue *queue=init_queue();
//创建数据
Person p1={"aaa",10};
Person p2={"bbb",10};
Person p3={"ccc",10};
Person p4={"ddd",10};
//入队
push_queue(queue,&p1);
push_queue(queue,&p2);
push_queue(queue,&p3);
push_queue(queue,&p4);
//取出对尾元素
Person *p=(Person *)back_queue(queue);
printf("name:%s, age=%d\n",p->name,p->age);
printf("\n");
clear_queue(queue);
printf("\n");
//入队
push_queue(queue,&p1);
push_queue(queue,&p2);
push_queue(queue,&p3);
push_queue(queue,&p4);
//输出
while(size_queue(queue)>0)
{
//取出对头元素
Person *p=(Person *)front_queue(queue);
printf("name:%s, age=%d\n",p->name,p->age);
//出队
pop_queue(queue);
}
//销毁队列
free_queue(queue);
return 0;
}

Day 64 栈的顺序和链式存储 队列相关推荐

  1. Python数据结构与算法基础|第二期:代码实现——栈的顺序存储与链式存储

    顺序存储的栈 由于Python内置的列表是顺序存储的,所以我们直接使用列表作为顺序存储的栈的底层.具体代码如下: class Stack(object):'实现顺序栈.'def __init__(se ...

  2. 线性表的顺序、链式存储结构基本操作

    线性表的抽象数据类型 operation InitList(&L):初始化操作,建立一个空的线性表L ListEmpty(L):若线性表为空,返回true,否则返回false ClearLis ...

  3. 【数据结构】 实验报告10 顺序、链式存储结构的二叉树递归遍历、层次遍历求高度

    一.实验目的和要求 (源码在最后) 要求: 两种及以上存储结构(建议 顺序存储结构和链式存储结构各一).两种及以上方法(建议 递归遍历和层次遍历方法各一).分析各代码性能. 抽象数据类型(二叉树)独立 ...

  4. 串--串的定义,顺序、链式存储结构,BF、KMP模式匹配算法(C语言描述)

    此文章仅作为自己学习过程中的记录和总结,同时会有意地去用英文来做笔记,一些术语的英译不太准确,内容如有错漏也请多指教,谢谢! 一.串(String)的定义: 串(String):由零个或多个字符组成的 ...

  5. Python数据结构与算法基础|第三期:代码实现——顺序存储队列与链式存储队列

    由于队列的动态由队头指针与队尾指针共同反映,所以我们在实现先入后出的同时还要实现队头元素与队尾元素的访问.对于普通的队列,我们使用列表实现其顺序存储,使用其它方法实现其链式存储. 顺序存储 由于我们使 ...

  6. 链表list(链式存储结构实现)_数据结构知否知否系列之 — 线性表的顺序与链式存储篇(8000 多字长文)...

    从不浪费时间的人,没有工夫抱怨时间不够. -- 杰弗逊 线性表是由 n 个数据元素组成的有限序列,也是最基本.最简单.最常用的一种数据结构. 作者简介:五月君,Nodejs Developer,热爱技 ...

  7. 数据结构-线性表的顺序、链式存储结构

  8. 数据结构学习笔记——链式存储结构实现栈(链栈)

    目录 一.链栈的定义 二.链栈的初始化 三.判断链栈是否为空栈 四.进栈(插入操作) 五.出栈(删除操作) 六.读取链栈的栈顶元素 七.链栈的建立 八.链栈的遍历输出 链式存储结构实现栈完整代码 一个 ...

  9. 数据结构(二):线性表包括顺序存储结构(顺序表、顺序队列和顺序栈)和链式存储结构(链表、链队列和链栈)...

    还记得数据结构这个经典的分类图吧: 今天主要关注一下线性表. 什么是线性表 线性表的划分是从数据的逻辑结构上进行的.线性指的是在数据的逻辑结构上是线性的.即在数据元素的非空有限集中 (1) 存在唯一的 ...

最新文章

  1. 开源大数据周刊-第30期
  2. unity调用普通java类_Unity中C#和Java的相互调用实例代码
  3. 查看mysql日志大小,SQL Server:查看SQL日志文件大小命令:dbcc sqlperf(logspace)
  4. python的内存分配
  5. 电子设计竞赛电源题(2)-检波与采样
  6. IDEA去除mapper.xml文件中的sql语句的背景色
  7. [文章存档]Azure上部署的java app在向第三方服务传送中文时出现乱码
  8. windows 安装mongodb
  9. 【BZOJ1096】仓库建设,斜率优化DP练习
  10. ShoeBox一个超级好用的图片切割工具
  11. GRE常见的熟词生义
  12. 先电OpenStack创建云主机报错500
  13. 工业物联网快速解决方案
  14. 使用计算机辅助翻译的基本流程,计算机辅助翻译不同于机器翻译,计算机辅助翻译的原理和流程...
  15. 当逛书店成为一种怀旧
  16. 存储卡被格式化了咋恢复文件?
  17. springboot整合手机验证码
  18. 有关与windows的一些资料以及链接(一)
  19. python相对导入常见问题和解决方案
  20. 讲座录播及课件|Tamer Özsu教授:图处理-全景式视角和开放性问题

热门文章

  1. C# DataTable和List之间相互转换
  2. 我父亲是一个收棒子的
  3. Hertz椭球接触计算公式
  4. 卢家峰课程系列-- advanced rs-fmri analysis 1/6 基本介绍与DICOM
  5. linux环境下python编程指南,在Linux系统中搭建Python编程环境
  6. unity转抖音小游戏笔记
  7. hex格式解析,合并hex
  8. php swoole实例,Swoole WebSocket实例
  9. 控制台推箱子小游戏C语言
  10. css怎么实现右边固定,左边自适应