链表的高级应用
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
linknode.c
接下来是运行结果图
单链表逆置
(我用的是每次将原链表的头结点头插到另一个空链表中,这样得到的新链表就是逆置完成的链表)
单链表的冒泡排序
(采用的是调用交换函数来进行冒泡)
将两个有序链表, 合并成一个有序链表
(新建一个空链表,比较俩个链表,每次小的节点插在新链表之后,最后判断哪个链表先为空,就将另一个链表后面的所有节点都接在新链表的尾端)
找到倒数第 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; }
接下来是运行结果图
相关文章推荐
- 【原创】《Linux高级程序设计》杨宗德著 - TCP高级应用 - 多路复用 分类: Linux --- 应用程序设计 2014-12-05 17:57 77人阅读 评论(0) 收藏
- Android中checkBox的高级应用---button属性
- java高级工程师-------------Velocity的应用
- VC调试器高级应用----WATCH窗口篇
- 第四周实践项目3--单链表应用(2)
- 动态内存分配应用举例(链表)
- Android开发之高级通知应用
- python中threading的高级函数应用解析 Lock Rlock Condition Semaphore Timer Event Semaphore对象
- opencv轮廓高级应用(轮廓匹配,几何直方图)
- odoo高级物流应用:跨厂区生产
- JavaScript高级之闭包的概念及其应用
- ADB 高级应用
- 线程高级应用-心得2-同步锁讲解及面试题案例分析
- webstrop快捷键高级应用
- 第四周 项目3 - 单链表应用
- JDK6笔记(6)----JDBC4.0高级应用(2)
- JavaFX表格控件TableView高级应用:自动添加ID列、删除操作列、单元格内容个性化渲染
- Oracle PL/SQL 高级应用(游标、存储过程、函数、程序包)
- Android高级开发第一讲--如何在Android应用中避免内存溢出OOM问题
- 第4周项目3单链表应用2