链表

如何检查一个单向链表上是否有环?

孤街浪徒 提交于 2020-04-06 20:47:40
1, 最简单的方法, 用一个指针遍历链表, 每遇到一个节点就把他的内存地址(java中可以用object.hashcode())做为key放在一个hashtable中. 这样当hashtable中出现重复key的时候说明此链表上有环. 这个方法的时间复杂度为O(n), 空间同样为O(n). 2, 使用反转指针的方法, 每过一个节点就把该节点的指针反向: <!-- lang: cpp --> Boolean reverse(Node *head) { Node *curr = head; Node *next = head->next; curr->next = NULL; while(next!=NULL) { if(next == head) { /* go back to the head of the list, so there is a loop */ next->next = curr; return TRUE; } Node *temp = curr; curr = next; next = next->next; curr->next = temp; } /* at the end of list, so there is no loop, let's reverse the list back */ next = curr->next; curr ->next =

5种常见的链表基本操作

梦想与她 提交于 2020-04-06 17:30:59
单链表的基本操作: 1、单链表反转 2、链表中环的检测 3、两个有序链表的合并 4、删除倒数第K个结点 5、求链表的中间结点 编写链表代码的注意事项: 1、如果链表为空时,代码是否能正常工作? 2、如果链表只包含一个结点时,代码是否能正常工作? 3、如果链表只包含两个结点时,代码是否能正常工作? 4、代码逻辑在处理头结点和尾结点的时候,是否能正常工作? 单链表反转 package com.datastructure.linkedlist; /** * 单链表的基本操作: * 1、单链表反转 * 2、链表中环的检测 * 3、两个有序链表的合并 * 4、求链表的中间结点 * * @Auther: dlm * @Date: 2020/4/6 10:19 */ public class SingleLinkedListBasicsOperate { public static class Node{ private int data; //存储整型数据 private Node next; //指向下一个结点的指针 public Node(int data,Node next){ this.data = data; this.next = next; } public int getData(){ return this.data; } } //1、单链表反转(不带头结点) public

链表排序

◇◆丶佛笑我妖孽 提交于 2020-04-06 11:46:53
//结构体 struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; 插入排序(算法中是直接交换节点,时间复杂度O(n^2),空间复杂度O(1)) class Solution { public: ListNode *insertionSortList(ListNode *head) { // IMPORTANT: Please reset any member data you declared, as // the same Solution instance will be reused for each test case. if(head == NULL || head->next == NULL)return head; ListNode *p = head->next, *pstart = new ListNode(0), *pend = head; pstart->next = head; //为了操作方便,添加一个头结点 while(p != NULL) { ListNode *tmp = pstart->next, *pre = pstart; while(tmp != p && p->val >= tmp->val) //找到插入位置 {tmp =

***148. Sort List 排序链表

做~自己de王妃 提交于 2020-04-06 11:36:48
1. 原始题目 在 O ( n log n ) 时间复杂度和常数级空间复杂度下,对链表进行排序。 示例 1: 输入: 4->2->1->3 输出: 1->2->3->4 示例 2: 输入: -1->5->3->4->0 输出: -1->0->3->4->5 2. 思路 归并排序。这道题两个递归解决。非常简洁。 快慢指针+归并排序 。 3. 解题 1 class Solution: 2 def sortList(self, head: ListNode) -> ListNode: 3 if not head or not head.next:return head 4 p,q = head, head.next 5 while(q and q.next): # 快慢指针,p最终指向中点 6 p = p.next 7 q = q.next.next 8 head2 = p.next 9 p.next = None 10 head = self.sortList(head) # 排好序的左链表 11 head2 = self.sortList(head2) # 排好序的右链表 12 head = self.merge(head,head2) # 合并两个排好序的链表 13 return head 14 15 def merge(self,head1,head2): #

LeetCode--链表

拥有回忆 提交于 2020-04-06 11:35:32
1、使用常量空间复杂度在O(n log n)时间内对链表进行排序。 思路: 因为题目要求复杂度为O(nlogn),故可以考虑归并排序的思想。 归并排序的一般步骤为: 1)将待排序数组(链表)取中点并一分为二; 2)递归地对左半部分进行归并排序; 3)递归地对右半部分进行归并排序; 4)将两个半部分进行合并(merge),得到结果。 所以对应此题目,可以划分为三个小问题: 1)找到链表中点 (快慢指针思路,快指针一次走两步,慢指针一次走一步,快指针在链表末尾时,慢指针恰好在链表中点); 2)写出merge函数,即如何合并链表。 (见merge-two-sorted-lists 一题解析) 3)写出mergesort函数,实现上述步骤。 /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: //找到链表中的中点 ListNode *findMiddle(ListNode *head){ ListNode *chaser = head; ListNode *runner = head->next; while

并发编程的艺术07-非阻塞同步演进

