`
- 浏览:
16707109 次
- 性别:
- 来自:
济南
-
---------------------------------------------------------------------------1. 转置单向链表 (也就是反序,注意链表的边界条件并考虑空链表)。#include <stddef.h>struct listtype{ int data; struct listtype * next;};typedef struct listtype * list;/* Reverse the singly linked list *psll. */void reverse_singly_linked_list(list * psll){ list h = NULL; list p = *psll; if (!psll || !*psll) { return; } while (p) { list tmp = p; p = p->next; tmp->next = h; h = tmp; } *psll = h;}---------------------------------------------------------------------------2. 在链表里如何发现循环链接?#include <stddef.h>struct listtype{ int data; struct listtype * next;};typedef struct listtype * list;/* Check that whether there is loop in the singly linked list sll or not. */int find_circle(list sll){ list fast = sll; list slow = sll; if (NULL == fast) { return -1; } while (fast && fast->next) { fast = fast->next->next; slow = slow->next; if (fast == slow) { return 1; } } return 0;}参考:http://ostermiller.org/find_loop_singly_linked_list.html---------------------------------------------------------------------------3. 找到单向链表中间那个元素,如果有两个则取前面一个。#include <stddef.h>struct listtype{ int data; struct listtype * next;};typedef struct listtype * list;/* Find the middle element of the singly linked list sll. */list find_middle(list sll){ list slow = sll; list fast = sll; if (NULL == fast) { return NULL; } while (1) { if (NULL == fast->next || NULL == fast->next->next) { return slow; } slow = slow->next; fast = fast->next->next; /* Prevent that there is a loop in the linked list. */ if (fast == slow) { return NULL; } }}---------------------------------------------------------------------------4. 删除单链表的倒数第 m 个元素。 给定一个单向链表 (长度未知),请设计一个既节省时间又节省空间的算法来找出该链表中的倒数第 m 个元素。实现这个算法,并为可能出现的特例情况安排好处理措施。#include <stddef.h>struct listtype{ int data; struct listtype * next;};typedef struct listtype * list;/* Find the mth element of the singly linked list sll from the end. */list find_the_mth_element_from_end(list sll, int m){ list fast = sll; /* Used for loop detecting. */ list ahead = sll; list after = sll; if (NULL == ahead || m <= 0) { return NULL; } while (m--) { if (NULL == ahead) { return NULL; } ahead = ahead->next; if (fast && fast->next) { fast = fast->next->next; if (fast == ahead) { return NULL; } } } while (1) { if (NULL == ahead) { return after; } ahead = ahead->next; after = after->next; if (fast && fast->next) { fast = fast->next->next; if (fast == ahead) { return NULL; } } }}---------------------------------------------------------------------------5. 给定一个单向链表的头指针,要求找出该链表循环部分的第一个节点。如果该链表不是循环链表,则返回空指针。例如给定下面的链表: 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> (3) 循环就应该返回结点 3 的指针。请优化时间和空间。解法一:一次遍历,把地址存入 hash 表就行了,第一次出现重复的地址就是需要的解。时间复杂度 O(n),空间复杂度 O(n)。解法二:把链表当做有向图,进行深度优先遍历,第一个回退边指向的节点即是需要的解。时间复杂度 O(n),空间复杂度 O(n)。解法三:首先根据链表创建一个逆序的链表。如下:原始:1->2->3->4->5->6->7->8->(3)逆序:1->2->3->8->7->6->5->4->(3)然后分别从两个链表头指针开始,找到 next 指针不一样的那个节点就是最终目标了。时间复杂度 O(n),空间复杂度 O(n)。解法四:用两个步长分别为 1 和 2 的指针前进,第一次相遇之后再前进,第二次相遇时停止。记下从第一次相遇到第二次相遇,步长为 1 的指针走过的步数 S,则 S 为环的长度。然后用两个指针,一个在链头,一个走到链头后第 S 个位置上,同时以步长为 1 前进,判断两个指针是否相等,如果是就是环的起始位置了。时间复杂度 O(n),空间复杂度 O(1)。解法五:(跟解法四的思想差不多,优于解法四,因为常数因子小)用两个步长分别为 1 和 2 的指针前进,第一次相遇之后,令其中一个指针指向链表头。然后,令两个指针步长都为 1,同时前进,相遇时停止。该节点就是环的起始位置。时间复杂度 O(n),空间复杂度 O(1)。下面给出解法五的 C 实现。#include <stddef.h>struct listtype{ int data; struct listtype * next;};typedef struct listtype * list;/** Find the head node of the loop in the singly linked list sll.* If there is not a loop in sll, NULL is return.*/list find_head_of_loop(list sll){ list slow = sll; list fast = sll; if (NULL == fast) { return NULL; } while (1) { if (NULL == fast->next || NULL == fast->next->next) { return NULL; } slow = slow->next; fast = fast->next->next; if (fast == slow) { slow = sll; break; } } while (1) { slow = slow->next; fast = fast->next; if (fast == slow) { return fast; } }}参考:http://www.chinaunix.net/jh/23/896018.html---------------------------------------------------------------------------6. 给定一个单向链表的结点,要求在常数时间里删除该结点。 常数时间删除结点肯定不行,不过可以用假删除,就是把要删除节点的值用要删除节点的下一个节点值覆盖,然后删除下一个节点 (要求该节点的下一个节点不能是空) : p->data = p->next->data; temp = p->next; p->next = temp->next; free(temp);---------------------------------------------------------------------------
分享到:
Global site tag (gtag.js) - Google Analytics
相关推荐
压缩包中的"Ex17_01"可能包含示例代码或练习题,你可以通过查看这些内容进一步加深对C#单向链表实现的理解。实践是学习编程的最佳途径,尝试编写和修改链表操作的代码,将帮助你巩固理论知识并提升编程技能。
C++进阶学习——单向链表的实现,相关教程链接如下: http://blog.csdn.net/tennysonsky/article/details/49685199
单向链表是一种基本的数据结构,它在计算机科学和编程中有着广泛的应用。与数组不同,链表中的元素不是在内存中连续存储的,而是通过指针连接起来。本篇文章将深入探讨单向链表的基本概念,包括其结构体定义、如何...
单向链表是一种基本的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的引用。在Kotlin中实现单向链表,我们需要理解链表的基本操作,包括创建链表、添加元素、删除元素以及遍历链表。下面我们将...
本文详细介绍了使用C语言实现带头结点的单向链表的基本操作,包括链表的创建、输出、插入元素和删除元素,以及单向链表的逆序连接和两个有序线性表的归并。 一、链表的创建 链表的创建是指在内存中分配一个结点,...
链表的种类主要有单向链表、双向链表和循环链表。单向链表中的节点只包含一个指向下一个节点的指针;双向链表中的节点包含两个指针,一个指向前一个节点,另一个指向下一个节点;循环链表则是首尾相接的链表,形成一...
- **单向链表**:每个节点只包含一个指向后继节点的指针。 - **双向链表**:每个节点包含两个指针,一个指向前驱节点,另一个指向后继节点。 - **循环链表**:最后一个节点的指针不是指向`NULL`,而是返回到链表的...
本程序是用C语言实现的简单学生成绩管理,用到的主要知识点是链表,涉及到链表的建立,插入,节点的删除,排序等几乎所有的链表常用操作.模块强,可以根据需要自行裁减,原创作品!
链表分为单向链表、双向链表和循环链表等类型。 1. **输出链表所有结点信息**: 在题目给出的`printlist`函数中,用于遍历链表并打印每个节点的信息。`while`循环条件是`p != NULL`,确保在遍历到链表末尾时停止。...
在本主题中,我们将深入探讨如何使用链表结构来实现一个学生成绩管理系统。这个系统由数据结构专家刘小晶教授举例讲解,旨在帮助我们理解数据结构在实际问题中的应用,特别是链表这一核心概念。链表是一种非连续、非...
给你一个链表,节点有值域,计数器(表示值出现的次数,初始化为1),指针域,节点的值有重复的,去除重复的值,修改相应节点的计数器。这样做的好处就是节省的很多存储空间。 对即将参加华为机考的同学有非常大的帮助...
单向循环链表是一种特殊的线性表存储结构,其中每个节点包含一个指向下一个节点的指针,最后一个节点的指针指向链表的头节点,形成一个闭环。在约瑟夫环问题中,单向循环链表非常适合模拟游戏参与者围成一圈的情形。...
链表功能的一个扩展延伸,查找倒数第K个元素,是某年考研题
链表分为单向链表、双向链表和循环链表等类型,它们各有优缺点,如单向链表插入和删除操作相对简便,但访问元素不如数组直接。 栈是一种后进先出(LIFO)的数据结构,常被比喻为一个堆叠的盘子。栈的操作主要包括压...
华为OD机试 - 单向链表中间节点(Java & JS & Python & C & C++).html付费专栏内容,免费下载,多种语言解法
值得注意的是,题目中还提供了一个错误的版本包含了 `struct Student *pre` 成员,这实际上不是必需的,因为这是单向链表,无需维护前一个节点的信息。 ##### 创建链表 链表的创建主要涉及内存分配和节点之间的链接...
在上述题目中,我们看到两个关于创建单向链表的算法,以及链表操作的问题,包括删除和队列操作。 1. 尾插法建立单向链表: 在`create1`函数中,我们需要创建一个带头结点的单向链表,其中节点按顺序插入。填空部分...
单项动态链表(也称为单向链表)是其中一种类型,每个节点只包含一个指向后继节点的链接。 #### 二、题目背景与要求 本题要求用C语言编写程序来创建一个包含三名学生数据的单项动态链表,并提供了三种不同的实现...
在本题中,我们关注的是单向链表,并探讨了四种基本操作:创建链表、尾插法插入节点、首插法插入节点以及显示链表中的所有数据节点。 1. **插入操作**: 函数`insert`实现了将指定节点插入已排序链表的功能,保持...
题:第一,只有头指针,没有尾指针。如要在表尾插入结点,则效率很低。第二,求表长 要从表头找到表尾效率也很低。第三,基本操作函数太少。c2-5.h 是从实际应用角度出发 重新定义的线性链表类型,LinkList 类型增加...