计算机考研408真题2010年42题

这篇具有很好参考价值的文章主要介绍了计算机考研408真题2010年42题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.链表

链表不同于顺序表,顺序表底层采用数组作为存储容器,需要分配一块连续且完整的内存空间进行使用,而链表则不需要,它通过一个指针来连接各个分散的结点,形成了一个链状的结构,每个结点存放一个元素,以及一个指向下一个结点的指针,通过这样一个一个相连,最后形成了链表。它不需要申请连续的空间,只需要按照顺序连接即可,虽然物理上可能不相邻,但是在逻辑上依然是每个元素相邻存放的,这样的结构叫做链表(单链表)。

链表分为带头结点的链表和不带头结点的链表,戴头结点的链表就是会有一个头结点指向后续的整个链表,但是头结点不存放数据
计算机考研408真题2010年42题

而不带头结点的链表就像上面那样,第一个节点就是存放数据的结点,一般设计链表都会采用带头结点的结构,因为操作更加方便。

我们来尝试定义一下:

public class LinkedList<E> {
  	//链表的头结点,用于连接之后的所有结点
    private final Node<E> head = new Node<>(null);
  	private int size = 0;   //当前的元素数量还是要存一下,方便后面操作
    
    private static class Node<E> {  //结点类,仅供内部使用
        E element;   //每个结点都存放元素
        Node<E> next;   //以及指向下一个结点的引用
      
      	public Node(E element) {
            this.element = element;
        }
    }
}

1.1插入

链表的插入该怎么做:可以先修改新插入的结点的后继结点(也就是下一个结点)指向,指向原本在这个位置的结点,接着我们可以将前驱结点(也就是上一个结点)的后继结点指向修改为我们新插入的结点,这样,我们就成功插入了一个新的结点,现在新插入的结点到达了原本的第二个位置上

public void add(E element, int index){
    Node<E> prev = head;   //先找到对应位置的前驱结点
    for (int i = 0; i < index; i++) 
        prev = prev.next;
    Node<E> node = new Node<>(element);   //创建新的结点
    node.next = prev.next;   //先让新的节点指向原本在这个位置上的结点
    prev.next = node;   //然后让前驱结点指向当前结点
    size++;   //完事之后一样的,更新size
}

我们来重写一下toString方法看看能否正常插入:

@Override
public String toString() {
    StringBuilder builder = new StringBuilder();
    Node<E> node = head.next;   //从第一个结点开始,一个一个遍历,遍历一个就拼接到字符串上去
    while (node != null) {
        builder.append(node.element).append(" ");
        node = node.next;
    }
    return builder.toString();
}
  • 考虑插入位置是否合法:
public void add(E element, int index){
    if(index < 0 || index > size)
        throw new IndexOutOfBoundsException("插入位置非法,合法的插入位置为:0 ~ "+size);
    Node<E> prev = head;
    for (int i = 0; i < index; i++)
        prev = prev.next;
    Node<E> node = new Node<>(element);
    node.next = prev.next;
    prev.next = node;
    size++;
}

1.2删除

插入操作完成之后,我们接着来看删除操作,那么我们如何实现删除操作呢?实际上也会更简单一些,我们可以直接将待删除节点的前驱结点指向修改为待删除节点的下一个
计算机考研408真题2010年42题
计算机考研408真题2010年42题

这样,在逻辑上来说,待删除结点其实已经不在链表中了,所以我们只需要释放掉待删除结点占用的内存空间就行了
计算机考研408真题2010年42题

public E remove(int index){
    if(index < 0 || index > size - 1)   //同样的,先判断位置是否合法
        throw new IndexOutOfBoundsException("删除位置非法,合法的删除位置为:0 ~ "+(size - 1));
    Node<E> prev = head;
    for (int i = 0; i < index; i++)   //同样需要先找到前驱结点
        prev = prev.next;
    E e = prev.next.element;   //先把待删除结点存放的元素取出来
    prev.next = prev.next.next;  //可以删了
    size--;   //记得size--
    return e;
}

这样,我们就成功完成了链表的删除操作。

  • 获取对应位置上的元素:
public E get(int index){
    if(index < 0 || index > size - 1)
        throw new IndexOutOfBoundsException("非法的位置,合法的位置为:0 ~ "+(size - 1));
    Node<E> node = head;
    while (index-- >= 0)   //这里直接让index减到-1为止
        node = node.next;
    return node.element;
}