ぃ、小莉子 提交于 2020-04-06 11:32:16
前言 不知道大家有没有发现几乎每个专业领域中都充斥着很多抽象的专业名词,如果没有相关的基础知识很难知道这些专业名词是什么意思,就比如说我们的这个标题“粗粒度同步”。川建国听了想骂娘,什么是TMD“粗粒度同步”?最近我对理查德·费曼做了一些了解,他在阐述一个事物的时候强调要用通俗易懂的语言,让人容易理解的方式而不是专业名词满天飞。对于一个事物能够给一个孩子或者是一个对此不了解的外行人讲明白就说明你自己是真的明白了。所以我们的技术类文章也会力求用通俗易懂的方式把事物讲的让人更容易理解,而不是使用大量的专业名词。 本章内容我们将以一个集合作为例子,集合中有 add , remove ,contains 三个函数。 add(x) 函数将元素 x 添加到集合中,当且仅当集合中原先不存在 x 时返回 true。 remove(x) 函数将元素 x 从集合中删除,当且仅当集合中原来存在 x 的时候返回 true 。 当且仅当集合中包含 x 元素时 contains(x) 返回 true。 链表中除了包含集合元素的常规节点外,还使用了两个称为 head , tail 的哨兵节点,作为链表的第一个节点和最后一个节点。哨兵节点不能被添加,删除,或查找,它们的 key 值分别为整数值的最小和最大值,也就是说 key 值越大的元素排序越靠后。 粗粒度同步 “粗粒度同步

数据结构概述

≡放荡痞女 提交于 2020-04-06 10:36:34
数据结构 数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。 常用结构 数组: 在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类数据元素的集合称为数组。在C语言中, 数组属于构造数据类型。一个数组可以分解为多个数组元素,这些数组元素可以是基本数据类型或是构造类型。因此按数组元素的类型不同,数组又可分为数值数组、字符数组、指针数组、结构数组等各种类别。 栈: 是只能在某一端插入和删除的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。 队列: 一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列是按照“先进先出”或“后进后出”的原则组织数据的。队列中没有元素时,称为空队列。 链表: 是一种物理存储单元上非连续、非顺序的存储结构,它既可以表示线性结构,也可以用于表示非线性结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成

第一次课程设计体会

孤者浪人 提交于 2020-04-06 09:22:03
第一次课程设计体会# 这次的课程设计带给我感受比较大的是在细节、理解和耐心三个方面。 整个系统的大部分程序都是考察数据结构当中单向链表的操作,在写代码的过程中,不断出现的无法运行程序、莫名其妙地开始刷屏、程序突然地结束都在告诉我对这方面有多不熟悉。确实,我阅读了课本的程序,看了翁恺的mooc,我还是没能搞懂。这就非常考验我的耐心,我在看似理解了其实完全没有理解的状态下徘徊几度无奈。但为了能完成课设,我利用了我所能查找到的一切的资源去让自己理解链表这个东西其真正是如何操作的其原理是什么,好处有什么。寻找了大量教学视频,终于在B站找到了一个他讲链表我听得懂的老师,并完成链表部分的代码。在调试的过程下,代码成功运行,那一刻的成就感不禁感谢自己的坚持和耐心,以及没理解好就不写代码的决心。 在对照着题目完成程序的过程中,细节我觉得是相当重要的。例如在输入记录的这个功能里面,题目还要求需要进行合法性检查。这也让人想起来后面的修改、删除两个功能也需要相应的合法检查,不然就无法完成相应的功能。并且在题目中所需要我们展示的表格示例里面,其平均工资一行,其数字是很有一定特殊性的,其小数点后的数字如果有除0以外的值是会被表示出来的,若没有则就不表示出来。所以我去查找了一点资料,发现这就需要使用%g的格式符,而%g的格式符只能用于浮点数上,所以我又将系统中的各类工资类型改成浮点型。而还有一个细节问题

C语言动态内存分配:(一)malloc/free的实现及malloc实际分配/释放的内存

大兔子大兔子 提交于 2020-04-06 08:36:28
一、malloc/free概述 malloc是在C语言中用于在程序运行时在堆中进行动态内存分配的库函数。free是进行内存释放的库函数。 1、函数原型 #include <stdlib.h> void *malloc( size_t size ); void free( void* memblock ); 2、返回值 成功时,返回所分配存储空间的起始地址;返回值类型为void*,在C语言中可以把void*直接付给具体的类型,但是在C++中必须进行强制类型转换 失败时(内存不足时)返回NULL size为0时,返回的指针不是NULL;但是除了free,别的地方不要使用这个指针。 3、使用示例 #include <stdlib.h> /* For _MAX_PATH definition */ #include <stdio.h> #include <malloc.h> void main( void ) { char *string; /* Allocate space for a path name */ string = malloc( _MAX_PATH ); // In a C++ file, explicitly cast malloc's return. For example, // string = (char *)malloc( _MAX_PATH ); if(

LeetCode.23 | 合并K个排序链表

巧了我就是萌 提交于 2020-04-06 03:24:00
""" https://leetcode-cn.com/problems/merge-k-sorted-lists/solution/he-bing-kge-pai-xu-lian-biao-by-leetcode/ 思路:还是以暴力遍历为主,先将链表->列表->列表.排序->新链表 1.新建一个空list,用以存储链表值,sortList存储排序后列表值 2.新建两个ListNode:head和dummy 2.1:head用以最后链表头的返回 2.2:dummy用以创建新链表 3.遍历链表,将值记录list;列表排序 4.生成新链表 """ class Solution: def mergeKLists(self, lists: List[ListNode]): curList=[] head=ListNode(0) dummy=head for ln in lists: #循环List中的ListNode while ln: #循环ListNode中的node curList.append(ln.val) ln=ln.next sortList=sorted(curList) for num in sortList: dummy.next=ListNode(num) dummy=dummy.next return head.next 来源: oschina 链接: https: