实现单链表的一些操作
2018-03-29 10:35
381 查看
头文件(linklist.h)
实现函数(linklist.c)
测试函数(test.c)
#pragma once #include <stdio.h> #include <windows.h> #include <stddef.h> #include <assert.h> typedef int listtype; typedef struct linklist { listtype data; struct linklist* next; }Linklist,*listpoint; void linklist_init(listpoint* headpoint);//初始化 void linklist_pushback(listpoint* pphead, listtype data);//尾插 listpoint new_listnode(listtype data);//开辟节点 void linklist_popback(listpoint* pphead);//尾删 void linklist_pushhead(listpoint* phead, listtype data);//头插 void destroy(listpoint head);//释放内存 void linklist_pophead(listpoint* head);//头删 void linklist_print(listpoint head);//打印链表 void linklist_insert(listpoint* head,size_t pos,const listtype data);//任意位置插入 void linklist_pop(listpoint* head, size_t pos);//任意位置删除 listpoint linklist_find(const listpoint head, const listtype to_find);//查找值的地址 void LinkListReversePrint(listpoint head);//逆序打印單鏈表 void LinkListInsertBefore(listpoint* head,listpoint pos,listtype value);//不允许遍历链表, 在 pos之前插入 listpoint Linklistfind(listpoint head, size_t place);//查找結點 void Linklistsort(listpoint pHead);//冒泡排序 listpoint LinkListReverse(listpoint* head);//鏈表逆置 listpoint LinkListMerge(listpoint* list1, listpoint* list2);//合并鏈表 int Linklisthascycle(listpoint head);//判斷是否有環 listpoint FindListKNode(listpoint head, size_t k);//找到倒數第K個節點 listpoint EraseLastKNode(listpoint head, size_t k);//刪除倒數第k個節點 size_t GetCycleLen(listpoint head);//如果鏈表帶環,求出它的長度 listpoint GetCycleEntry(listpoint head);//如果鏈表帶環,求出環的入口 listpoint HasCross(listpoint head1, listpoint head2);//判断链表是否相交并求交点 listpoint HasCross1(listpoint head1, listpoint head2);//判断链表是否相交并求交点(两个不带环的链表) listpoint HasCross2(listpoint head1, listpoint head2);//判断链表是否相交并求交点(两个带环的链表)
实现函数(linklist.c)
#include "linklist.h" void destroy(listpoint head) { free(head); } listpoint Linklistfind(listpoint head, size_t place)//查找結點 { assert(head); listpoint ret = head; while (--place) { ret = ret->next; } return ret; } listpoint new_listnode(listtype data)//建立新的节点 { listpoint newnode = (listpoint)malloc(sizeof(Linklist)); assert(newnode); newnode->data = data; newnode->next = NULL; return newnode; } void linklist_print(listpoint head)//打印 { for (; head != NULL; head = head->next) { printf("%d ", head->data); } } void linklist_init(listpoint* headpoint)//初始化链表 { *headpoint = NULL; } void linklist_pushback(listpoint* pphead, listtype data)//尾插 { assert(pphead); if (*pphead == NULL) { *pphead = new_listnode(data); } else { listpoint tail = *pphead; while (tail->next != NULL) { tail = tail->next; } tail->next = new_listnode(data); } } void linklist_popback(listpoint* pphead)//尾删 { assert(pphead); if (*pphead == NULL) { printf("尾删时链表为空\n"); system("pause"); exit(1); } if ((*pphead)->next == NULL) { destroy(*pphead); *pphead = NULL; } else { listpoint tmp = *pphead; while (tmp->next->next != NULL) { tmp = tmp ->next; } destroy(tmp->next); tmp->next = NULL; } } void linklist_pushhead(listpoint* phead, listtype data)//头插 { assert(phead); listpoint tmp = *phead; *phead = new_listnode(data); (*phead)->next = tmp; } void linklist_pophead(listpoint* head)//头删 { assert(head); if (*head == NULL) { printf("头删时链表为空\n"); system("pause"); exit(1); } listpoint tmp = (*head)->next; destroy(*head); *head = tmp; } void linklist_insert(listpoint* head,size_t pos,const listtype data)//任意位置插入 { size_t list_count = 0; size_t count = 0; listpoint tmp = *head; assert(head); while (tmp != NULL) { tmp = tmp->next; list_count++; } if (list_count == 0) { printf("任意位置插入时链表为空\n"); system("pause"); exit(1); } if (pos > list_count || pos == 0) { printf("任意位置插入时插入位置不合法\n"); system("pause"); exit(1); } if (pos == 1) { linklist_pushhead(head,data); } else { listpoint tmp1 = NULL; tmp = *head; for (; count < pos - 2; count++) { tmp = tmp->next; } tmp1 = tmp->next; tmp->next = new_listnode(data); tmp->next->next = tmp1; } } void linklist_pop(listpoint* head, size_t pos)//任意位置删除 { size_t count = 0; assert(head); if (*head == NULL) { printf("任意位置删除时链表为空,无法删除!"); exit(1); } listpoint tmp = *head; while (tmp != NULL) { count++; tmp = tmp->next; } if (pos > count || pos == 0) { printf("任意位置删除时,位置不合法\n"); exit(1); } if(pos == 1) { linklist_pophead(head); } else { tmp = *head; pos -= 2; while (pos--) { tmp = tmp->next; } listpoint tmp1 = tmp->next->next; destroy(tmp->next); tmp->next = tmp1; } } listpoint linklist_find(const listpoint head, const listtype to_find) { if (head == NULL) { return NULL; } listpoint tmp = head; while (tmp->next != NULL) { if (tmp->data == to_find) { return tmp; } tmp = tmp->next; } return NULL; } void LinkListReversePrint(listpoint head)//逆序打印單鏈表 { assert(head); listpoint cur = NULL; listpoint tail = NULL; while (tail != head) { cur = head; while (cur->next != tail) { cur = cur->next; } printf("%d ", cur->data); tail = cur; } } void LinkListInsertBefore(listpoint* head, listpoint pos, listtype value)//不允许遍历链表, 在 pos之前插入 { assert(head); if (*head == NULL) { return; } listtype temp; listpoint newnode = new_listnode(value); newnode->next = pos->next; pos->next = newnode; temp = newnode->data; newnode->data = pos->data; pos->data = temp; } void Linklistsort(listpoint pHead)//冒泡排序鏈表 { if (NULL == pHead) { return; } else { listpoint Tail = NULL; listpoint Flag = NULL; while (Flag != pHead) { Tail = Flag; Flag = pHead; listpoint Pre = pHead; while (Pre->next != Tail) { listpoint Cur = Pre->next; if (Pre->data > Cur->data) { listtype dTemp = Pre->data; Pre->data = Cur->data; Cur->data = dTemp; Flag = Pre->next; } Pre = Pre->next; } } } } listpoint LinkListReverse(listpoint* head)//鏈表逆置 { assert(head); if (*head == NULL) { return NULL; } listpoint ret = NULL; listpoint tail = NULL; listpoint cur = *head; while (tail != *head) { cur = *head; while (cur->next != tail) { cur = cur->next; } tail = cur; //linklist_pushhead(&ret, cur->data);//調用头插 linklist_pushback(&ret, cur->data); } return ret; } listpoint LinkListMerge(listpoint* list1, listpoint* list2)//合并鏈表 { assert(list1); assert(list2); if (*list1 == NULL) { return *list2; } if (*list2 == NULL) { return *list1; } listpoint cur1 = *list1; listpoint cur2 = *list2; listpoint new_head = NULL; listpoint tail = NULL; while (cur1 != NULL && cur2 != NULL) { if (cur1->data <= cur2->data) { linklist_pushback(&new_head, cur1->data); cur1 = cur1->next; } else { linklist_pushback(&new_head, cur2->data); cur2 = cur2->next; } } if (*list1 != NULL) { tail = new_head; while (tail->next != NULL) { tail = tail->next; } tail->next = cur1; } else { tail = new_head; while (tail->next != NULL) { tail = tail->next; } tail->next = cur2; } return new_head; } int Linklisthascycle(listpoint head)//判斷是否有環 { if (head == NULL) { return 0; } listpoint fast = head; listpoint slow = head; if (head->next == NULL) { return 0; } while (fast != NULL) { fast = fast->next->next; slow = slow->next; if (fast == slow) { return 1; } if (fast == NULL) { return 0; } if (fast->next == NULL) { return 0; } } return 0; } listpoint FindListKNode(listpoint head, size_t k)//找到倒數第K個節點 { if (head == NULL) { return NULL; } listpoint fast = head; listpoint slow = head; while (k--) { if (fast == NULL) { return NULL; } fast = fast->next; } while (fast != NULL) { fast = fast->next; slow = slow->next; } return slow; } listpoint EraseLastKNode(listpo 4000 int head, size_t k)//刪除倒數第k個節點 { if (head == NULL) { return NULL; } listpoint find_node = NULL; listtype temp = 0; find_node = FindListKNode(head, k); temp = find_node->data; find_node->data = find_node->next->data; find_node->next->data = temp; listpoint p_temp = find_node->next->next; destroy(find_node->next); find_node->next = p_temp; return head; } size_t GetCycleLen(listpoint head)//如果鏈表帶環,求出它的長度 { if (head == NULL) { return 0; } size_t count = 1; listpoint fast = head; listpoint slow = head; while (fast != NULL) { fast = fast->next->next; slow = slow->next; if (fast == slow) { break; } } while (fast->next != slow) { count++; fast = fast->next; } return count; } listpoint GetCycleEntry(listpoint head)//如果鏈表帶環,求出環的入口 { if (head == NULL) { return NULL; } listpoint start = head; listpoint fast = head; listpoint slow = head; while (fast != NULL) { fast = fast->next->next; slow = slow->next; if (fast == slow) { break; } } while (start != fast) { start = start->next; fast = fast->next; } return start; } listpoint HasCross1(listpoint head1, listpoint head2)//判断链表是否相交并求交点 { if (head1 == NULL || head2 == NULL) { return NULL; } //两个不带环的链表 listpoint cur1 = head1; listpoint cur2 = head2; while (cur1->next != NULL) { cur1 = cur1->next; } cur1->next = cur2; int ret = Linklisthascycle(head1); if (ret == 1) { printf("两链表相交\n"); } else { printf("两链表不相交\n"); return NULL; } return GetCycleEntry(head1); } listpoint HasCross2(listpoint head1, listpoint head2)//判断链表是否相交并求交点 { listpoint cur1 = head1; listpoint cur2 = head2; listpoint ret = NULL; if (GetCycleEntry(head1) == GetCycleEntry(head2)) { ret = GetCycleEntry(head1); while (cur1->next != ret) { cur1 = cur1->next; } cur1->next = cur2; ret = GetCycleEntry(head1); return ret; } else { listpoint ret1_head1 = GetCycleEntry(head1); listpoint ret2_head2 = GetCycleEntry(head2); listpoint fast = ret1_head1; listpoint slow = ret2_head2; while (fast != slow) { fast = fast->next->next; slow = slow->next; } return fast; } return NULL; } listpoint HasCross(listpoint head1, listpoint head2)//判断链表是否相交并求交点 { if (head1 == NULL || head2 == NULL) { return NULL; } size_t flag = 0; listpoint ret_note = NULL; if (Linklisthascycle(head1) + Linklisthascycle(head2) == 2) { size_t len = GetCycleLen(head1); listpoint ret_enter_head1 = GetCycleEntry(head1); listpoint ret_enter_head2 = GetCycleEntry(head2); while (len--) { ret_enter_head1 = ret_enter_head1->next->next; ret_enter_head2 = ret_enter_head2->next; if (ret_enter_head1 == ret_enter_head2) { flag = 1; } } if (flag == 1) { ret_note = HasCross2(head1, head2); return ret_note; } return NULL; } else if (Linklisthascycle(head1) + Linklisthascycle(head2) == 0) { ret_note = HasCross1(head1, head2); return ret_note; } else { return NULL; } }
测试函数(test.c)
#include "linklist.h" int main() { listpoint node = NULL; listpoint node2 = NULL; listpoint node3 = NULL; listpoint node4 = NULL; listpoint node5 = NULL; listpoint node6 = NULL; listpoint tmp = NULL; listpoint ret = NULL; int RET = 0; linklist_init(&node);//初始化 linklist_pushback(&node, 5);//尾插 linklist_pushback(&node, 5);//尾插 linklist_pushback(&node, 6);//尾插 linklist_init(&node2);//初始化 linklist_pushback(&node2, 2);//尾插 linklist_pushback(&node2, 4);//尾插 linklist_pushback(&node2, 6);//尾插 linklist_init(&node3);//初始化 linklist_pushback(&node3, 1);//尾插 linklist_pushback(&node3, 3);//尾插 linklist_pushback(&node3, 5);//尾插 linklist_init(&node4);//初始化 linklist_pushback(&node4, 1);//尾插 linklist_pushback(&node4, 2);//尾插 linklist_pushback(&node4, 3);//尾插 linklist_pushback(&node4, 4);//尾插 linklist_pushback(&node4, 5);//尾插 linklist_pushback(&node4, 6);//尾插 linklist_init(&node5);//初始化 linklist_pushback(&node5, 1);//尾插 linklist_pushback(&node5, 2);//尾插 linklist_pushback(&node5, 3);//尾插 linklist_pushback(&node5, 4);//尾插 linklist_pushback(&node5, 5);//尾插 linklist_pushback(&node5, 6);//尾插 linklist_init(&node6);//初始化 linklist_pushback(&node6, 1);//尾插 linklist_pushback(&node6, 2);//尾插 linklist_pushback(&node6, 3);//尾插 linklist_pushback(&node6, 4);//尾插 linklist_pushback(&node6, 5);//尾插 linklist_pushback(&node6, 6);//尾插 linklist_popback(&node);//尾删 linklist_popback(&node);//尾删 linklist_pushhead(&node, 7);//头插 linklist_pushhead(&node, 7);//头插 linklist_pophead(&node);//头删 linklist_insert(&node, 1, 9);//任意位置插入 linklist_insert(&node, 2, 15);//任意位置插入 linklist_insert(&node, 3, 20);//任意位置插入 linklist_pop(&node, 1);//任意位置删除 linklist_pop(&node, 2);//任意位置删除 linklist_print(node);//打印 LinkListReversePrint(node);//逆序打印單鏈表 ret=Linklistfind(node,1);//查找結點 LinkListInsertBefore(&node,ret,20);//不允许遍历链表, 在 pos之前插入 ret = Linklistfind(node,1);//查找結點 LinkListInsertBefore(&node, ret, 30);//不允许遍历链表, 在 pos之前插入 node=LinkListReverse(&node);//鏈表逆置 Linklistsort(node);//冒泡排序 ret = LinkListMerge(&node2, &node3);//合并鏈表 RET=Linklisthascycle(node);//判斷是否有環 ret=FindListKNode(node,2);//找到倒數第K個節點 node = EraseLastKNode(node, 5);//刪除倒數第k個節點 node = EraseLastKNode(node, 2);//刪除倒數第k個節點 node = EraseLastKNode(node, 2);//刪除倒數第k個節點 listpoint cur = node4; while (cur->next != NULL) { cur = cur->next; } cur->next = node4->next; RET = Linklisthascycle(node4);//判斷是否有環 RET=GetCycleLen(node4);//如果鏈表帶環,求出它的長度 ret=GetCycleEntry(node4);//如果鏈表帶環,求出環的入口 node6->next->next = node5->next->next; ret=HasCross(node5,node6);//判断链表是否相交并求交点 free(node); system("pause"); return 0; }
相关文章推荐
- Java实现单链表的一些常用操作
- 单链表基础操作C++实现
- C语言实现单链表的初始化、创建、遍历等操作
- 原生JS实现一些简单的操作
- 单链表的一些操作(全~)
- 数据结构基础(8) --单链表的设计与实现(1)之基本操作
- 遍历表格中的input转化为json数据传到后台解析实现一些操作
- Java实现单链表的各种操作
- java实现单链表的基础操作
- 单链表的一些操作
- C#中Bitmap类实现对图像操作的一些方法
- 单链表基础操作C++实现
- java实现单链表操作
- C语言实现单链表的各种操作
- 数据结构之 单链表的实现与操作
- 更新一些堆栈的操作实现
- 利用C语言实现一些简单的栈操作
- c++学习笔记—单链表基本操作的实现
- 递归法实现对单链表的基本操作
- C语言数据结构单链表的一些基本操作