public int size(){
    return size;
}
  • 什么情况下使用顺序表,什么情况下使用链表呢?
    • 通过分析顺序表和链表的特性我们不难发现,链表在随机访问元素时,需要通过遍历来完成,而顺序表则利用数组的特性直接访问得到,所以,当我们读取数据多于插入或是删除数据的情况下时,使用顺序表会更好。
    • 而顺序表在插入元素时就显得有些鸡肋了,因为需要移动后续元素,整个移动操作会浪费时间,而链表则不需要,只需要修改结点 指向即可完成插入,所以在频繁出现插入或删除的情况下,使用链表会更好。

虽然单链表使用起来也比较方便,不过有一个问题就是,如果我们想要操作某一个结点,比如删除或是插入,那么由于单链表的性质,我们只能先去找到它的前驱结点,才能进行。为了解决这种查找前驱结点非常麻烦的问题,我们可以让结点不仅保存指向后续结点的指针,同时也保存指向前驱结点的指针

这样我们无论在哪个结点,都能够快速找到对应的前驱结点,就很方便了,这样的链表我们成为双向链表(双链表)

2.栈

栈(也叫堆栈,Stack)是一种特殊的线性表,它只能在在表尾进行插入和删除操作
计算机考研408真题2010年42题

底部称为栈底,顶部称为栈顶,所有的操作只能在栈顶进行,也就是说,被压在下方的元素,只能等待其上方的元素出栈之后才能取出,就像我们往箱子里里面放的书一样,因为只有一个口取出里面的物品,所以被压在下面的书只能等上面的书被拿出来之后才能取出,这就是栈的思想,它是一种先进后出的数据结构(FILO,First In, Last Out)

实现栈也是非常简单的,可以基于我们前面的顺序表或是链表,这里我们需要实现两个新的操作:

  • pop:出栈操作,从栈顶取出一个元素。
  • push:入栈操作,向栈中压入一个新的元素。

栈可以使用顺序表实现,也可以使用链表实现

2.1入栈

当有新的元素入栈,只需要在链表头部插入新的结点即可,我们来尝试编写一下:

public class LinkedStack<E> {

    private final Node<E> head = new Node<>(null);   //大体内容跟链表类似

    private static class Node<E> {
        E element;
        Node<E> next;

        public Node(E element) {
            this.element = element;
        }
    }
}

入栈操作:

public void push(E element){
    Node<E> node = new Node<>(element);   //直接创建新结点
    node.next = head.next;    //新结点的下一个变成原本的栈顶结点
    head.next = node;     //头结点的下一个改成新的结点
}

2.2出栈

出栈也是同理,所以我们只需要将第一个元素移除即可:

public E pop(){
  	if(head.next == null)   //如果栈已经没有元素了,那么肯定是没办法取的
      	throw new NoSuchElementException("栈为空");
    E e = head.next.element;   //先把待出栈元素取出来
    head.next = head.next.next;   //直接让头结点的下一个指向下一个的下一个
    return e;
}

3.队列

前面我们学习了栈,栈中元素只能栈顶出入,它是一种特殊的线性表,同样的,队列(Queue)也是一种特殊的线性表。

就像我们在超市、食堂需要排队一样,我们总是排成一列,先到的人就排在前面,后来的人就排在后面,越前面的人越先完成任务,这就是队列,队列有队头和队尾
计算机考研408真题2010年42题
秉承先来后到的原则,队列中的元素只能从队尾进入,只能从队首出去,也就是说,入队顺序为1、2、3、4,那么出队顺序也一定是1、2、3、4,所以队列是一种先进先出(FIFO,First In, First Out)的数据结构。

队列也可以使用链表和顺序表来实现,只不过使用链表的话就不需要关心容量之类的问题了,会更加灵活一些文章来源地址https://www.toymoban.com/news/detail-423348.html

public class LinkedQueue<E> {

    private final Node<E> head = new Node<>(null);

    public void offer(E element){  //入队操作
        Node<E> last = head;
        while (last.next != null)   //入队直接丢到最后一个结点的屁股后面就行了
            last = last.next;
        last.next = new Node<>(element);
    }

    public E poll(){   //出队操作
        if(head.next == null)   //如果队列已经没有元素了,那么肯定是没办法取的
            throw new NoSuchElementException("队列为空");
        E e = head.next.element;
        head.next = head.next.next;   //直接从队首取出
        return e;
    }

    private static class Node<E> {
        E element;
        Node<E> next;

        public Node(E element) {
            this.element = element;
        }
    }
}

