`
xinklabi
  • 浏览: 1591961 次
  • 性别: Icon_minigender_1
  • 来自: 吉林
文章分类
社区版块
存档分类
最新评论

链表常见笔试题

阅读更多

链表的一些常见笔试面试问题总结及代码

先什么也不说,假设链表节点的数据结构为:

struct node
{
int data;
struct node* next;
};

创建单链表的程序为:

struct node* create(unsigned int n)
{
//创建长度为n的单链表
assert(n > 0);
node* head;
head = new node;
head->next = NULL;
cout << "请输入head节点的值(int型):";
cin >> head->data;
if (n == 1)
{
   return head;
}
node* p = head;
for (unsigned int i = 1; i < n; i++)
{
   node* tmp = new node;
   tmp->next = 0;
   cout << "请输入第" << i+1 << "个节点的值(int):";
   cin >> tmp->data;
   p->next = tmp;
   p = tmp;
}
return head;
}

问题1:链表逆置

思想为:head指针不断后移,指针反向即可,代码为:

void reverse(node*& head)
{
if (head != NULL && head->next != NULL)
{
   node* p = head;
   node* q = head->next;
   p->next = NULL;
   while (q->next != NULL)
   {
    head = q->next;
    q->next = p;
    p = q;
    q = head;
   }
   head->next = p;
}
return;
}

问题2:删除不知头结点链表的某个节点
如果单向链表不知道头节点,一个指针指向其中的一个节点,问如何删除这个指针指向的节点?

思想为:把这个节点的下一个节点的值复制给该节点,然后删除下一个节点即可。

问题3:怎么判断链表中是否有环?

思想为:设置两个指针,一个步长为1,另一个步长为2,依次后移,如果相遇且都不为空,则有环。

与这个类似的问题包括:怎么快速检测出一个巨大的链表中的死链?或者如何找出一个单链表的中间节点?

代码为:

bool loop(node* head)
{
bool flag = true;
if (head == NULL)
{
   flag = false;
}
node* one = head;
node* two = head->next;
if (two == NULL)
{
   flag = false;
}
while (one != two)
{
   if (one != NULL)
   {
    one = one->next;
   }
   if (two != NULL)
   {
    two = two->next;
   }
   if (two == NULL)
   {
    break;
   }
   two = two->next;
   if (one == NULL || two == NULL)
   {
    break;
   }
}
if (one == NULL || two == NULL)
{
   flag = false;
}
return flag;
}

问题4:如果一个单向链表,其中有环,怎么找出这个链表循环部分的第一个节点?

思想为:假设该节点在x位置处,假设步长为1的指针和步长为2的指针相遇在x+z处,循环的长度为y,那么2(x+z)-(x+z)=k*y,
那么当一个指针再从开始出后移时,另一个指针从相遇点开始后移时,这两个指针就会在循环开始处相遇。

代码为:

node* findLoopPlace(node* head, unsigned int* place = NULL)
{
//查找循环的位置,place存储位置
if (!loop(head))
{
   return NULL;
}
node* one = head;
node* two = head->next;
unsigned int count = 1;

while (one != two)
{
   one = one->next;
   two = two->next->next;
}
one = head;
while (one != two)
{  
   if (count != 1)
   {
    one = one->next;
   }
   two = two->next;
   count++;
}
*place = count;
return one;
}

问题5:如何查找链表中倒数第k个节点?

思想为:两个指向头结点的指针,一个先向后移动k位,然后两个同时向后面移动直到一个节点到达链尾,前面一个指针的位置就是了。

node* findLastK(node* head,unsigned int k)
{
//查找单链表倒数第k个位置
node* p = head;
unsigned int count = 0;
while (p != NULL)
{
   p = p->next;
   count++;
}
if (count < k)
{
   return NULL;
}
p = head;
node* q = head;
for (unsigned int i = 0; i < k; i++)
{
   p = p->next;
}
while (p != NULL)
{
   q = q->next;
   p = p->next;
}
return q;
}

问题6:编程序判断两个链表是否相交。

这个问题的精彩解说请参见《编程之美》一书之《编程判断两个链表是否相交》,这里就不写了,该书的pdf文档在网上很好下。

文章后面给了两个扩展问题:

(1)如果链表可能有环,如何做判断?

思想为:首先应该明白,只有一个链表有环的情况下是不会相交的,只有都有环或者都没有环的情况下才可能相交,都没有环的情况下最简便的方法就是判断链尾是否相交即可;都有环的情况下,分别找到环上的任一点,一个不动,另一个步进,即可判断是否相交。

(2)如何求相交链表的第一个节点?应该为单链表情况

思想为:方法一是先把任一个链表连成环,即从表尾接到表头,按照问题4的解法;方法二是计算两个链表的长度,而两个链表是按照尾部对齐的,那么从短链表的第一个位置从长链表的第长度差+1的位置依次比较指针值,相等的位置即是。

相关程序包括:单链表中在某个位置插入环以及销毁链表等,代码如下:

void insertCircle(node* head, unsigned int n)
{
//在第n个位置形成环,记head为n=1
node* p = head;
node* q = head;
unsigned int count = 1;

while(p->next != NULL)
{
   p = p->next;
   count++;
}
if (n <= count)
{
   for (unsigned int i = 1; i < n; i++)
   {
    q = q->next;
   }
   p->next = q;
}
return;
}

void destroy(node* head)
{
//销毁链表
if (loop(head))
{
   node *q = findLoopPlace(head);
   while (head != q)
   {
    node* p = head;
    head = head->next;
    delete p;
   }
   head = head->next;
   q->next = NULL;
   destroy(head);
}
else
{
   while (head != NULL)
   {
    node* p = head;
    head = head->next;
    delete p;
   }
}
}

分享到:
评论

相关推荐

    C语言链表在笔试常考题.docx

    在C语言笔试面试中,链表是一道常考题,以下是两个常见的链表题目及其解决方案。 链表逆置 链表逆置是将链表的节点顺序逆转的过程。例如,原始链表为1-&gt;2-&gt;3-&gt;4-&gt;5,逆置后的链表为5-&gt;4-&gt;3-&gt;2-&gt;1。 解决方案: `...

    软件类职位常见笔试题

    "软件类职位常见笔试题"这个主题涵盖了多种类型的题目,旨在测试候选人在编程、算法、操作系统、网络、数据库等多个方面的知识。以下是对这些常见笔试题型的详细解析: 1. **编程题**:编程题通常要求应聘者用特定...

    Java程序员常见笔试题

    Java 程序员常见笔试题 Java 是一种广泛应用的编程语言,掌握 Java 的基础知识是任何 Java 程序员的必备技能。下面是 Java 程序员常见笔试题的知识点总结: 面向对象的特征 抽象:抽象是忽略一个主题中与当前目标...

    计算机常见笔试题

    ### 计算机常见笔试题 #### 题目1:单向链表倒序建立 - **题目描述**:给定一个单向链表,要求在不申请新空间的情况下将其倒序,并返回新的链表头节点。 - **链表结构体定义**: ```cpp struct Link { int data;...

    百度历年笔试题

    百度笔试题常常涉及到算法与数据结构的运用,如排序算法(快速排序、归并排序等)、查找算法(二分查找、哈希查找)以及常用的数据结构(链表、栈、队列、树、图)。这些基础知识是解决问题的基础,熟练掌握能提高...

    Java笔试题大集合及答案(另附各大公司笔试题)

    Java作为一门广泛使用的编程语言,其笔试题涵盖了基础语法、数据结构、算法、多线程、网络编程、设计模式等多个方面。本资料集合了大量Java笔试题,旨在帮助求职者全面复习并准备Java相关的笔试环节,同时包含了各大...

    125条常见的java面试笔试题大汇总.pdf

    以上是对《125条常见的java面试笔试题大汇总》部分知识点的详细解析。这些知识点涵盖了Java编程的基础概念和技术要点,对于准备面试的求职者来说非常重要。理解这些概念不仅有助于提高编程技能,还能加深对Java语言...

    华为常见的笔试题实现

    2. **数据结构与算法**:华为的笔试题中常涉及到数组、链表、栈、队列、树(如二叉树、平衡树)、图等数据结构,以及排序(如快速排序、归并排序)、查找(如二分查找)等算法。熟练掌握这些基础知识,能够高效地...

    南瑞笔试题集合

    【南瑞笔试题集合】是针对应届毕业生设计的一系列笔试试题,旨在考察应聘者在IT领域的基础知识、专业技能和解决问题的能力。南瑞,作为中国电力行业的重要企业,其笔试环节通常涵盖计算机科学、软件工程、电力系统等...

    中兴笔试题 笔试题 找工作

    【中兴笔试题】主要考察的是应聘者的基础 IT 知识,尤其是计算机科学与技术方面的内容,包括数据结构、数据库管理、操作系统、编程语言(C 和 Java)、网络通信以及软件工程的基本概念。以下是对这些知识点的详细解释...

    计算机专业常见笔试题.

    计算机专业常见笔试题是毕业生和求职者在找工作时必须面对的一个环节,这些题目涵盖了计算机科学与技术的多个领域,旨在测试应聘者的理论基础、编程能力、逻辑思维以及问题解决技巧。下面将根据这个主题,详细解析...

    南京300云java招聘笔试题库

    常见的算法题型包括但不限于排序(冒泡排序、快速排序、归并排序等)、查找(二分查找、哈希查找等)、图论(深度优先搜索、广度优先搜索、最短路径算法等)、动态规划、递归和回溯等。对于数据结构,如栈、队列、...

    C++常见笔试题汇总

    ### C++常见笔试题知识点汇总 #### 一、链表反转 **知识点1:单向链表的反转** - **应用场景**: 单向链表的反转是计算机科学中常见的问题,尤其是在面试中常被用来考察候选人的编程能力和逻辑思维能力。 - **基本...

    IT常见笔试面试题

    这份名为“IT常见笔试面试题”的资料,无疑是为毕业生和求职者提供了一个宝贵的准备工具。以下是对这些常见题型的详细解读,希望能帮助你更好地理解和应对IT行业的面试挑战。 一、编程能力 在IT面试中,编程能力是...

    2015校园招聘笔试题大合集

    2015年的校园招聘笔试题大合集是一份宝贵的资源,涵盖了当年各大IT公司对候选人的技术能力考察点。这份合集不仅包含了基础的编程知识,还可能涉及算法、数据结构、操作系统、计算机网络等多个领域,帮助我们深入了解...

    java外包笔试题两套.zip

    外包公司常常会用Java笔试题来评估应聘者的技能水平。本压缩包"java外包笔试题两套.zip"包含了两套针对Java程序员的笔试题目,分别为"java外包笔试A卷.docx"和"java外包笔试F卷.docx",旨在测试应聘者的基础知识、...

    华为java笔试题,java常见笔试题

    LinkedList使用双向链表,按索引访问相对较慢,但插入和删除操作速度快,适合频繁进行这些操作的场景。 【线程同步示例】 在多线程环境中,当多个线程对同一变量进行增减操作时,需要考虑线程同步以避免数据不一致...

Global site tag (gtag.js) - Google Analytics