大厂面试经典单链表例题(创建有序单链表,逆置单链表,判断链表是否有环,取链表中间节点)(含核心代码与解析)

简介: 大厂面试经典单链表例题(创建有序单链表,逆置单链表,判断链表是否有环,取链表中间节点)(含核心代码与解析)

目录


引言

创建有序单链表

题目

算法思路

代码实现

逆置单链表

题目

算法思路

代码实现

判断单链表是否有环

题目

算法思路

代码实现

取单链表中间节点的数值

题目

算法思路

代码实现

总结


引言


有关单链表的基础操作,如动态分布空间,单链表创建的思路,单链表的增、删、改、毁,笔者已经在博客中详细解析了,有兴趣的小伙伴也可以取看看,

本次介绍的是有关单链表的四道大厂面试典中典,其中的逆置单链表更是重量级,大家放心食用😁


正文


创建有序单链表


题目


创建一个升序或降序的单链表,并打印输出,例如:

输入: 1 5 6 2 3
输出: 1 2 3 5 6


算法思路


算法思路:

       s1:每获得一个数据 就创建一个数据结点

       s2:把数据写入到数据结点中去

       s3:把写好的数据结点加入到链表中去

           分情况讨论:

               从无到有

               从少到多

                   头插法

                   尾插法

                   中间插入

我们将算法思路待人代码中观察


代码实现


Node *create_sort_list()
{
  u4 d;
  Node *pnew = NULL;    //指向 新创建的节点
  Node *head = NULL;
  while(1)
  {
    scanf("%d",&d);
    if(d == 0)        //约定输入0,结束输入
      break;
    pnew = malloc(sizeof(*pnew));    //分配空间
    pnew->data = d;                  //将数据写入数据节点
    pnew->next = NULL;
        //将写好的数据节点加入到链表
    if(head == NULL)                 //从无到有
    {
      head = pnew;
    }
    else                             //从少到多
    {
      Node *p = head;
      Node *pre = NULL;
      while(p)                     //找出链表中比新节点大的数据打的节点
      {
        if(p->data > pnew->data)    //找到就返回这个节点
        {
          break;
        }
        else                        //没找到就往下遍历,直到p==NULL,即新节点的值是最大的,插到末尾
        {
          pre = p;
          p = p->next;
        }
      }
      if(p != NULL)
      {
        if(p == head)            //头插法
        {
          pnew->next = head;   //新节点指向链表的第一个,即指向head
              head = pnew;     //然后将head指向新节点
        }
        else                     //插入中间
        {
          pnew->next = p;
          pre->next = pnew;
        }
      }
      else                         //插到末尾
      {
        pre->next = pnew;
      }
    }
  }
  return head;
}


逆置单链表


题目


就地逆置一个链表(不允许申请新的结点空间)

   例子:

       h: 1 5 3 4

       =>

       h: 4 3 5 1

       要求:

           不允许申请新的结点空间


算法思路


把原链表的每一个结点 ,摘下来 ,然后按头插法 加入到新链表。

 

Node *reverse(Node *h)
{
  //创建一个指向逆置后链表的第一个结点
  //创建一个指针p为遍历指针
  while(p)
  {
      //step 1:把h指向的链表的第一个结点摘下来
    //step2: 按照头插法 把p结点 加入到逆置后的链表first
    //step2.1 从无到有
    //step2.2 从少到多
  }
      //返回逆置链表的第一个节点
}


代码实现


Node *reverrse(Node *h)
{
  Node *first = NULL;        //创建一个指向逆置后链表的第一个结点
  Node *p = h;               //创建一个指针p为遍历指针
  while(p)
  {
        //step 1:把h指向的链表的第一个结点摘下来
    h = h->next;
    p->next = NULL;
        //step2: 按照头插法 把p结点 加入到逆置后的链表first
    //step2.1 从无到有
    if(first == NULL)
    {
      first = p;
    }
    else            //step2.2 从少到多
    {
      p->next = first;
      first = p;
    }
    p = h;
  }
  return first;        //返回逆置链表的第一个节点
}


判断单链表是否有环


题目


判断一个单链表是否有环


算法思路


快慢指针

定义两个指针p和q;

让p每次走两步,q每次走一步

当p和q相遇时则说明有环,否则就没有环。


代码实现


/*
is_a_ring:判断单链表是否有环
    @h:指定的单链表的第一个节点指针
    返回值:
        1 有环
        0 无环
 */
int is_a_ring(Node *h)
{
  Node *p = NULL;//fast指针
  Node *q = NULL;//slow指针
  p = h;
  q = h;
  while(p)
  {
    p = p->next;
    if(p == NULL)
    {
        break;
    }
    p = p->next;
    q = q->next;
    if(p == q)
    {
      return 1;
    } 
  }
  return 0;
}


取单链表中间节点的数值


题目


写一个程序,获取链表中间结点的值

       例子:

           对于奇数结点 返回中间结点值

           输入 :1 2 3 4 5

           输出:3

           对于偶数结点  返回较小下标的值

           输入: 25 69 78 45 96 -21 -47 62

           输出:45


算法思路


定义两个指针p和q;

让p每次走两步 q走一步

当p走到链表末尾时 此时q刚好走到链表的中间结点。


代码实现


void get_middle_v(Node *h)
{
  Node *pk = h;    //快指针
  Node *pm = h;    //慢指针
  while(1)
  {
    if(pk->next == NULL)    //快指针已经到了最后一个(奇数个)
    {
      printf("%d\n",pm->data);
      break;
    }
    else
    {
      pk = pk->next->next;        //快指针的下一个是最后一个(偶数个)
      if(pk == NULL)
      {
        printf("%d\n",pm->data);
        break;
      }
      pm = pm->next;
    }
  }
}