到了这里,关于计算机考研408真题2010年42题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【计算机考研】408要怎么复习,才能130+?

    【计算机考研】408要怎么复习,才能130+?

    计算机组成原理:理解计算机硬件的工作原理,是理解其他课程的基础。 数据结构:算法的基石,建议作为复习的起点,因为它最像“数学”,一旦掌握,不易遗忘。 操作系统:理解计算机系统资源的管理与调度。 计算机网络:网络通信的基本原理和协议。 王道视频课程:

    2024年04月09日
    浏览(15)
  • 【计算机考研】408算法大题怎么练?

    【计算机考研】408算法大题怎么练?

    先说结论:基础阶段学好各个数据结构与,重点是数组、链表、树、图。然后强化阶段突破算法提 在基础阶段,并不需要过于专门地练习算法。相反,基础阶段的重点应该放在对各种数据结构原理的深入理解上。在我个人的经验中,我发现在这一阶段,建立对数据结构的扎实

    2024年04月10日
    浏览(12)
  • 计算机组成原理(考研408)练习题#4

    用于复习408或计算机组成原理期末考试。如有错误请在评论区指出。 So let\\\'s start studying with questions! それでは、問題の勉強を始めましょう! 1. 设某浮点数真值为 0.125,若该浮点数用 IEEE754 标准表示,则该浮点数对应的机器数是什么?(用十六进制表示,不写步骤不得分)

    2024年02月09日
    浏览(11)
  • 计算机组成原理(考研408)练习题#3

    用于复习408或计算机组成原理期末考试。如有错误请在评论区指出。 So let\\\'s start studying with questions! それでは、問題の勉強を始めましょう! 1. 定点整数原码编码[x]原=1110100B 的真值为_________。 首先,1110100B是一个8位二进制数,表示的是一个有符号整数的原码。根据原码编码

    2024年02月09日
    浏览(16)
  • 【23考研】计算机408数据结构代码题强化阶段划重点(王道书)

    视频链接:【23考研】10分钟带你整理408数据结构强化阶段代码题复习重点 本篇只适合考408的同学,请自主命题的同学自觉右上角×掉 因为王道书为了照顾自主命题的同学,所以很多算法也给出了代码实现,实际上对于考408的同学,很多代码是不需要掌握的,毕竟408的代码题没

    2024年02月15日
    浏览(30)
  • 【计算机组成原理】考研真题攻克与重点知识点剖析 - 第 1 篇:计算机系统概述

    【计算机组成原理】考研真题攻克与重点知识点剖析 - 第 1 篇:计算机系统概述

    本文基础知识部分来自于b站:分享笔记的好人儿的思维导图与王道考研课程,感谢大佬的开源精神,习题来自老师划的重点以及考研真题。 此前我尝试了完全使用Python或是结合大语言模型对考研真题进行数据清洗与可视化分析,本人技术有限,最终数据清洗结果不够理想,

    2024年02月07日
    浏览(16)
  • 408计算机复试专业课问答汇总

    408计算机复试专业课问答汇总

    桶排序 又要代码精简,又要运行效率提高,分别在 C 语言和 C++语言里面,你如何做优化?对于参加过算法比赛的学生来说这应该不难。在 C 里面比如把递归改成迭代,通过设置判断变量减少不必要的循环次数,在 C++比如用引用传递代替值传递 贪心算法,原理是什么 使用贪

    2024年04月11日
    浏览(49)
  • 硕士研究生入学统一考试408 计算机学科考试大纲

    一、 数据结构 【考查目标】 1. 掌握数据结构的基本概念、基本原理和基本方法。 2. 掌握数据的逻辑结构、存储结构及基本操作的实现, 能够对算法进行基本的时间复杂度 与空间复杂度的分析。 3. 能够运用数据结构基本原理和方法进行问题的分析与求解, 具备采用 C 或

    2023年04月24日
    浏览(52)
  • 计算机保研面试常见问题(408操作系统简答题)

    1. 操作系统的特点和功能是什么? 答:操作系统的特点是并发、共享、虚拟、异步。其中,并发和共享是操作系统主要的特点。操作系统的功能主要包括:处理机管理、存储器管理、设备管理和文件管理等。操作系统管理计算机的全部软、硬件资源,合理组织计算机的工作流

    2024年02月07日
    浏览(49)
  • 计算机保研面试常见问题(408数据结构简答题)

    计算机保研面试常见问题(408数据结构简答题)

    1. 什么是时间复杂度?O(n)的O代表了什么? 答:时间复杂度是指执行算法所需要的计算工作量,可以用于描述一个程序的规模。O(n)中的O表示的是最坏情况下的时间复杂度。 2. 时间复杂度的量级排序是什么? 答:O(logn) O(n) O(nlogn) O(n^2) O(2^n) O(n!) 3. 顺

    2024年02月13日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包