您的位置:首页 > 其它

链表的高级应用

2018-04-03 19:32 225 查看
这次的我们需要完成以下操作

单链表逆置

(我用的是每次将原链表的头结点头插到另一个空链表中,这样得到的新链表就是逆置完成的链表)

单链表的冒泡排序

(采用的是调用交换函数来进行冒泡)

将两个有序链表, 合并成一个有序链表

(新建一个空链表,比较俩个链表,每次小的节点插在新链表之后,最后判断哪个链表先为空,就将另一个链表后面的所有节点都接在新链表的尾端)

找到倒数第 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;
LinkNode *fast = cur->next;
while(fast != back)
{
if(cur->data > fast->data)
{
sweep(cur,fast);
}
cur = cur->next;
fast = fast->next;
}
back = cur;
}
}

LinkNode *LinkNodeMerge(LinkNode *head1,LinkNode *head2)
{
if(head1 == NULL)
{
return head2;
}
if(head2 == NULL)
{
return head1;
}
LinkNode *cur = head1;
LinkNode *back = head2;
LinkNode *head = NULL;
LinkNode *file = NULL;
while(cur != NULL && back != NULL)
{
if(cur->data < back->data)
{
if(head == NULL)
{
head = cur;
cur = cur->next;
file = head;
}
else
{
file->next = cur;
cur = cur->next;
file = file->next;
}
}
else
{
if(head == NULL)
{
head = back;
back = back->next;
file = head;
}
else
{
file->next = back;
back = back->next;
file = file->next;
}
}
}
if(cur == NULL)
{
file = back;
}
else
{
file = cur;
}
return head;
}

LinkNode *FindLastKNode(LinkNode *head,size_t K)
{
if(head == NULL)
{
return NULL;
}
size_t i = LinkNodeSize(head);
if(i < K)
{
return NULL;
}
LinkNode *fast = head;
LinkNode *slow = head;
for(;K>0;--K)
{
fast = fast->next;
}
while(fast != NULL)
{
fast = fast->next;
slow = slow->next;
}
return slow;
}

void EraseListKNode(LinkNode **head,size_t K)
{
if(head == NULL)
{
return;
}
if(*head == NULL)
{
printf("LinkNode is null.\n");
return;
}
size_t i = LinkNodeSize(*head);
if(i < K)
{
return;
}
LinkNode *fast = *head;
LinkNode *slow = *head;
for(;K>0;--K)
{
fast = fast->next;
}
while(fast->next != NULL)
{
fast = fast->next;
slow = slow->next;
}
LinkNode *to_delete = slow->next;
slow->next = to_delete->next;
DeleteNode(to_delete);
return;
}

int HasCycle(LinkNode *head)
{
if(head == NULL)
{
return 0;
}
LinkNode *fast = head;
LinkNode *slow = head;
while(fast->next != NULL && fast != NULL)
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
{
break;
}
}
if(fast->next == NULL && fast == NULL)
{
return 0;
}
else
{
return 1;
}
}

size_t GetCycleLen(LinkNode *head)
{
size_t i = 0;
if(head == NULL)
{
return i;
}
LinkNode *fast = head;
LinkNode *slow = head;
while(fast->next != NULL && fast != NULL)
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
{
break;
}
}
if(fast->next == NULL && fast == NULL)
{
return i;
}
else
{
while(fast != slow->next)
{
slow = slow->next;
++i;
}
return i+1;
}
}

LinkNode *GetCycleEntry(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(fast == slow)
{
break;
}
}
if(fast->next == NULL && fast == NULL)
{
return NULL;
}
else
{
slow = head;
while(slow != fast)
{
slow = slow->next;
fast = fast->next;
}
return slow;
}
}

