链表拆分与快慢指针相关算法题
一拆分为二
设 C = a 1 , b 1 , a 2 , b 2 , … , a m , b m C={a_{1},b_{1},a_{2},b_{2},\dots,a_{m},b_{m}} C=a1,b1,a2,b2,…,am,bm,为线性表,采用带头节点的单链表存放,将其拆分为两个线性表
使得 A = a 1 , a 2 , … , a n A=a_{1},a_{2},\dots,a_{n} A=a1,a2,…,an, B = b n , … , b 2 , b 1 B=b_{n},\dots,b_{2},b_{1} B=bn,…,b2,b1
算法思想
循环遍历链表C,
采用尾插法将一个节点插入表A,这个节点为奇数号节点,这样建立的表A与原来的节点顺序相同;
采用头插法将下一节点插入表B,这个节点为偶数号节点,这样建立的表B与原来的节点顺序正好相反
malloc一个B头节点,将B的next指向NULL
用一个工作指针cur来指向A表的第一个节点,准备遍历A表
用一个tail指针指向A头节点,用来尾插找尾
cur往后遍历A表,直到cur指向空时结束
将tail的next也就是A的next指向cur,这里不动
tail指针后移,指向A表的最后一个节点
cur指向cur的next,后移一位
这时候cur走向偶数位置,判断cur是否指向空
用next保存cur的下一个节点
cur的next指向B的next,将cur头插到B表
B的next指向cur
cur指向next
再进行A表的尾插
再进行B表的头插
将tail的next指向NULL
LinkList DisCreat(LinkList &A)
{LinkList B = (LinkList)malloc(sizeof(LNode)); //创建B表表头B->next = NULL; //B表初始化LNode* cur = A->next, *next; //cur为工作指针LNode* tail = A; //tail始终指向A的尾节点while (cur){tail->next = cur; //将*cur链到A的表尾tail = cur;cur = cur->next;if (cur){next = cur->next; //头插后,*cur将断链,用next记忆*cur的后继cur->next = B->next; //将*cur插入到B表的前端B->next = cur;cur = next;}}tail->next = NULL; //A尾节点的next指向NULLreturn B;
}
判断链表是否带环
单链表有环,是指单链表的最后一个节点的指针指向了链表中的某个节点,判断单链表是否存在环
算法思想
设置快慢指针分别为fast和slow最初都指向链表头head
slow每次走一步,fast每次走两步
fast走得比slow快,若有环,则fast一定先进入环
两个指针进入环后,一定会在环上相遇
链表分割|链表的回文结构|相交链表|环形链表|随机链表的复制©-CSDN博客
这里有详细说明过程,环形链表1和2
LNode* FindLoopStart(LNode* head)
{LNode* fast = head, *slow = head; //设置两个快慢指针while (fast && fast->next){slow = slow->next; //每次走一步fast = fast->next->next; //每次走两步if (slow == fast) //相遇break;}if (fast == NULL || fast->next == NULL)return NULL; //没有环,返回空LNode* p1 = head, *p2 = slow; //分别指向开始点,相遇点while (p1 != p2){p1 = p1->next;p2 = p2->next;}return p1; //返回入口点
}
一个指针从头节点开始走,一个节点从相遇点开始走,当两个指针相遇的时候,就是入口点
返回倒数第k个节点
输入一个链表,输出该链表的倒数第k个节点
算法思想
快慢指针思想
将fast指针指向链表的第k+1个节点,slow指向链表的第一个节点,此时fast和slow之间刚好相差k个节点,两个指针同步向后走,当fast走到链表的尾部空节点时,slow指针正好指向链表的倒数第k个节点
fast先走k步,之后同步走
直到fast指向空
LNode* getKthFromEnd(LinkList &head, int k)
{if (head == NULL)return NULL;LNode* fast = head, *slow = head;int i = 0;while (fast){if (i >= k){slow = slow->next;}fast = fast->next;i++;}return slow;
}