总结


这些题目其实总体难度不高,更重要的是体会其中的算法思路,分类思想,利用好单链表本身的空间余节点取解决问题。

相关文章
|
1月前
|
存储 缓存 NoSQL
Redis常见面试题全解析
Redis面试高频考点全解析:从过期删除、内存淘汰策略,到缓存雪崩、击穿、穿透及BigKey问题,深入原理与实战解决方案,助你轻松应对技术挑战,提升系统性能与稳定性。(238字)
|
3月前
|
存储 安全 测试技术
Python面试题精选及解析
本文详解Python面试中的六大道经典问题,涵盖列表与元组区别、深浅拷贝、`__new__`与`__init__`、GIL影响、协程原理及可变与不可变类型,助你提升逻辑思维与问题解决能力,全面备战Python技术面试。
155 0
|
1月前
|
监控 Java 关系型数据库
面试性能测试总被刷?学员真实遇到的高频问题全解析!
面试常被性能测试题难住?其实考的不是工具,而是分析思维。从脚本编写到瓶颈定位,企业更看重系统理解与实战能力。本文拆解高频面试题,揭示背后考察逻辑,并通过真实项目训练,帮你构建性能测试完整知识体系,实现从“会操作”到“能解决问题”的跨越。
|
5月前
|
存储 安全 Java
2025 最新史上最全 Java 面试题独家整理带详细答案及解析
本文从Java基础、面向对象、多线程与并发等方面详细解析常见面试题及答案,并结合实际应用帮助理解。内容涵盖基本数据类型、自动装箱拆箱、String类区别,面向对象三大特性(封装、继承、多态),线程创建与安全问题解决方法,以及集合框架如ArrayList与LinkedList的对比和HashMap工作原理。适合准备面试或深入学习Java的开发者参考。附代码获取链接:[点此下载](https://pan.quark.cn/s/14fcf913bae6)。
3121 48
|
5月前
|
缓存 NoSQL Java
Java Redis 面试题集锦 常见高频面试题目及解析
本文总结了Redis在Java中的核心面试题,包括数据类型操作、单线程高性能原理、键过期策略及分布式锁实现等关键内容。通过Jedis代码示例展示了String、List等数据类型的操作方法,讲解了惰性删除和定期删除相结合的过期策略,并提供了Spring Boot配置Redis过期时间的方案。文章还探讨了缓存穿透、雪崩等问题解决方案,以及基于Redis的分布式锁实现,帮助开发者全面掌握Redis在Java应用中的实践要点。
331 6
|
5月前
|
NoSQL Java 微服务
2025 年最新 Java 面试从基础到微服务实战指南全解析
《Java面试实战指南:高并发与微服务架构解析》 本文针对Java开发者提供2025版面试技术要点,涵盖高并发电商系统设计、微服务架构实现及性能优化方案。核心内容包括:1)基于Spring Cloud和云原生技术的系统架构设计;2)JWT认证、Seata分布式事务等核心模块代码实现;3)数据库查询优化与高并发处理方案,响应时间从500ms优化至80ms;4)微服务调用可靠性保障方案。文章通过实战案例展现Java最新技术栈(Java 17/Spring Boot 3.2)的应用.
459 9
|
5月前
|
缓存 算法 NoSQL
校招 Java 面试高频常见知识点深度解析与实战案例详细分享
《2025校招Java面试核心指南》总结了Java技术栈的最新考点,涵盖基础语法、并发编程和云原生技术三大维度: 现代Java特性:重点解析Java 17密封类、Record类型及响应式Stream API,通过电商案例演示函数式数据处理 并发革命:对比传统线程池与Java 21虚拟线程,详解Reactor模式在秒杀系统中的应用及背压机制 云原生实践:提供Spring Boot容器化部署方案,分析Spring WebFlux响应式编程和Redis Cluster缓存策略。
151 0
|
5月前
|
存储 缓存 安全
Java 集合容器常见面试题及详细解析
本文全面解析Java集合框架,涵盖基础概念、常见接口与类的特点及区别、底层数据结构、线程安全等内容。通过实例讲解List(如ArrayList、LinkedList)、Set(如HashSet、TreeSet)、Map(如HashMap、TreeMap)等核心组件,帮助读者深入理解集合容器的使用场景与性能优化。适合准备面试或提升开发技能的开发者阅读。
106 0
|
5月前
|
存储 Java 数据库
应届生面试高频 Java 基础问题及详细答案解析
摘要: Java数据类型分为基本类型(如int、float等)和引用类型(如类、数组)。final可修饰类、方法和变量,使其不可继承、重写或修改。static用于类级别的变量和方法,共享于所有实例。"=="比较基本类型的值或引用类型的地址,而equals比较对象内容(需重写)。Java只有值传递,对于引用类型传递的是地址副本。String对象不可变,拼接操作会创建新对象而非修改原对象。Java 10的var支持类型推断,Java 16的Record提供不可变类简化。
129 0
|
5月前
|
存储 安全 Java
应届生面试高频 Java 基础问题及实操示例解析
本文总结了Java基础面试中的高频考点,包括数据类型分类、final修饰符的三种用途、static关键字特性、==与equals的区别、Java只有值传递的特性、String的不可变性、Error与Exception的差异、程序初始化顺序规则,以及IO流的字节流/字符流分类。每个问题都配有简明定义和典型示例,如用final修饰变量示例、static方法调用限制说明等,帮助应聘者快速掌握核心概念和实际应用场景。
106 0

推荐镜像

更多
  • DNS