简单的链表操作已经无法满足我的电脑对于编程的渴望,它的键盘已经饥渴难耐。风扇轰轰作响的咆哮让我仿佛置身舒马赫的车里。
为了安抚我的电脑,我又写了一些较为复杂的链表操作来给它运行。同样是采用c语言编写。代码如下:
#include <stdio.h>
#include <stdlib.h>
typedef char LinkType;
typedef struct LinkNode {
LinkType data;
struct LinkNode* next;
} LinkNode;
LinkNode* creat(LinkNode* head,LinkType data){
LinkNode* l = (LinkNode*)malloc(sizeof(LinkNode));
l->next = NULL;
head->next = l;
head = l;
l->data = data;
return l;
}
/**
* @brief 逆序打印单链表.
*
* @param head
*/
void LinkListReversePrint(LinkNode* head){
if (head == NULL)//非法输入
return;
else{
printf("%d",head->data);
LinkListReversePrint(head->next);
}
}
/**
* @brief 不允许遍历链表, 在 pos之前插入
*
* @param head
* @param pos
* @param value
*/
void LinkListInsertBefore(LinkNode** head, LinkNode* pos, LinkType value){
if (head == NULL)
return;
//在pos之前插入value值
//可以转化为在pos之后插入value
LinkNode* node = (LinkNode*)malloc((sizeof(LinkNode)));
node->next = pos->next;
pos->next = node;
node->data = pos->data;
pos->data = value;
return;
}
/**
* @brief JosephCycle问题
*
* @param head
* @param food
*/
LinkNode* JosephCycle(LinkNode* head, size_t food){
//判断环是否为空;
//head->data是每个人的号码
if (head == NULL)
return NULL;
LinkNode* tmp = head;
LinkNode* add =tmp;
int count = 1;
while(tmp->next != head){
++count;
tmp = tmp->next;
}
tmp = head;
while(tmp){
for (int i = 1; i < food; ++i) {
if (tmp->data == '0'){
for (int j = 0; j < count; ++j) {
tmp = tmp->next;
if (tmp->data != '0')
break;
}
if (tmp->data == '0'){
return add;
}
}
tmp = tmp->next;
}
add = tmp;
tmp->data = '0';
}
}
/**
* @brief 单链表逆置
*
* @param head
*/
void LinkListReverse(LinkNode* head){
if (head == NULL)
return;
LinkNode*tmp = NULL;
LinkNode* p = head->next;
LinkNode* new = head;
while(p){
//头插元素
tmp = p->next;
p->next = new->next;
new->next = p;
p = tmp;
}
}
LinkNode* LinkListReverse2(LinkNode* head){
if (head->next == NULL)
return head;
LinkNode *Preturn = LinkListReverse2(head->next);
head->next->next = head;
head->next = NULL;
return Preturn;
}
/**
* @brief 单链表的冒泡排序
*
* @param head
*/
void LinkListBubbleSort(LinkNode* head,int n){
if (head == NULL)
return;
LinkNode* t = head->next;
for (int i = 0; i < n -1; ++i) {
LinkNode* l = t;
for (int j = 0; j < n-i; ++j) {
if (l->data > l->next->data){
LinkType tmp = l->data;
l->data = l->next->data;
l->next->data = tmp;
}
l = l->next;
}
t = t->next;
}
}
/**
* @brief 将两个有序链表, 合并成一个有序链表
*
* @param head1
* @param head2
*
* @return
*/
LinkNode* LinkListMerge(LinkNode* head1, LinkNode* head2){
if (head1 == NULL)
return head2;
if (head2 == NULL)
return head1;
//创建一个新的头节点指针。
LinkNode* new_head = (LinkNode*)malloc(sizeof(LinkNode));
LinkNode* p1 = head1;
LinkNode* p2 = head2;
LinkNode* HH = new_head;
while ((p1 != NULL) && (p2 != NULL)){
if (p1->data > p2->data){
new_head->next = p2;
p2 = p2->next;
new_head = new_head->next;
}else if (p1->data < p2->data){
new_head->next = p1;
p1 = p1->next;
new_head = new_head->next;
} else{
new_head->next = p2;
p2 = p2->next;
new_head = new_head->next;
new_head->next = p1;
p1 = p1->next;
new_head = new_head->next;
}
}
if (p1 != NULL){
new_head->next = p1;
}
if (p2 != NULL){
new_head->next = p2;
}
free(head1);
free(head2);
return HH;
}
LinkNode* FindMidNode(LinkNode* head){
if (head == NULL)
return NULL;
LinkNode* fast = head;
LinkNode* slow = head;
while((fast != NULL) && (fast->next != NULL)){
fast == fast->next->next;
slow == slow->next;
}
return slow;
}
/**
* @brief 找到倒数第 K 个节点.
*
* @param head
*
* @return
*/
LinkNode* FindLastKNode(LinkNode* head, size_t K){
if (head == NULL)
return NULL;
LinkNode* fast = head;
LinkNode* slow = head;
for (int i = 1; i < K; ++i) {
if (fast == NULL)
return NULL;
fast = fast->next;
}
while(fast != NULL){
fast = fast->next;
slow = slow->next;
}
return slow;
}
/**
* @brief 删除倒数第K个节点
*
* @param head
* @param K
*/
void EraseLastKNode(LinkNode** head, size_t K){
if (head == NULL)
return ;
LinkNode* fast = head;
LinkNode* slow = head;
for (int i = 0; i < K; ++i) {
if (fast == NULL)
return ;
fast = fast->next;
}
while(fast->next != NULL){
fast = fast->next;
slow = slow->next;
}
LinkNode* to_delete = slow->next;
slow->next = slow->next->next;
free(to_delete);
return;
}
/**
* @brief 判定单链表是否带环. 如果带环返回1
*
* @param head
*
* @return
*/
LinkNode* HasCycle(LinkNode* head){
if (head == NULL)
return NULL;
LinkNode* fast = head;
LinkNode* slow = head;
while((fast->next != NULL) && (fast != NULL)){
fast = fast->next->next;
slow = slow->next;
if (slow == fast)
return slow;
}
return NULL;
}
/**
* @brief 如果链表带环, 求出环的长度
*
* @param head
*
* @return
*/
size_t GetCycleLen(LinkNode* head){
LinkNode* L = HasCycle(head);
if (L == NULL)
return 0;
LinkNode* p = L->next;
size_t count = 1;
while(p != L){
++count;
p = p->next;
}
return count;
}
/**
* @brief 如果链表带环, 求出环的入口
*
* @param head
*
* @return
*/
LinkNode* GetCycleEntry(LinkNode* head){
LinkNode* L = HasCycle(head);
if (L == NULL)
return 0;
LinkNode* star = head;
LinkNode* entr = L;
while(star != entr){
star = star->next;
entr = entr->next;
}
return star;
}
/**
* @brief 判定两个链表是否相交, 并求出交点
*
* @param head1
* @param head2
*
* @return
*/
LinkNode* HasCross(LinkNode* head1, LinkNode* head2){//本次仅讨论两个链表非环的情况
if (head1 == NULL)
return head2;
if (head2 == NULL)
return head1;
//两个非环链表的相交仅有y的样子一种情况
LinkNode* p = head1;
while (p->next != NULL){
p = p->next;
}
LinkNode* tmp = p;
p->next = head2;
LinkNode* intersection = GetCycleEntry(head1);
tmp->next = NULL;
return intersection;
}
/**
* @brief 判定两个链表是否相交. 但是链表可能带环
*
* @param head1
* @param head2
*
* @return 如果相交, 返回1, 否则返回0
*/
int HasCrossWithCycle(LinkNode* head1, LinkNode* head2){
LinkNode* star1 = GetCycleEntry(head1);
LinkNode* star2 = GetCycleEntry(head2);
if ((star1 != NULL)&&(star2 != NULL)){//如果两个都带环
if (star1 == star2)//两环入口相等时
return 1;
LinkNode* p = star1->next;//两环入口不等时
while (p != star1){
if (p == star2)
return 1;
}
return 0;
} else{//只有一个带环不可能相交
return 0;
}
}
/**
* @brief 求两个有序链表的交集
*
* @param head1
* @param head2
*
* @return 返回表示交集的新链表
*/
LinkNode* UnionSet(LinkNode* head1, LinkNode* head2){
if (head1 == NULL)
return head2;
if (head2 == NULL)
return head1;
//创建一个新的头节点指针。
LinkNode* new_head = (LinkNode*)malloc(sizeof(LinkNode));
LinkNode* p1 = head1;
LinkNode* p2 = head2;
LinkNode* HH = new_head;
while ((p1 != NULL) && (p2 != NULL)){
if (p1->data > p2->data){
p2 = p2->next;
}else if (p1->data < p2->data){
p1 = p1->next;
} else{
new_head->next = p2;
p2 = p2->next;
new_head = new_head->next;
p1 = p1->next;
}
}
return HH;
}
typedef struct ComplexNode {
LinkType data;
struct ComplexNode* next;
struct ComplexNode* random;
} ComplexNode;
/**
* @brief 拷贝复杂链表
*
* @param head
*
* @return
*/
ComplexNode* CopyComplex(ComplexNode* head){
//创建一个链表的每个节点的复制
if (head == NULL)
return NULL;
ComplexNode* p = head;
while(p != NULL){//完成复制
ComplexNode* L = (ComplexNode*)malloc(sizeof(ComplexNode));
L->next = p->next;
L->data = p->data;
p->random = NULL;
ComplexNode* tmp = p->next;
p->next = L;
p = tmp;
}
p = head;
while(p->next != NULL){//完成赋值
p->next->random = p->random->next;
p = p->next->next;
}
ComplexNode* new_head = (ComplexNode*)malloc(sizeof(ComplexNode));
ComplexNode* fast = new_head;
p = head;
while(p->next == NULL){
fast->next = p->next->next;
fast = fast->next;
p = p->next->next;
}
return new_head;
}