1.合并两个有序链表,合并以后的链表依旧有序。
#pragma once
typedef struct ListNode
{
int _data;
ListNode* _next;
}Node;
void Display(Node* head) //非递归打印
{
while (head)
{
cout << head->_data << " ";
head = head->_next;
}
cout << endl;
}
Node* MeageList(Node* l1, Node* l2) //合并链表
{
Node* NewNode = new Node;
Node* cur1;
Node* cur2;
if (NULL == l1)
{
return l2;
}
if (NULL == l2)
{
return l1;
}
if (l1->_data < l2->_data) //吧头数据小的一个作为新链表的头
{
NewNode->_data = l1->_data;
cur1 = l1->_next;
cur2 = l2;
}
else
{
NewNode->_data = l2->_data;
cur2 = l2->_next;
cur1 = l1;
}
Node* NewList = NewNode;
while (cur1 && cur2) //把剩余链表连接在后面
{
if (cur1->_data > cur2->_data)
{
NewNode->_next = cur2;
NewNode = NewNode->_next;
cur2 = cur2->_next;
}
else
{
NewNode->_next = cur1;
NewNode = NewNode->_next;
cur1 = cur1->_next;
}
}
if (cur1 == NULL)
{
NewNode->_next = cur2;
}
else
NewNode->_next = cur1;
return NewList;
}
Node* MeageListRe(Node* l1, Node* l2) // 递归合并
{
if (NULL == l1)
{
return l2;
}
if (NULL == l2)
{
return l1;
}
if (l1->_data < l2->_data)
{
l1->_next = MeageListRe(l1->_next, l2);
return l1;
}
else
{
l2->_next = MeageListRe(l2->_next, l1);
return l2;
}
}
2. 逆置/反转单链表,查找单链表的倒数第k个节点,要求只能遍历一次链表 。
typedef struct ListNode //链表节点
{
int _data;
ListNode* _next;
}Node;
Node* ReverceList(Node* list) //逆制单链表 (取下一个节点,头插)
{
if (NULL == list)
{
return NULL;
}
Node* Head = list->_next;
Node* NewHead = list; //原链表的头节点,变成新链表的尾节点。
Node* cur = list->_next;
NewHead->_next = NULL;
while (cur)
{
Head = cur;
cur = cur->_next;
Head->_next = NewHead; //找到下一个节点,插在前面
NewHead = Head;
}
return Head;
}
Node* ReFind(Node* list, int k) //查找倒数第K个节点, (两指针 相差K-1步)
{
if (NULL == list)
{
return NULL;
}
Node* ptr1 = list;
Node* ptr2 = list;
while (k--)
{
ptr1 = ptr1->_next; //ptr1先走 k-1 步
}
while (ptr1&&ptr2)
{
ptr1 = ptr1->_next;
ptr2 = ptr2->_next;
}
return ptr2;
}
3. 判断链表是否带环?若带环求环的长度?若带环求环的入口点?
typedef struct ListNode //链表节点
{
int _data;
ListNode* _next;
}Node;
Node* Find(Node* list, int key) //查找某个节点
{
if (NULL == list)
return NULL;
Node* node = list;
while (node)
{
if (node->_data == key)
{
return node;
}
node = node->_next;
}
return NULL;
}
Node* MakeRing(Node* list) // 构建带环链表
{
Node* ret = Find(list, 9);
Node* newnode = list;
Node* newhead = list;
while (newnode->_next)
{
newnode = newnode->_next;
}
newnode->_next = ret;
return newhead;
}
bool JudgeRing(Node* list) //判断链表是否带环
{
if (NULL == list)
return false;
Node* fast = list;
Node* slow = list;
while (fast && fast->_next)
{
fast = fast->_next->_next;
slow = slow->_next;
if (slow == fast)
return true;
}
return false;
}
Node* FindRingnode(Node* list) //找链表环的入口点
{
if (NULL == list)
return NULL;
Node* fast = list;
Node* slow = list;
while (fast && fast->_next)
{
fast = fast->_next->_next;
slow = slow->_next;
if (slow == fast)
break;
}
if (fast && fast->_next)
{
slow = list;
}
else
return NULL;
// 若带环 ,slow从头开始走,fast从相遇点开始走,第一次相遇即为交点
while (slow != fast)
{
slow = slow->_next;
fast = fast->_next;
}
return slow;
}
int RingLong(Node* list) //求环的长度
{
Node* node = FindRingnode(list); //找到还的入口点
int count = 0;
Node* node1 = node;
while (node)
{
node = node->_next;
count++;
if (node == node1) //当在环内走一圈,走的距离就是环长
break;
}
return count;
}
typedef struct ListNode
{
int _data;
ListNode* _next;
}Node;
Node* Find(Node* list, int key) //查找结点
{
assert(list);
Node* node = list;
while (node)
{
if (node->_data == key)
{
return node;
}
node = node->_next;
}
return NULL;
}
Node* MakeRing(Node* list) //建造带环链表
{
assert(list);
Node* node = list;
while (node->_next)
{
node = node->_next;
}
node->_next = Find(list, 1);
return list;
}
void MakeCrossList(Node* list1, Node* list2) //建造相交链表
{
assert(list1);
assert(list2);
Node* node2 = list2;
while (node2->_next)
{
node2 = node2->_next;
}
node2->_next = Find(list1, 3);
}
bool JudgeRing(Node* list) //判断链表是否带环
{
if (NULL == list)
return false;
Node* fast = list;
Node* slow = list;
while (fast && fast->_next) //快慢指针是否相遇
{
fast = fast->_next->_next;
slow = slow->_next;
if (slow == fast)
return true;
}
return false;
}
Node* FindRingnode(Node* list) //找带环链表的入口点
{
if (NULL == list)
return NULL;
Node* fast = list;
Node* slow = list;
while (fast && fast->_next)
{
fast = fast->_next->_next;
slow = slow->_next;
if (slow == fast)
break;
}
if (fast && fast->_next)
{
slow = list;
}
else
return NULL;
// 若带环 ,slow从头开始走,fast从相遇点开始走,第一次相遇即为交点
while (slow != fast)
{
slow = slow->_next;
fast = fast->_next;
}
return slow;
}
int RingLong(Node* list) //求环的长度
{
Node* node = FindRingnode(list);
int count = 0;
Node* node1 = node;
while (node)
{
node = node->_next;
count++;
if (node == node1)
break;
}
return count;
}
Node* JudgeCross1(Node* list1, Node* list2) //不带环相交的判断
{
assert(list1);
assert(list2);
Node* head1 = list1;
Node* head2 = list2;
while (head2->_next)
{
head2 = head2->_next;
}
head2->_next = head1; //让 list1 的头链上 list2 的结尾
//判断新链表是否带环
//若新链表带环,则环的入口点就是第一个相交的点
return FindRingnode(list2);
}
int GetListlength(Node* list) //求链表长度
{
assert(list);
Node* head = list;
int len = 0;
while (head)
{
if (JudgeRing(list)) //带环链表的长
{
Node* node = FindRingnode(list);
while (node != head)
{
head = head->_next;
len++;
}
len = len + RingLong(list); //链表长 = 头结点到环入口的长度 + 环的长度
break;
}
else //不带环链表的长
{
len++;
head = head->_next;
}
}
return len;
}
Node* JudgeCross2(Node* list1, Node* list2) //链表带环相交
{
//1.环外相交
//2.环内相交
assert(list1);
assert(list2);
int long1 = GetListlength(list1);
int long2 = GetListlength(list2);
int step = 0;
Node* head1 = list1;
Node* head2 = list2;
if (long1 > long2) //长的链表先走,让链表等长
{
step = long1 - long2;
while (step--)
head1 = head1->_next;
}
else
{
step = long2 - long1;
while (step--)
head2 = head2->_next;
}
if (JudgeRing(list1) && JudgeRing(list2)) //若相交,两条链表必然都带环
{
while (FindRingnode(list1) != head2)
{
head2 = head2->_next;
}
if (head2 == FindRingnode(list1)) //若相交,list1 环上的点(入口点),必在 list2 上
{
while (head1 != FindRingnode(list1)) //1.环外相交
{
head1 = head1->_next;
head2 = head2->_next;
if (head1 == head2)
return head1;
}
if (head1 == FindRingnode(list1)) //2.环上相交(环有两个入口点),环的任意一个入口点就是交点
return FindRingnode(list1);
}
else
return NULL;
}
return NULL;
}