这次的我们需要完成以下操作
- 单链表逆置
(我用的是每次将原链表的头结点头插到另一个空链表中,这样得到的新链表就是逆置完成的链表) - 单链表的冒泡排序
(采用的是调用交换函数来进行冒泡) - 将两个有序链表, 合并成一个有序链表
(新建一个空链表,比较俩个链表,每次小的节点插在新链表之后,最后判断哪个链表先为空,就将另一个链表后面的所有节点都接在新链表的尾端) - 找到倒数第 K 个节点
(先利用之前的求链表长度函数得到链表的总长度,然后判断K值是否合理,再然后创建一快(一次2步)一慢(一次1步)指针,然后让快指针先走K步之后再俩指针开始走,当快指针走到尾节点时,慢指针正好走到K点了) - 删除倒数第K个节点
(和找到倒数第K个节点类似) - 判定单链表是否带环. 如果带环返回1
(1.先遍历链表,将所有节点的地址都保存在一个新建的顺序表中,然后每走一部查找一次顺序表看是否地址有重复,有则是有环,无则没环(该方法时间复杂度O(n^2),空间复杂度O(n))2.定义一快一慢指针,然后比较看俩指针有没有可能相等,有则有环,无则无环(该方法时间复杂度O(n),空间复杂度O(1))) - 如果链表带环, 求出环的长度
(先找出俩快慢指针相遇的点,然后快指针不动,慢指针走到再次相遇就是环的长度,定义一个计数器) - 如果链表带环, 求出环的入口
(先用快慢指针找到相遇点,然后在从头定义一个指针开始遍历一次,同时慢指针也开始从相遇点开始走,直到慢指针和新定义的指针相遇的节点就是环的入口) - 判定两个链表是否相交, 并求出交点
(分别遍历俩链表一遍,看最后一个节点是否相等,如果相等那么就是相交的否则就不相交。相交情况下再求俩链表的长度,差值为K,再将俩遍历指针移到头节点处,长链表的指针先走K步之后然后俩指针再同时开始走,相遇的节点就是交点)
接下来就是我们的代码了
linknode.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef char LinkType;
typedef struct LinkNode{
LinkType data;
struct LinkNode *next;
}LinkNode;
LinkNode* CreateNode(LinkType valaue);
void DeleteNode(LinkNode *head);
void LinkNodePrint(LinkNode *head,const char* msg);
void LinkNodeInit(LinkNode **head);
void LinkNodePushTop(LinkNode **head,LinkType value);
void LinkNodeReverse(LinkNode **head);
void LinkNodeBubbleSort(LinkNode *head);
LinkNode *LinkNodeMerge(LinkNode *head1,LinkNode *head2);
LinkNode *FindLastKNode(LinkNode *head,size_t K);
void EraseListKNode(LinkNode **head,size_t K);
int HasCycle(LinkNode *head);
size_t GetCycleLen(LinkNode *head);
LinkNode *HasCross(LinkNode *head1,LinkNode *head2);
linknode.c
#include "linknode.h"
void LinkNodeInit(LinkNode **head)
{
if(head ==NULL)
{
return;
}
*head = NULL;
}
LinkNode* CreateNode(LinkType value)
{
LinkNode *new_node = (LinkNode *)malloc(sizeof(LinkNode));
if(new_node == NULL)
{
perror("malloc");
return NULL;
}
new_node->next = NULL;
new_node->data = value;
return new_node;
}
void DeleteNode(LinkNode *head)
{
free(head);
head = NULL;
return;
}
void LinkNodePushTop(LinkNode **head,LinkType value)
{
if(head == NULL)
{
return;
}
LinkNode *cur = CreateNode(value);
cur->next = *head;
*head = cur;
}
void LinkNodeReverse(LinkNode **head)
{
if(head == NULL)
{
return;
}
if(*head == NULL)
{
return;
}
LinkNode *cur = (*head)->next;
LinkNode *to_delete = *head;
to_delete->next = NULL;
while(cur != NULL)
{
LinkNodePushTop(&to_delete,cur->data);
cur = cur->next;
}
*head = to_delete;
return;
}
void sweep(LinkNode *cur,LinkNode *fast)
{
cur->data = cur->data ^ fast->data;
fast->data = cur->data ^ fast->data;
cur->data = cur->data ^ fast->data;
}
void LinkNodeBubbleSort(LinkNode *head)
{
if(head == NULL)
{
return;
}
LinkNode *back = NULL;
while(back != head->next)
{
LinkNode *cur = head;
LinkN