数据结构day6(2023.7.20)

2023-11-07

一、Xmind整理:

 

二、课上练习:

练习1:个栈的入栈次序ABCDE,则栈的不可能的输出序列是(D)

A.ABCDE          B.DECBA          C.EDCBA          D.DCEAB

       栈的特点是先进后出,后进先出,D不符合该思想,根据题意,可以推测D选项首先入栈的是ABCD,然后D出,C出,E进入,E出,但在这种情况下,B应当比A先出栈。

练习2:顺序栈

 

练习3:顺序栈的结构体定义

 

练习4:顺序栈的插入 


/*
 * function:    入栈
 * @param [ in] 
 * @param [out] 
 * @return      成功返回0 失败返回-1
 */
int list_stack_push(datatype e,StackList *stack)
{
    //1.判断栈是否创建
    //2.判断栈是否为满
    if(NULL==stack || stack->top==MAXSIZE-1)
    {
    puts("push  stack  error");
    return -1;
    }
    //3.入栈:先加后压
    //stack->top++;
stack->data[++stack->top]=e;
    return 0;
}

练习5:顺序栈的删除

/*
 * function:    出栈
 * @param [ in] 
 * @param [out] 
 * @return      成功返回0 失败返回-1
 */
int list_stack_pop(StackList *stack)
{
    //1.判断栈是否创建
    //2.判断栈是否为空
    if(NULL==stack || stack->top==-1)
    {
    puts("pop error");
    return -1;
    }
    //3.出栈:先弹后减
    printf("pop data is:%d\n",stack->data[stack->top--]);
//    stack->top--;
    return 0;
}

练习6:顺序栈的遍历

/*
 * function:    顺序栈的输出
 * @param [ in] 
 * @param [out] 
 * @return      无
 */
void stack_output(StackList *stack)
{
    //1.判断栈是否创建
    //2.判断栈是否为空
    if(NULL==stack || stack->top==-1)
    {
    puts("output error");
    return;
    }
    //3.输出
    for(int i=0;i<=stack->top;i++)
    {
    printf("%d\t",stack->data[i]);
    }
    puts("");
}

练习7:顺序栈的创建

/*
 * function:    创建栈
 * @param [ in] 
 * @param [out] 
 * @return      
 */
StackList *create_stack()
{
StackList *stack=(StackList *)malloc(sizeof(StackList));
    if(NULL == stack)
    {
    return NULL;
    }
    //栈顶置空
stack->top=-1;
    memset(stack->data,0,sizeof(stack->data));
    return stack;
}

练习8:链栈

 

练习9:链栈节点创建【单链表节点创建】

/*
 * function:    创建一个节点
 * @param [ in] 
 * @param [out] 
 * @return      
 */
LinkStack create_node()
{
LinkStack node=(LinkStack)malloc(sizeof(struct Node));
    if(NULL==node)
    return NULL;
node->data=0;
node->next=NULL;
    return node;//0x10
}

练习10:链栈插入【单链表头插】

/*
 * function:    链栈的入站
 * @param [ in] 
 * @param [out] 
 * @return      
 */

LinkStack link_stack_push(datatype e,LinkStack top)
{
    //在堆区创建一个节点
LinkStack node=create_node();//在堆区申请一个节点
node->data=e;//数据域赋值为e
    //node节点链接到链表中
node->next=top;
top=node;
    return top;//因为自定义函数指针的改变不影响实参,需要返回
}

练习11:链栈删除【单链表头删】

/*
 * function:    头删除
 * @param [ in] 
 * @param [out] 
 * @return      
 */
LinkStack link_stack_pop(LinkStack top)
{
    //判断链表是否为空
    if(NULL==top)
    {
    return top;
    }
    if(top->next==NULL)
    {
    free(L);
    L=NULL;
    }
    else
    {
    LinkStack q=top->next;
    top->data=q->data;
    top->next=q->next;
    free(q);
    q=NULL;
    }
return top;


}

练习12:链栈遍历【单链表遍历】

/*
 * function:    循环遍历
 * @param [ in] 
 * @param [out] 
 * @return      成功返回0 失败返回-1
 */
int link_output(LinkStack top)

