`
xinklabi
  • 浏览: 1560353 次
  • 性别: 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;
   }
}
}

分享到:
评论

相关推荐

    华为常见笔试题大全常考知识点

    华为常见笔试题大全,常考知识点如static,IP地址,数据结构,链表,指针,字符串常见函数的实现,文件操作等

    面试中常见---链表题,C/C++

    数据结构, 链表,笔试,很多次碰到,数据结构, 链表,笔试,很多次碰到。

    知名公司笔试中常见数据结构试题

    知名公司常见的数据结构笔试试题,希望对大家有用

    C++链表逆序经典实现

    IT公司最常见笔试题。2010-06-07编写。欢迎讨论。 QQ:114723704

    C++笔试宝典

    C++笔试题 笔试资料 C++常见笔试题 C++笔试题大全

    125问常见的java面试笔试题大汇总

    所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项...

    富士通c++面试题

    C++常见笔试题和面试题目-富士通南大软件 ①链表反转 单向链表的反转是一个经常被问到的一个面试题,也是一个非常基础的问题。比如一个链表 是这样的: 1-&gt;2-&gt;3-&gt;4-&gt;5 通过反转后成为5-&gt;4-&gt;3-&gt;2-&gt;1。 最容易想到的...

    《程序员代码面试指南》、公司招聘笔试题、《剑指Offer》、算法、数据结构.zip

    常见的数据结构有数组、链表、栈、队列、树、图等。 算法则是解决特定问题的步骤,是对数据运算和操作的详细描述。算法的设计和选择会直接影响到程序的效率,因此,在设计和选择算法时,需要考虑到时间复杂度、空间...

    数据结构笔试常见题解

    BNF.txt fibonacci.txt link.txt misc.txt 二叉树公共祖先.txt 二叉树路径.txt 大数运算.txt 排序.txt 最小公倍数和最大公约.txt 求值表达式.txt 测试用例.txt 英文名词.txt 链表循环检测.txt

    java面试题库2021.pdf

    ④JSTL、 DisplayTag 等常见标签库的用法 3、 Web 编程原理 ① HTTP 协议 ②请求/相应架构原理 ③web 容器 四、 JDBC 编程 1、 SQL 基础 2、 JDBC 基础 ①数据库 ②数据库连接池 ③事物管理, 批处理 3、 JDBC 进阶 ...

    最全面试笔试整合(比较齐全包括网页,文档。。。)

    复件 华为面试题.java华为面试题 JAVA方面 1 面向对象的特征有哪些方面 2 String是最基本的数据类型吗? 3 int 和 Integer 有什么区别 4 String 和StringBuffer的区别 5 运行时异常与一般异常有何异同? 异常...

    免费下载:C语言难点分析整理.doc

    19. C语言笔试-运算符和表达式 104 20. C语言编程准则之稳定篇 107 21. C语言编程常见问题分析 108 22. C语言编程易犯毛病集合 112 23. C语言缺陷与陷阱(笔记) 119 24. C语言防止缓冲区溢出方法 126 25. C语言高效...

    C语言难点分析整理.doc

    19. C语言笔试-运算符和表达式 104 20. C语言编程准则之稳定篇 107 21. C语言编程常见问题分析 108 22. C语言编程易犯毛病集合 112 23. C语言缺陷与陷阱(笔记) 119 24. C语言防止缓冲区溢出方法 126 25. C语言...

    c语言难点分析整理,C语言

    19. C语言笔试-运算符和表达式 104 20. C语言编程准则之稳定篇 107 21. C语言编程常见问题分析 108 22. C语言编程易犯毛病集合 112 23. C语言缺陷与陷阱(笔记) 119 24. C语言防止缓冲区溢出方法 126 25. C语言高效...

    高级C语言 C 语言编程要点

    19. C语言笔试-运算符和表达式 104 20. C语言编程准则之稳定篇 107 21. C语言编程常见问题分析 108 22. C语言编程易犯毛病集合 112 23. C语言缺陷与陷阱(笔记) 119 24. C语言防止缓冲区溢出方法 126 25. C语言高效...

    高级进阶c语言教程..doc

    19. C语言笔试-运算符和表达式 104 20. C语言编程准则之稳定篇 107 21. C语言编程常见问题分析 108 22. C语言编程易犯毛病集合 112 23. C语言缺陷与陷阱(笔记) 119 24. C语言防止缓冲区溢出方法 126 25. C语言高效...

    史上最强的C语言资料

    19. C语言笔试-运算符和表达式 104 20. C语言编程准则之稳定篇 107 21. C语言编程常见问题分析 108 22. C语言编程易犯毛病集合 112 23. C语言缺陷与陷阱(笔记) 119 24. C语言防止缓冲区溢出方法 126 25. C语言高效...

    高级C语言详解

    19. C语言笔试-运算符和表达式 104 20. C语言编程准则之稳定篇 107 21. C语言编程常见问题分析 108 22. C语言编程易犯毛病集合 112 23. C语言缺陷与陷阱(笔记) 119 24. C语言防止缓冲区溢出方法 126 25. C语言高效...

    C语言难点分析整理

    19. C语言笔试-运算符和表达式 104 20. C语言编程准则之稳定篇 107 21. C语言编程常见问题分析 108 22. C语言编程易犯毛病集合 112 23. C语言缺陷与陷阱(笔记) 119 24. C语言防止缓冲区溢出方法 126 25. C语言高效...

    leetcode答案-Algorithm:xyzliu学习算法

    链表、队列、栈、树、图以及常见的算法思想,如递归、枚举、动态规划这些都没学过,那么我们不应该盲目疯狂地去刷 题。而是先去找本书先去学习这些必要的知识,然后再去刷题。因为如果这些基础都不不懂的话,一道题...

Global site tag (gtag.js) - Google Analytics