1 单链表逆序,是在原基础上逆序
最常见的方式新建两个节点分别指向当前node节点的前一个节点和后一个节点,然后将node->next指向前一个节点pre,再将pre节点更改为node,最后将node节点移至next,即完成了对当前node节点的更改。实现代码见下:
void back_list(Node* node)
{
Node* pre = NULL; // 指向node节点的前一个节点
Node* next = NULL; //指向node节点的下一个节点
if(node==NULL) return NULL;
while(node!=NULL)
{
next = node->next;
node->next = pre;
pre = node;
node = next;
}
}
2 找出单链表中倒数第n个节点
同样新建两个指针,一个快指针,一个慢指针,让快指针先走n步,然后快慢指针同时每次前进一步,直到快指针前进到null结束。实现代码见下:
Node* backwards_n_list(Node* head,int n)
{
if(head==NULL) return NULL;
Node* after = head;
Node* front = head;
for(int i=0;i<n;i++)
{
if(front->next)
{
front=front->next;
}
else
{
if(i==n-1) return after;
else return NULL;
}
}
while(front)
{
front = front->next;
after = after->next;
}
return after;
}
3 判断单链表中是否有环
比较简单的做法:新建两个快慢指针,快指针走两步,满指针走一步,若有循环,则快指针必会转过一圈,在此之后,快指针与满指针的距离每次都会减1,当减到0的时候,二者相遇。使用此原理,实现代码如下:
bool is_hoop(Node* head)
{
Node* after = head;
Node* front = head;
while(front!=NULL&& front->next!=NULL)
{
front = front->next->next;
after = after->next;
if(front == after) return true;
}
return false;
}
4 找出环形单链表中环的入口
在有环的基础上,有一入环点和相遇点,假设头指针的位置到入环点的距离为a,入环点到相遇点的距离为b,相遇点到入环点的距离为b,慢指针到达相遇点距离为a+b,快指针到达相遇点的距离为a+b+(b+c)k,由于快指针走两步,慢指针走一步,因此快指针走的距离是慢指针的两倍。因此有2(a+b) = a+b+(b+c)k ,即a = c+k(b+c)(k-1),也就是说当两指针到达相遇点时,让慢指针回到头结点位置,此时两者同时以步长为1开始前进,两者再次相遇时候就是入环点。实现代码如下:
Node* hoop_entrance(Node* head)
{
// write code here
Node* after = head;
Node* front = head;
while(front && front->next)
{
front = front->next->next;
after = after->next;
if(front == after) break;
}
if(front == NULL||front->next == NULL) return NULL;
after = head;
while(after!=front)
{
after = after->next;
front = front->next;
}
return front;
}
5 合并两个有序列表(升序),合并后依然有序
不新建链表,只在原有链表基础上修改。
新建三个新指针,s,n1,n2,s指向链表第一个节点数据较小的那个节点,n1和n2分别指向两个链表的节点,每次比较n1和n2的数据,s每次指向较小的那个,直至n1或n2指向NULL为止。实现代码如下:
Node* merge_Linked_list(Node* head1,Node* head2)
{
if(head1==NULL||head2==NULL) return NULL;
if(head1==NULL&&head2!=NULL) return head2;
if(head1!=NULL&&head2==NULL) return head1;
Node* n1 = head1;
Node* n2 = head2;
Node* s = NULL;
if(n1->data < n2->data)
{
s = n1;
n1 = n1->next;
}
else
{
s = n2;
n2=n2->next;
}
while(n1&&n2)
{
if(n1->data <= n2->data)
{
s->next = n1;
s = n1;
n1 = n1->next;
}
else
{
s->next = n2;
s = n2;
n2 = n2->next;
}
}
if(n1 == NULL) s->next = n2;
if(n2 == NULL) s->next = n1;
if(head1->data < head2->data) return head1;
else return head2;
}
6 判断两个链表是否是y型链表
最简单的实现方式:设置两个新指针,分别指向两个链表,让二者开始同时前进,当n1碰到NULL的时候,再让它回到另一个链表的头节点为止前进,n2同理。二者相遇,即y型链表。实现代码如下:
Node* is_yList(Node* head1,Node* head2)
{
Node *n1 = head1;
Node *n2 = head2;
while(n1!=n2)
{
n1 = (n1 ==NULL ? head2 : n1->next);
n2 = (n2 ==NULL ? head1 : n2->next);
}
return n1;
}