# 面试数据结构篇—单链表常考点汇总

 // Definition for singly-linked list.
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};

图1： 单链表图（感谢第七城市提供）

1：就地逆转单链表

2：检测单链表是否有环

3：判断两个单链表是否有交点，如果有交点，求交点

4：在O(1)时间内删除链表内的某一结点

5：如果单链表有环，求环的长度以及入环点

（一）就地逆转单链表

经典做法：设定三个指针，一个是pre（指向前一个结点），一个是current（指向当前结点），一个next（指向下一个结点），然后三个指针同时往右移，并且同时修改指针指向的位置

//reverse the single-list in place
//@author: zhang haibo
//@time: 2013-12-5
{
//check the head is or not NULL
//the head of the reverse list
ListNode* reverseHead = NULL;
//current listnode
ListNode* current = head;
//the previous listnode of current listnode
ListNode* pre = NULL;
while(current != NULL)
{
ListNode* next = current->next;
if(next == NULL)
current->next = pre;
pre = current;
current = next;
}

}

（二）检测单链表是否有环

//check the singly-list whether or not has cycle
//@author: zhang haibo
//@time: 2013-12-5
{
ListNode* slow = head;
ListNode* fast = head;
while(fast != NULL && fast->next != NULL)
{
slow = slow->next;
fast = fast->next->next;
if(slow == fast)
return true;
}

return false;
}

（三）判断两个单链表是否有交点，如果有交点，求交点

//check two lists have intersection or not.
//@author: zhang haibo
//@time: 2013-12-5
bool Is_Exist_Intersection(ListNode* list1, ListNode* list2, ListNode* &result)
{
if(list1 == NULL || list2 == NULL)
return false;
ListNode* p1 = list1;
ListNode* p2 = list2;
int length_of_list1 = 1;
int length_of_list2 = 1;
while(p1->next != NULL)
{
p1 = p1->next;
++length_of_list1;
}
while(p2->next != NULL)
{
p2 = p2->next;
++length_of_list2;
}

//not have the intersection
if(p1 != p2)
return false;

//have the intersection
p1 = list1, p2 = list2;
if(length_of_list1 < length_of_list2)
{
p1 = list2;
p2 = list1;
}

//p1 goes forward dis steps
int dis = abs(length_of_list1 - length_of_list2);
while(dis--)
p1 = p1->next;
//p1 and p2 goes forward	in the same time
while(p1 != p2 )
{
p1 = p1->next;
p2 = p2->next;
}

//set the result
result = p1;

return true;
}

（四）在O(1)时间内删除链表内的某一结点

1）如果此节点是尾节点，则必须从头进行扫描到尾部节点前一个节点，进行删除，耗费N-1时间。

2）如果此节点是内部节点，则删除此节点的下一个节点，并且交换两个节点的数据即可，耗费1时间。

//delete one node in the list
//@author: zhang haibo
//@time: 2013-12-5
ListNode* Delete_Node(ListNode* head, ListNode* deletedNode)
{
if(head == NULL || deletedNode == NULL)
//if deletedNode is the head of the list
{
}
//not the tail
if(deletedNode->next != NULL)
{
ListNode* next = deletedNode->next;
deletedNode->val = next->val;
deletedNode->next = next->next;
next = NULL;
}
else//the tail
{
ListNode* current = head;
while(current->next != deleteNode)
current = current->next;
current->next = NULL;
}
}

（五）如果单链表有环，求环的长度以及入环点

带环链表有如下几点性质，这里不再证明，请找相关资料查看：

1：快指针（每次走两步）和慢指针（每次走一步）肯定会在第一圈相遇

2：相遇点到入环点 和  链表头指针到入环点 的距离是相同的。

//find the entrance point and
// calculate the length of cycle
//@author: zhang haibo
//@time:  2013-12-5
ListNode* Find_Loop_Port(ListNode* head, int& length)
{
length = 0;
return NULL;

ListNode* slow = head;
ListNode* fast = head;
while(fast != NULL && fast->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
++length;
}

//no cycle
if(fast == NULL || fast->next == NULL)
{
length = 0;
return NULL;
}

//set slow point to the start head
while(slow != fast)
{
slow = slow->next;
fast = fast->next;
++length;
}

return slow;
}

• 本文已收录于以下专栏：

## LeetCode 25. Reverse Nodes in k-Group（反转链表）

• jmspan
• 2016年05月20日 10:35
• 342

## Linux ipcs 命令和ipcrm命令详解

ipcs 命令 　　用途 ： linux/uinx上提供关于一些进程间通信方式的信息，包括共享内存，消息队列，信号，报告进程间通信设施状态。  　　语法 　　    ipcs [ -m] [ -...

## java数据结构—单链表的实现原理

举报原因： 您举报文章：面试数据结构篇—单链表常考点汇总 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)