{
    //判断是否创建
    //判断是否为空
    if(NULL==top )
    {
    return -1;
    }
    while(top!=NULL)
    {
    printf("%d\t",top->data);
    top=top->next;
    }
    puts("");
}

栈的整体代码:

stack_head.h:

#ifndef __STACK_HEAD_H__
#define __STACK_HEAD_H__

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXSIZE 4
typedef int datatype;
typedef struct
{
	//栈顶
	int top;
	//数据元素
	datatype data[MAXSIZE];
}StackList;

int list_stack_pop(StackList *stack);
StackList *create_stack();
int list_stack_push(datatype e,StackList *stack);
void stack_output(StackList *stack);

//定义单链表节点结构体
typedef struct Node
{
	//数据域:数据元素
	datatype data;
	//指针域:存储下一个节点的地址
	struct Node *next;
}*LinkStack;


LinkStack link_stack_push(datatype e,LinkStack top);
int link_output(LinkStack top);
LinkStack link_stack_pop(LinkStack L);

#endif


stack_test.c:

#include "stack_head.h"
/*
 * function:    创建栈
 * @param [ in] 
 * @param [out] 
 * @return      
 */
StackList *create_stack()
{
	StackList *stack=(StackList *)malloc(sizeof(StackList));
	if(NULL == stack)
	{
		return NULL;
	}
	//栈顶置空
	stack->top=-1;
	memset(stack->data,0,sizeof(stack->data));
	return stack;
}
/*
 * function:    入栈
 * @param [ in] 
 * @param [out] 
 * @return      成功返回0 失败返回-1
 */
int list_stack_push(datatype e,StackList *stack)
{
	//1.判断栈是否创建
	//2.判断栈是否为满
	if(NULL==stack || stack->top==MAXSIZE-1)
	{
		puts("push  stack  error");
		return -1;
	}
	//3.入栈:先加后压
	//stack->top++;
	stack->data[++stack->top]=e;
	return 0;
}
/*
 * function:    顺序栈的输出
 * @param [ in] 
 * @param [out] 
 * @return      无
 */
void stack_output(StackList *stack)
{
	//1.判断栈是否创建
	//2.判断栈是否为空
	if(NULL==stack || stack->top==-1)
	{
		puts("output error");
		return;
	}
	//3.输出
	for(int i=0;i<=stack->top;i++)
	{
		printf("%d\t",stack->data[i]);
	}
	puts("");
}
/*
 * function:    出栈
 * @param [ in] 
 * @param [out] 
 * @return      成功返回0 失败返回-1
 */
int list_stack_pop(StackList *stack)
{
	//1.判断栈是否创建
	//2.判断栈是否为空
	if(NULL==stack || stack->top==-1)
	{
		puts("pop error");
		return -1;
	}
	//3.出栈:先弹后减
	printf("pop data is:%d\n",stack->data[stack->top--]);
//	stack->top--;
	return 0;
}
/*
 * function:    创建一个节点
 * @param [ in] 
 * @param [out] 
 * @return      
 */
LinkStack create_node()
{
	LinkStack node=(LinkStack)malloc(sizeof(struct Node));
	if(NULL==node)
		return NULL;
	node->data=0;
	node->next=NULL;
	return node;//0x10
}/*
 * function:    链栈的入站
 * @param [ in] 
 * @param [out] 
 * @return      
 */

LinkStack link_stack_push(datatype e,LinkStack top)
{
	//在堆区创建一个节点
	LinkStack node=create_node();//在堆区申请一个节点
	node->data=e;//数据域赋值为e
	//node节点链接到链表中
	node->next=top;
	top=node;
	return top;//因为自定义函数指针的改变不影响实参,需要返回
}
/*
 * function:    循环遍历
 * @param [ in] 
 * @param [out] 
 * @return      成功返回0 失败返回-1
 */
int link_output(LinkStack top)

{
	//判断是否创建
	//判断是否为空
	if(NULL==top )
	{
		return -1;
	}
	while(top!=NULL)
	{
		printf("%d\t",top->data);
		top=top->next;
	}
	puts("");
}
/*
 * function:    头删除
 * @param [ in] 
 * @param [out] 
 * @return      
 */
