Java数据结构(习题)

本文介绍了如何使用栈和队列实现特定功能,包括判断一个序列是否为栈的合法弹出序列、在栈中获取最小元素以及用两个队列或两个栈模拟栈和队列的操作。通过示例代码详细阐述了各种操作的逻辑和思路,旨在加深对数据结构的理解和应用。
摘要由CSDN通过智能技术生成

1.给定两个序列 第一个序列是栈的压入序列 第二个序列是栈的弹出序列 判断第二个序列是否是第一个序列正确的弹出序列

  • 问题分析:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入序列为1,2,3,4,5,其可能的一个弹出顺序为4,5,3,2,1(先入1,2,3,再入4,随后弹出4,再入5随后全部弹出)。但4,3,5,1,2(若要4先出,则应4再3前入栈)就不可能为此栈的弹出队列。
  • 思路分析:我们可以借助一个栈,同时再两个队列中分别定义两个临时指针。首先,让入栈队列中的元素按临时指针依次入栈,随后获取栈顶元素与出栈队列中的临时指针进行比较,相等时便弹出并让出栈队列中的临时指针往后移动,继续循环,若临时指针与栈顶元素不相等,则让入栈队列元素依次继续入栈。
  • 代码实现:

public static boolean isPosArray(int[] array1,int[] array2){
        if(array1 == null || array1.length == 0 || array2 == null || array2.length == 0){
            return false;
        }
        //array1中的序列依次入栈,array2定义一个临时指针,从头往后走
        //临时指针在array2中的元素与栈顶元素不相等的时候,继续入栈
        Stack<Integer> stack = new Stack<>();
        int j = 0; //表示array2中的临时指针
        for(int i=0; i<array1.length; i++){
            //i表示当前array1中的临时指针
            int curName = array1[i];
            stack.push(curName);
            while(!stack.isEmpty() && stack.peek() == array2[j]){
                stack.pop();
                j++;
            }
        }
        if(stack.isEmpty()){
            return true;
        }
        System.out.println("Given array is not a pop-stach array");
        return false;
    }

2.在栈中实现一个函数,返回栈中最小元素

  • 思路分析:要实现一个能返回栈中最小元素的功能,我们可以借助一个辅助栈来实现。可以让我们的辅助栈一直保存数据栈中的最小元素,这样一来在获取最小元素时可以直接获取辅助栈的栈顶元素。那么在入栈时就要将入数据栈元素与辅助栈栈顶元素进行比较,若比栈顶元素小,则将其入栈后,将辅助栈栈顶元素也更新为次元素。
  • 代码实现:
    public static Stack<Integer> dataStack = new Stack<>();
    public static Stack<Integer> assistStack = new Stack<>();
    public static int getMin(){
        if(assistStack.isEmpty()){
            throw new UnsupportedOperationException("the stack has been empty");
        }
        return assistStack.peek();
    }

    public static void pushStack(int value){
        dataStack.push(value);

        if(assistStack.isEmpty() || value < assistStack.peek()){
            assistStack.push(value);
        }else{
            assistStack.push(assistStack.peek());
        }
    }

    public static int popStack(){
        if(dataStack.isEmpty()){
            throw new UnsupportedOperationException("the stack has been empty");
        }
        assistStack.pop();
        return dataStack.pop();
    }

3.两个队列实现一个栈

  • 思路分析:两个队列实现一个栈,即用两个表实现一个栈的功能,即先进后出,我们就需要实现这个栈的入栈和出栈方法。在入栈时,若一个队列为空,则将元素入另一个队列。始终保持两个队列中有一个队列有数据。在弹出时,要实现栈先进先出的特性,则每次弹出时把队列中的元素放入另一个队列中,删除最后一个元素。
  • 代码实现:
    3
    public static Queue<Integer> queue1 = new LinkedList<>();
    public static Queue<Integer> queue2 = new LinkedList<>();
    public static void pushStack(int value){
        if(queue1.isEmpty() && queue2.isEmpty()){
            queue1.add(value);
        }else if(queue1.isEmpty()){
            queue2.add(value);
        }else{
            queue1.add(value);
        }
    }

    public static int popStack(){
        //popQueue是当前的数据队列
        // 1 ? 2 : 3  1为true 选择2作为结果 反之选择3作为结果
        Queue<Integer> popQueue = queue1.isEmpty() ? queue2 : queue1;
        //pushQueue是当前的辅助队列
        Queue<Integer> pushQueue = queue1.isEmpty() ? queue1 : queue2;

        while(popQueue.size() > 1){
            pushQueue.add(popQueue.remove());
        }
        return popQueue.remove();
    }

4.两个栈实现一个队列

  • 思路分析:与第三题类似,入队时可直接在stack1中入栈,出栈时,若stack2为空,则当stack1不为空时,让stack2入stack1的栈顶元素,最后返回stack2的栈顶元素。
