面试中常见的链表题目
来源:互联网 发布:希捷官方数据恢复 编辑:程序博客网 时间:2024/04/28 18:18
最近参加面试遇到的一些常见的单链表题目,总结思路和实现代码。
1.单链表的反序
2.给单链表建环
3.检测单链表是否有环
4.给单链表解环
5.检测两条链表是否相交
6.不输入头节点,删除单链表的指定节点(只给定待删除节点指针)
7.合并两个有序链表
1.单链表的反序
01
//逆转链表,并返回逆转后的头节点
02
node* reverse(node *head)
03
{
04
if
(head == NULL || head->next == NULL)
05
{
06
return
head;
07
}
08
node *cur = head;
09
node *pre = NULL;
10
node *tmp;
11
while
(cur->next)
12
{
13
tmp = pre;
14
pre = cur;
15
cur = cur->next;
16
pre->next = tmp;
//操作pre的next逆转
17
}
18
cur->next = pre;
//结束时,操作cur的next逆转
19
return
cur;
20
}
01
//方法二
02
node *reverse(node *head)
03
{
04
node *p, *q, *r;
05
06
p = head;
07
q = p->next;
08
09
while
(q != NULL)
10
{
11
r = q->next;
12
q->next = p;
13
p = q;
14
q = r;
15
}
16
17
head->next = NULL;
18
head = p;
19
20
return
head;
21
}
2.给单链表建环
01
//给单链表建环,让尾指针,指向第num个节点,若没有,返回false
02
bool
bulid_looplink(node *head,
int
num)
03
{
04
node *cur = head;
05
node *tail = NULL;
06
int
i = 0;
07
if
(num <= 0 || head == NULL)
08
{
09
return
false
;
10
}
11
for
(i = 1; i < num; ++i)
12
{
13
if
(cur == NULL)
14
{
15
return
false
;
16
}
17
cur = cur->next;
18
}
19
tail = cur;
20
while
(tail->next)
21
{
22
tail = tail->next;
23
}
24
tail->next = cur;
25
return
true
;
26
}
3.检测单链表是否有环
01
//检测单链表是否有环,快慢指针
02
bool
detect_looplink(node *head)
03
{
04
node *quick_node = head->next, *slow_node = head;
05
if
(head == NULL || head->next == NULL)
06
{
07
return
false
;
08
}
09
while
(quick_node != slow_node)
10
{
11
if
(quick_node == NULL || slow_node == NULL)
12
break
;
13
quick_node = quick_node->next->next;
14
slow_node = slow_node->next;
15
}
16
if
(quick_node != NULL && slow_node != NULL)
//非尾节点相遇
17
return
true
;
18
return
false
;
19
}
4.给单链表解环
ps:为了增加节点位图的效率,本应使用hash或则红黑树,这里不造车了,直接用 set容器
01
//找到有环节点,并解环,找到并解环,返回true,无环,返回false
02
//思路:先找到环节点:被2个节点指向的节点(一定有环的条件)ps:不考虑中间环,因为只有一个next节点,只可能是尾环
03
bool
unloop_link(node *head)
04
{
05
set<node *> node_bitmap;
//node的地址位图
06
unsigned
int
num = 0;
07
node *cur = head, *pre = NULL;
08
while
(cur != NULL)
09
{
10
if
(!node_bitmap.count(cur) )
//该节点未被遍历过
11
{
12
node_bitmap.insert(cur);
13
++num;
14
}
15
else
//指向已被遍历过的节点,此时pre节点为尾节点
16
{
17
pre->next = NULL;
18
return
true
;
19
}
20
pre = cur;
21
cur = cur->next;
22
}
23
return
false
;
24
}
01
//检测两条链表是否相交,是则返回第一个交点,否则返回NULL
02
//思路:把2个链表各遍历一遍,记下长度length1和length2,若2者的尾节点指针相等,则相交。
03
// 之后再把长的链表从abs(len1-len2)的位置开始遍历,第一个相等的指针为目标节点
04
node* detect_intersect_links(node *first_link, node *second_link)
05
{
06
int
legnth1 = 1, length2 = 1, pos = 0;
07
node *cur = NULL, *longer_link = first_link, *shorter_link = second_link;
08
if
(first_link == NULL || second_link == NULL)
09
{
10
return
NULL;
11
}
12
while
(first_link->next || second_link->next)
//遍历2个链表
13
{
14
if
(first_link->next)
15
{
16
first_link = first_link->next;
17
++legnth1;
18
}
19
if
(second_link->next)
20
{
21
second_link = second_link->next;
22
++length2;
23
}
24
}
25
if
(first_link != second_link)
//比较尾节点
26
{
27
return
NULL;
28
}
29
pos = legnth1 - length2;
30
if
(legnth1 < length2)
//保证 longer_link为长链表
31
{
32
pos = length2 - legnth1;
33
cur = longer_link;
34
longer_link = shorter_link;
35
shorter_link = cur;
36
}
37
while
(pos-- > 0)
38
longer_link = longer_link->next;
39
while
(longer_link || shorter_link)
40
{
41
if
(longer_link == shorter_link)
//找到第一个交点
42
{
43
return
longer_link;
44
}
45
longer_link = longer_link->next;
46
shorter_link = shorter_link->next;
47
}
48
return
NULL;
49
}
6.不输入头节点,删除单链表的指定节点(只给定待删除节点指针)
01
//无头节点,随机给出单链表中一个非头节点,删除该节点,当传入空节点,或者尾节点时,返回false
02
//思路:由于没有头节点,非循环单链表,无法获取目标节点的前节点,所以只能把它的next节点数据前移,并删除next节点
03
//ps:当传入节点为尾节点,无法用此方法删除
04
bool
withouthead_delete_node(node *target_node)
05
{
06
node *cur = NULL;
07
if
(target_node == NULL || target_node->next == NULL)
//空节点或者尾节点,失败
08
{
09
return
false
;
10
}
11
cur = target_node->next;
12
target_node->name = cur->name;
13
target_node->next = cur->next;
14
delete
cur;
15
return
true
;
16
}
7.合并两个有序链表
001
/*
002
递归实现:
003
①算法思想:
004
递归终止条件:若head1为空,返回head2指针(head);若head2为空,返回head1指针(head)
005
递归过程:
006
007
1 若head1->data>head2->data; head 指针应该指向head2所指向的节点,而且head->next应该指向head1和head2->next两个链表的合成序列的头指针;
008
009
2 否则head 指针应该指向head1所指向的节点,而且head->next应该指向head->next和head2两个链表的合成序列的头指针;
010
*/
011
#include <iostream>
012
using
namespace
std;
013
014
/*节点的类定义*/
015
class
Node
016
{
017
public
:
018
int
data;
019
Node *next;
020
Node(
int
data)
021
{
022
this
->data = data;
023
}
024
};
025
026
/*链表的类定义*/
027
class
LinkedList
028
{
029
public
:
030
Node *head;
031
032
/*用一个整形数组作为参数的构造函数*/
033
LinkedList(
int
array[])
034
{
035
head =
new
Node(array[0]);
036
Node *temp = head;
037
int
i;
038
for
( i = 1; i < 3; i++ )
039
{
040
temp->next =
new
Node(array[i]);
041
temp = temp->next;
042
}
043
044
temp->next = NULL;
045
}
046
};
047
048
/*递归的合并两个有序链表*/
049
Node * mergeLinkedList(Node *head1, Node *head2)
050
{
051
Node *p = NULL;
052
053
if
(head1 == NULL && head2 == NULL)
054
return
p;
055
else
if
(head1 == NULL)
056
return
head2;
057
else
if
(head2 == NULL)
058
return
head1;
059
else
060
{
061
if
(head1->data < head2->data)
062
{
063
p = head1;
064
p->next = mergeLinkedList(head1->next, head2);
065
}
066
else
067
{
068
p = head2;
069
p->next = mergeLinkedList(head1, head2->next);
070
}
071
072
return
p;
073
}
074
}
075
076
/*打印链表的所有元素*/
077
void
printList(Node *head)
078
{
079
Node *temp = head;
080
while
(temp != NULL)
081
{
082
cout<<temp->data<<
" "
;
083
temp = temp->next;
084
}
085
}
086
087
int
main()
088
{
089
int
array1[3] = {2,5,8};
090
int
array2[3] = {1,6,7};
091
092
/*构造两个有序链表--list1和list2*/
093
LinkedList list1(array1);
094
LinkedList list2(array2);
095
096
/*递归的将这两个有序链表合并成一个有序链表*/
097
Node *new_head = mergeLinkedList(list1.head, list2.head);
098
099
/*打印有序链表*/
100
printList(new_head);
101
102
return
0;
103
}
转载于:http://blog.csdn.net/yongjunhe/article/details/8488091
0 0
- 面试中常见的链表题目
- 面试中常见的链表题目
- 面试中常见的链表题目
- 面试中常见的链表题目
- 转 面试中常见链表题目
- 面试中常见的50个面试题目及答案
- 常见的abap面试题目
- 常见的abap面试题目
- 常见的abap面试题目
- 常见的abap面试题目
- 常见的计算机网络面试题目
- php常见的面试题目
- python常见的面试题目
- 常见的SQL面试题目
- php常见的面试题目
- php常见的面试题目
- Java面试常见的题目
- java面试的常见题目
- C++ 虚函数表解析--陈皓
- jsp 工作原理
- Android: 在onCreate()中获得对象尺寸
- zookeeper 临时节点不消失的原因
- xpags repeat显示序号
- 面试中常见的链表题目
- mybaits错误解决:There is no getter for property named 'id' in class 'java.lang.String'
- Apache/.htaccess的Order Allow,Deny 详解
- 理解Java的GC日志
- 自定义可删除全部内容的EditText
- ViewPager的setOnPageChangeListener方法详解
- 匿名内部类
- Spring源码阅读(一):IOC容器的初始化
- Linux编译安装GCC-4.9.0