LinkStack link_stack_pop(LinkStack top)
{
	//判断链表是否为空
	if(NULL==top)
	{
		return top;
	}
	if(top->next==NULL)
	{
		free(L);
		L=NULL;
	}
	else
	{
		LinkStack q=top->next;
		top->data=q->data;
		top->next=q->next;
		free(q);
		q=NULL;
	}
	return top;


}

stack_main.c:

#include "stack_head.h"
int main(int argc, const char *argv[])
{
	/*
	StackList *stack=create_stack();
	char continu;
	datatype e;
	int flag;
	do
	{
	//入栈
		printf("please enter e:");
		scanf("%d",&e);
		flag=list_stack_push(e,stack);
		if(flag==-1)
			break;
		printf("Please enter whether you will continue");
		scanf(" %c",&continu);

	}while(continu!='N'&&continu!='n');
	
	stack_output(stack);
	do
	{
		flag=list_stack_pop(stack);

		if(flag==-1)
			break;
		printf("Please enter whether you will continue");
		scanf(" %c",&continu);

	}while(continu!='N'&&continu!='n');
	
	stack_output(stack);
	
*/
	LinkStack top=NULL;
	char continu;
	datatype e;
	int flag;
	do
	{
	//入栈
		printf("please enter e:");
		scanf("%d",&e);
		
		top=link_stack_push(e,top);
		
		printf("Please enter whether you will continue");
		scanf(" %c",&continu);

	}while(continu!='N'&&continu!='n');
	
	link_output(top);
	do
	{
		
		top=link_stack_pop(top);
		printf("Please enter whether you will continue");
		scanf(" %c",&continu);

	}while(continu!='N'&&continu!='n');
	
	link_output(top);
	return 0;
}

练习13:顺序队列

 

练习14:顺序队列创建

/*
 * function:    在堆区申请空间
 * @param [ in] 
 * @param [out] 
 * @return      返回地址
 */
QueueList *create_queue()
{
QueueList  *queue=(QueueList *)malloc(sizeof(QueueList));
    if(NULL==queue)
    return NULL;

queue->front=queue->rear=0;
    memset(queue->data,0,sizeof(queue->data));
    return queue;
}

练习15:顺序队列入队

/*
 * function:    入队
 * @param [ in] 
 * @param [out] 
 * @return      成功返回0 失败返回-1
 */
int enqueue(datatype e,QueueList *queue)
{
    //1.判断是否创建
    //2.判断是否满
    if(NULL==queue || queue->rear==MAXSIZE)
    {
    puts("enqueue error");
    return -1;
    }
    //3.入队:在队尾插入
queue->data[queue->rear++]=e;
//    queue->rear++;
    return 0;
    
}

练习16:顺序队列出队

/*
 * function:    出队
 * @param [ in] 
 * @param [out] 
 * @return      成功返回0 失败返回-1
 */
int delqueue(QueueList *queue)
{
    //1.判断是否创建
    //2.判断是否为空
    if(NULL==queue || queue->front==queue->rear)
    {
    puts("delqueue error");
    return -1;
    }
    //3.出队:出队在队头
    printf("delqueue data is:%d\n",queue->data[queue->front++]);
//    queue->front++;

}

练习17:顺序队列遍历

/*
 * function:    循环输出队列
 * @param [ in] 
 * @param [out] 
 * @return      无
 */
void output(QueueList *queue)
{
    //1.判断是否创建
    //2.判断是否为空
    if(NULL==queue || queue->front==queue->rear)
    {
    puts("output error");
    return;
    }
    //3.从队头到队尾输出
    for(int i=queue->front;i<queue->rear;i++)
    {
    printf("%d\t",queue->data[i]);
    }
    puts("");
}

练习18:循环队列

 

练习19:循环队列入队

/*
 * function:    循环队列入队
 * @param [ in] 
 * @param [out] 
 * @return      成功返回0 失败返回-1
 */
int enqueue(datatype e,QueueList *queue)
{
    //1.判断是否创建
    //2.判断是否满
    if(NULL==queue ||queue->front==(queue->rear+1)%MAXSIZE)
    {
    puts("enqueue error");
    return -1;
    }
    //3.入队:在队尾插入
queue->data[queue->rear]=e;
queue->rear=(queue->rear+1)%MAXSIZE;
    return 0;
    
}

练习20:循环队列出队

/*
 * function:    出队
 * @param [ in] 
 * @param [out] 
 * @return      成功返回0 失败返回-1
 */