public static Stack<Integer> stack1 = new Stack<>();
    public static Stack<Integer> stack2 = new Stack<>();
    public static void pushQueue(int value){
        stack1.push(value);
    }

    public static int popQueue(){
        if(stack1.isEmpty() && stack2.isEmpty()){
            throw new UnsupportedOperationException("the stack has been empty");
        }
        if(stack2.isEmpty()){
            while(!stack1.isEmpty()){
                stack2.push(stack1.pop());
            }
        }
        return stack2.pop();
    }
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1.队列的共同特点是(只允许在端点处插入和删除元素) 4.通常采用的两种存储结构是(线性存储结构和链表存储结构) 5.下列关于的叙述正确的是(D) A.是非线性结构B.是一种树状结构C.具有先进先出的特征D.有后进先出的特征 6.链表不具有的特点是(B)A.不必事先估计存储空间 B.可随机访问任一元素 C.插入删除不需要移动元素 D.所需空间与线性表长度成正比 7.用链表表示线性表的优点是(便于插入和删除操作) 8.在单链表中,增加头结点的目的是(方便运算的实现) 9.循环链表的主要优点是(从表中任一结点出发都能访问到整个链表) 10.线性表L=(a1,a2,a3,……ai,……an),下列说法正确的是(D) A.每个元素都有一个直接前件和直接后件 B.线性表中至少要有一个元素 C.表中诸元素的排列顺序必须是由小到大或由大到小 D.除第一个和最后一个元素外,其余每个元素都有一个且只有一个直接前件和直接后件 11.线性表若采用链式存储结构时,要求内存中可用存储单元的地址(D) A.必须是连续的 B.部分地址必须是连续的C.一定是不连续的 D.连续不连续都可以 12.线性表的顺序存储结构和线性表的链式存储结构分别是(随机存取的存储结构、顺序存取的存储结构) 13.树是结点的集合,它的根结点数目是(有且只有1) 14.在深度为5的满二叉树中,叶子结点的个数为(31) 15.具有3个结点的二叉树有(5种形态) 16.设一棵二叉树中有3个叶子结点,有8个度为1的结点,则该二叉树中总的结点数为(13) 17.已知二叉树后序遍历序列是dabec,中序遍历序列是debac,它的前序遍历序列是(cedba) 18.已知一棵二叉树前序遍历和中序遍历分别为ABDEGCFH和DBGEACHF,则该二叉树的后序遍历为(DGEBHFCA) 19.若某二叉树的前序遍历访问顺序是abdgcefh,中序遍历访问顺序是dgbaechf,则其后序遍历的结点访问顺序是(gdbehfca) 20.数据库保护分为:安全性控制、 完整性控制 、并发性控制和数据的恢复。 1. 在计算机中,算法是指(解题方案的准确而完整的描述) 2.在下列选项中,哪个不是一个算法一般应该具有的基本特征(无穷性) 说明:算法的四个基本特征是:可行性、确定性、有穷性和拥有足够的情报。 3. 算法一般都可以用哪几种控制结构组合而成(顺序、选择、循环) 4.算法的时间复杂度是指(算法执行过程中所需要的基本运算次数) 5. 算法的空间复杂度是指(执行过程中所需要的存储空间) 6. 算法分析的目的是(分析算法的效率以求改进) ............ .................
1.1 单项选择题 1. 数据结构是一门研究非数值计算的程序设计问题中,数据元素的① 、数据信息在计算机中的② 以及一组相关的运算等的课程。 ① A.操作对象   B.计算方法  C.逻辑结构  D.数据映象 ② A.存储结构 B.关系 C.运算 D.算法 2. 数据结构DS(Data Struct)可以被形式地定义为DS=(D,R),其中D是① 的有限集合,R是D上的② 有限集合。 ① A.算法 B.数据元素 C.数据操作 D.数据对象 ② A.操作 B.映象 C.存储 D.关系 3. 在数据结构中,从逻辑上可以把数据结构分成 。 A.动态结构和静态结构 B.紧凑结构和非紧凑结构 C.线性结构和非线性结构 D.内部结构和外部结构 4. 算法分析的目的是① ,算法分析的两个主要方面是② 。 ① A. 找出数据结构的合理性 B. 研究算法中的输入和输出的关系 C. 分析算法的效率以求改进 D. 分析算法的易懂性和文档性 ② A. 空间复杂性和时间复杂性 B. 正确性和简明性 C. 可读性和文档性 D. 数据复杂性和程序复杂性 5. 计算机算法指的是① ,它必具备输入、输出和② 等五个特性。 ① A. 计算方法 B. 排序方法 C. 解决问题的有限运算序列 D. 调度方法 ② A. 可行性、可移植性和可扩充性 B. 可行性、确定性和有穷性 C. 确定性、有穷性和稳定性 D. 易读性、稳定性和安全性 1.2 填空题(将正确的答案填在相应的空中) 1. 数据逻辑结构包括 、 、 和 四种类型,树形结构和图形结构合称为 。 2. 在线性结构中,第一个结点 前驱结点,其余每个结点有且只有 个前驱结点;最后一个结点 后续结点,其余每个结点有且只有 个后续结点。 3. 在树形结构中,树根结点没有 结点,其余每个结点有且只有 个直接前驱结点,叶子结点没有 结点,其余每个结点的直接后续结点可以 。 4. 在图形结构中,每个结点的前驱结点数和后续结点数可以 。 5. 线性结构中元素之间存在 关系,树形结构中元素之间存在 关系,图形结构中元素之间存在 关系。 6. 算法的五个重要特性是__ __ , __ __ , ___ _ , __ __ , _ ___。 7. 分析下面算法(程序段),给出最大语句频度 ,该算法的时间复杂度是__ __。 for (i=0;i<n;i++) for (j=0;j<n; j++) A[i][j]=0; 8. 分析下面算法(程序段),给出最大语句频度 ,该算法的时间复杂度是__ __。 for (i=0;i<n;i++) for (j=0; j<i; j++) A[i][j]=0; 9. 分析下面算法(程序段),给出最大语句频度 ,该算法的时间复杂度是__ __。 s=0; for (i=0;i<n;i++) for (j=0;j<n;j++) for (k=0;k<n;k++) s=s+B[i][j][k]; sum=s; 10. 分析下面算法(程序段)给出最大语句频度 ,该算法的时间复杂度是__ __。 int i=0,s=0; while (s<n) { i++; s+=i; //s=s+i } 11. 分析下面算法(程序段)给出最大语句频度 ,该算法的时间复杂度是__ __。 i=1; while (i<=n) i=i*2;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

降温vae+

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值