LinkNode *HasCross(LinkNode *head1,LinkNode *head2)
{
if(head1 == NULL || head2 == NULL)
{
return NULL;
}
LinkNodePushBack(&head1,'c');
LinkNodePushBack(&head1,'e');
LinkNode *cur = head1;
LinkNode *cur1 = head2;
while(cur->next  != NULL)
{
cur = cur->next;
}
while(cur1->next != NULL)
{
cur1 = cur1->next;
}
if(cur != cur1)
{
return NULL;
}
else
{
size_t i = LinkNodeSize(head1);
size_t j = LinkNodeSize(head2);
size_t K = 0;
if(i < j)
{
K = j-i;
cur = head1;
cur1 = head2;
for(;K>0;--K)
{
cur1 = cur1->next;
}
while(cur != cur1)
{
cur = cur->next;
cur1 = cur1->next;
}
return cur;
}
else
{
K = i-j;
cur = head1;
cur1 = head2;
for(;K>0;--K)
{
cur = cur->next;
}
while(cur != cur1)
{
cur = cur->next;
cur1 = cur1->next;
}
return cur;
}
}
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------

#define LINE printf("------------------------------------------\n");

void LinkNodePrint(LinkNode *head,const char* msg)
{
LINE;
printf("%s",msg);
printf("\n");
if(head == NULL)
{
printf("LinkNode is null.\n");
return;
}
LinkNode* cur = NULL;
cur = head;
while(cur != NULL)
{
printf("[%c|%p]->",cur->data,&(cur->data));
cur = cur->next;
}
printf("NULL\n");
return;
}

void testLinkNodeReverse()
{
LinkNode *head = NULL;
LinkNodeInit(&head);

LinkNodePushBack(&head,'a');
LinkNodePushBack(&head,'b');
LinkNodePushBack(&head,'c');
LinkNodePushBack(&head,'d');
LinkNodePushBack(&head,'e');
LinkNodePushBack(&head,'f');
LinkNodePushBack(&head,'g');

LinkNodeReverse(&head);
LinkNodePrint(head,"LinkNodeReverse");
}

void testLinkNodeBubbleSort()
{
LinkNode *head = NULL;
LinkNodeInit(&head);

LinkNodePushBack(&head,'z');
LinkNodePushBack(&head,'r');
LinkNodePushBack(&head,'x');
LinkNodePushBack(&head,'a');
LinkNodePushBack(&head,'c');
LinkNodePushBack(&head,'b');
LinkNodePushBack(&head,'e');

LinkNodeBubbleSort(head);
LinkNodePrint(head,"LinkNodeBubbleSort");
}

void testLinkNodeMerge()
{
LinkNode *head1 = NULL;
LinkNode *head2 = NULL;
LinkNodeInit(&head1);
LinkNodeInit(&head2);

LinkNodePushBack(&head1,'a');
LinkNodePushBack(&head1,'c');
LinkNodePushBack(&head1,'e');
LinkNodePushBack(&head1,'g');
LinkNodePushBack(&head2,'b');
LinkNodePushBack(&head2,'d');
LinkNodePushBack(&head2,'f');
LinkNodePushBack(&head2,'h');

LinkNode *head = LinkNodeMerge(head1,head2);
LinkNodePrint(head,"LinkNodeMerge");
}

void testFindListKNode()
{
LinkNode *head = NULL;
LinkNodeInit(&head);

LinkNodePushBack(&head,'a');
LinkNodePushBack(&head,'b');
LinkNodePushBack(&head,'c');
LinkNodePushBack(&head,'d');
LinkNodePushBack(&head,'e');
LinkNodePushBack(&head,'f');
LinkNodePushBack(&head,'g');

LinkNode * head1 = FindLastKNode(head,3);
LINE;
printf("FindLastKNode\n");
printf("[%c|%p]\n",head1->data,&(head1->data));
}

void testEraseListNode()
{
LinkNode *head = NULL;
LinkNodeInit(&head);

LinkNodePushBack(&head,'a');
LinkNodePushBack(&head,'b');
LinkNodePushBack(&head,'c');
LinkNodePushBack(&head,'d');
LinkNodePushBack(&head,'e');
LinkNodePushBack(&head,'f');
LinkNodePushBack(&head,'g');

EraseListKNode(&head,3);
LinkNodePrint(head,"EraseListKNode");
}

void testHasCycle()
{
LinkNode *head = NULL;
LinkNodeInit(&head);

LinkNodePushBack(&head,'a');
LinkNodePushBack(&head,'b');
LinkNodePushBack(&head,'c');
LinkNode *cur1 = LinkNodePushBack(&head,'d');
LinkNodePushBack(&head,'e');
LinkNodePushBack(&head,'f');
LinkNode *cur = LinkNodePushBack(&head,'g');
cur->next = cur1;

LINE;
printf("HasCycle\n");
printf("%d\n",HasCycle(head));
}

void testGetCycleLen()
{
LinkNode *head = NULL;
LinkNodeInit(&head);

LinkNodePushBack(&head,'a');
LinkNodePushBack(&head,'b');
LinkNodePushBack(&head,'c');
LinkNode *cur1 = LinkNodePushBack(&head,'d');
LinkNodePushBack(&head,'e');
LinkNodePushBack(&head,'f');
LinkNode *cur = LinkNodePushBack(&head,'g');
cur->next = cur1;

LINE;
printf("GetCycleLen\n");
printf("%d\n",GetCycleLen(head));
}

void testGetCycleEntry()
{
LinkNode *head = NULL;
LinkNodeInit(&head);

LinkNodePushBack(&head,'a');
LinkNodePushBack(&head,'b');
LinkNodePushBack(&head,'c');
LinkNode *cur1 = LinkNodePushBack(&head,'d');
LinkNodePushBack(&head,'e');
LinkNodePushBack(&head,'f');
LinkNode *cur = LinkNodePushBack(&head,'g');
cur->next = cur1;

LinkNode *head1 = GetCycleEntry(head);
LINE;
printf("GetCycleLen\n");
printf("[%c|%p]\n",head1->data,&(head1->data));
}

void testHasCross()
{
LinkNode *head1 = NULL;
LinkNode *head2 = NULL;
LinkNodeInit(&head1);
LinkNodeInit(&head2);

LinkNodePushBack(&head1,'a');
LinkNodePushBack(&head1,'b');
LinkNodePushBack(&head1,'c');
LinkNode *cur = LinkNodePushBack(&head1,'d');
LinkNodePushBack(&head1,'e');
LinkNodePushBack(&head1,'f');
LinkNodePushBack(&head2,'g');
LinkNodePushBack(&head2,'h');
LinkNodePushBack(&head2,'i');
LinkNodePushBack(&head2,'c');
LinkNodePushBack(&head2,'e');
LinkNode *cur1 = LinkNodePushBack(&head2,'j');

cur1->next = cur;
LINE;
LinkNode *file = HasCross(head1,head2);
printf("HasCross\n");
printf("[%c|%p]\n",file->data,&(file->data));
}

int main()
{
testLinkNodeReverse();
testLinkNodeBubbleSort();
testLinkNodeMerge();
testFindListKNode();
testEraseListNode();
testHasCycle();
testGetCycleLen();
testGetCycleEntry();
testHasCross();
return 0;
}


接下来是运行结果图

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  链表 单链表