int delqueue(QueueList *queue)
{
    //1.判断是否创建
    //2.判断是否为空
    if(NULL==queue || queue->front==queue->rear)
    {
    puts("delqueue error");
    return -1;
    }
    //3.出队:出队在队头
    printf("delqueue data is:%d\n",queue->data[queue->front]);
queue->front=(queue->front+1)%MAXSIZE;
    return 0;

}

练习21:循环队列的遍历

/*
 * function:    循环输出队列
 * @param [ in] 
 * @param [out] 
 * @return      无
 */
void output(QueueList *queue)
{
    //1.判断是否创建
    //2.判断是否为空
    if(NULL==queue || queue->front==queue->rear)
    {
    puts("output error");
    return;
    }
    //3.从队头到队尾输出
    for(int i=queue->front;i!=queue->rear;i=(i+1)%MAXSIZE)
    {
    printf("%d\t",queue->data[i]);
    }
    puts("");
}

练习22:循环队列个数计算

/*
 * function:    计算循环队列个数
 * @param [ in] 
 * @param [out] 
 * @return      
 */
int loop_queue_count(QueueList *queue)
{
 return (MAXSIZE-queue->front+queue->rear)%MAXSIZE;
}

练习23:链式队列

 

练习24:链式队列节点创建【单链表节点创建】

//创建节点
queue  *CreateLink()
{
	//创建队列:头节点,尾节点【指向单向链表的头以及尾】
	queue *q=(queue *)malloc(sizeof(queue));
	if(q==NULL)
		return NULL;
	//创建单向链表的头节点
	Node *L=(Node *)malloc(sizeof(Node));
	if(L==NULL)
		return NULL;
	L->len=0;//对单向链表头结点的数据域赋值,链表为空
	L->next=NULL;//单向链表头结点没有后继节点
	
	q->front=L;//队头指向单向链表的第一个节点
	q->rear=L;//队尾指针指向单向链表的最后一个节点
	return q;
}

练习25:链式队列入队【单链表尾插】

void EnqueueLink(queue *q,datatype e)
{
	//1.判断队列是否创建成功
	if(q==NULL)
		return;
	//2.入队
	Node *p=(Node *)malloc(sizeof(Node));
	if(p==NULL)
		return;
	p->data=e;
	p->next=NULL;
	
	//3.入队
	q->rear->next=p;
	q->rear=p;
	q->front->len++;
}

练习26:链式队列出队【单链表头删】

//链式队列的出队
//成功返回出队的数据,
int dequeueLink(queue *q)
{
	//1.判断队列是否存在
	//2.判断队列是否为空
	if(q==NULL || q->front->next==NULL)
		return -1;
	//3.出队
	Node *p=q->front->next;
	int data=p->data;
	q->front->next=p->next;
	free(p);
	p=NULL;
	q->front->len--;
	return data;
}

练习27:链式队列遍历【单链表的输出】

//链是队列的遍历
void LinkShow(queue *q)
{
	printf("\n");
	Node *p=q->front;
	while(p->next)
	{
		p=p->next;
		printf("%d\t",p->data);
	}
	printf("\n");
}

练习28:释放空间

//释放头节点后面的节点
	int t=q->front->len;
	for(int i=0;i<t;i++)
	{
		dequeueLink(q);
	}
	free(q->front);//删除头节点
	free(q);//释放队列的空间
	q=NULL;//q释放没有指向,防止野指针

练习29:直接插入排序

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
	int m,t,j;
	int arr[100];
	printf("请问你要插入几个数:");
	scanf("%d",&m);
	for(int i=0;i<m;i++)
	{
		printf("请输入第%d个数:",i+1);
		scanf("%d",&arr[i]);
	}
	int *p=arr;
	for(int i=1;i<m;i++)
	{
		t=*(p+i);
		for(j=i-1;j>=0;j--)
		{
			if(t<*(p+j))
			{
				*(p+j+1)=*(p+j);
			}
			else
				break;
		}
		*(p+j+1)=t;
	}
	for(int i=0;i<m;i++)
		printf("%d\t",*(p+i));
	puts("");
	return 0;
}

三、课后作业:

实现双向链表的逆置

方法一:
DoubleLink rev_doublelink(DoubleLink L)
{
	//判断链表是否为空
	if(NULL==L)
		return L;
	//判断链表只有一个节点
	if(NULL == L || L->next==NULL)
	{
		return L;
	}
    //先找最后一个节点的位置
	DoubleLink p=L;
	while(p->next!=NULL)
	{
		p=p->next;
	}
	DoubleLink q=L;
	DoubleLink s=NULL;
	while(q!=NULL)
    {
        s=q->next;
		q->next=q->prev;
		q->prev=s;
		q=s;
    }
    return p;
}
方法二:
DoubleLink rev_doublelink(DoubleLink L)
{
	//判断链表是否为空
	if(NULL==L)
		return L;
	//判断链表只有一个节点
	if(NULL == L || L->next==NULL)
	{
		return L;
	}
	DoubleLink p=L;
	DoubleLink q=NULL;
	while (p!=NULL)
	{
		q=p->prev;
		p->prev=p->next;
		p->next=q;
		p=p->prev;
	}
	// 更新头节点的prev指针为NULL
	if(q!=NULL)
	{
		L=q->prev;
		L->prev=NULL;
	}
	return L;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构day6(2023.7.20) 的相关文章

  • python实现ip地址查询

    encoding utf8 根据ip地址查询出IP所在的地理位置 import requests def get ip info ip r requests get http ip taobao com service getIpInfo
  • websocket简单使用

    简单实现 参考 https websockets readthedoc PS 此文章只限于python版本大于3 6 前期准备 pip install websocket server端 import asyncio import webs
  • 怎么插入svg_公众号文章SVG使用教程分享

    嘿 胖友们大家好呀 我是三儿 每天 困扰在我们新时代新媒体人面前的 不是今天不知道该写啥 也不是粉丝咋又掉了 而是 今天中午吃啥 每天一到饭点 公司的外卖群里就开始了灵魂质问 今天吃啥 这个时候 就轮到貌美如花的小三儿出场了 先来看看三儿是
  • 小程序用户隐私保护指引设置填写指南(小程序隐私保护说明如何填写)

    小程序隐私保护指引完整填写范本 小程序隐私保护说明如何填写 小程序用户隐私保护指南填写指南仅供参考 为了区分用户 开发者在征得你明确同意后 会收集你的微信昵称和头像 为了显示距离 开发商在征得你的明确同意后 会收集你的位置信息 对于用户互动

随机推荐

  • MCU学习笔记_PWR电源管理系统

    MCU学习笔记 电源管理系统 1 STM32电源监控器概述 2 STM32电源 3 HAL库配置PVD实例 1 STM32电源监控器概述 原因 保持系统正常运行 实现特定条件下的低功耗模式 上电复位 POR 掉电复位 PDR 上电复位是指上
  • 面试官:说说react的渲染过程

    hello 这里是潇晨 大家在面试的过程中有没有遇到过一些和react相关的问题呢 比如面试官让你说说react渲染的过程 这到题目比较开放 也比较考验大家对react渲染原理以及源码的整体架构的理解 整体流程 react的核心可以用ui
  • STM32局部变量过大导致栈溢出

    最近项目调试中发现只要使用memset函数对一个局部数组赋值时 就会导致其他全局变量值被更改 接着就进入HardFault错误 后来发现局部变量和全局变量地址重叠 Data Write结构体为全局变量 OTA Data为局部数组 看了启动文
  • 利用类实现rand函数,以及相应的优化

    亮点 实现了一个非常高效的跳越性调用函数 见代码part 4 include
  • IDEA将jar包部署到Docker中使用TLS认证

    一 无CA认证 1 修改服务器配置 开放Docker的远程连接访问 root localhost vim usr lib systemd system docker service 将ExecStart属性value值改为 usr bin
  • vue + elementui:分页查询,el-pagination,纯前端分页

    效果 新建pages js文件 文件内容 数据分页 function pageData total pageRow currentPage allTableDataList var dealData var onePageList var
  • ChatGPT在指尖跳舞: open-interpreter实现本地数据采集、处理一条龙

    更多详情请点击查看原文ChatGPT在指尖跳舞 open interpreter实现本地数据采集 处理一条龙 Python教学专栏 旨在为初学者提供系统 全面的Python编程学习体验 通过逐步讲解Python基础语言和编程逻辑 结合实操案
  • vue集成汉字转拼音(附多音字解决方案)

    1 结果显示 输出首字母 N 输出拼音 NiHaoMa 2 js调用 import HanziToPinyin from hanziToPinyin export default class Message extends Vue moun
  • Intellij IDEA的激活(使用破解补丁永久激活)

    1 先下载个idea 给个官网下载吧 https www jetbrains com idea 这里只介绍破解补丁方式 个人觉得破解补丁方式是最一劳永逸的 破解步骤如下 2 从http idea lanyus com 这个网址下载破解补丁
  • HTTPS加密流程详解

    文章目录 HTTPS与HTTP的关系 HTTPS基本工作过程 对称密钥 非对称密钥 中间人攻击 证书 HTTPS与HTTP的关系 HTTPS协议基于HTTP 只是比HTTP多了一个加密层 为什么要加密呢 因为网络传输的过程中 明文传输的数据
  • 华为OD机试 - 找终点(Java)

    题目描述 给定一个正整数数组 设为nums 最大为100个成员 求从第一个成员开始 正好走到数组最后一个成员 所使用的最少步骤数 要求 第一步必须从第一元素开始 且1 lt 第一步的步长
  • css-赛博朋克风动画组件

    css 赛博朋克风动画组件 目录 文章目录 前言 结果展示 代码 前言 Tutorials收费课程中的一种实现 实现思路 先绘制盒子 制作动画 通过颜色位置变化来实现流转 webkit box reflect below 2px linea
  • 李宏毅机器学习课程笔记1:Regression、Error、Gradient Descent

    台湾大学李宏毅老师的机器学习课程是一份非常好的ML DL入门资料 李宏毅老师将课程录像上传到了YouTube 地址 NTUEE ML 2016 这篇文章是学习本课程第1 3课所做的笔记和自己的理解 Lecture 1 Regression
  • android开发:gradle 3.X中dependencies依赖api、compile和implementation的区别

    参考 Android Studio3 X中dependencies依赖api compile和implementation的区别 注意 文中的Android Studio3 X应该是gradle3 x
  • golang数据结构初探之动态数组slice

    动态数组slice slice 又称动态数组 依托于数组实现 可以方便的进行扩容和传递 实际使用时比数组更灵活 但正是因为灵活 实际使用时更容易出错 避免出错的最好方法便是了解其实现原理 特性速览 初始化 声明和初始化切片的方式主要有以下几
  • Jupyter Notebook常用快捷键(在命令模式中按H也可查看)

    命令模式 按键 Esc 开启 Enter 转入编辑模式 Shift Enter 运行本单元 选中下个单元 Ctrl Enter 运行本单元 Alt Enter 运行本单元 在其下插入新单元 Y 单元转入代码状态 M 单元转入markdown
  • chatgpt赋能python:Python如何读取npz文件?

    Python 如何读取 npz 文件 在 Python 中 我们可以使用多种方式读取 npz 格式的文件 npz 文件是 numpy 的压缩文件格式 可以用于存储多个数组数据 什么是 npz 文件 npz 文件是一个多个数组数据的压缩文件格
  • 推荐一款超厉害的国产Java工具类Hutool

    文章目录 Hutool 是什么 入门和安装 Maven Gradle 非Maven项目 编译安装 包含组件 日期时间工具 DateUtil 转换 Date long Calendar之间的相互转换 字符串转日期 格式化日期输出 获取Date
  • 关于RNA-seq 的那点事Count 数的标准化 (一) RPKM 和FPKM,TPM及C(R)PM

    图片来自网络 我们都知道 在RNA seq 测序的过程中 我们测完序的最终目的是想根据测序的结果 最终分析得到差异基因以及潜在可能的功能分析 那么在进行差异分析以及对表达量进行分析的时候 对基因原始的Count 进行标准化 消除由于测序过程
  • 数据结构day6(2023.7.20)

    一 Xmind整理 二 课上练习 练习1 个栈的入栈次序ABCDE 则栈的不可能的输出序列是 D A ABCDE B DECBA C EDCBA D DCEAB 栈的特点是先进后出 后进先出 D不符合该思想 根据题意 可以推测D选项首先入栈