链表

单向链表c++实现

被刻印的时光 ゝ 提交于 2020-03-07 22:07:01
单向链表的结构 单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。 设置节点类如下: class Node{ int item; Node* next; }; 其中节点指针next指向节点类型变量,从而实现链表的连接 设置链表类如下,包含一节点指针head class SingleLink{ public: SingleLink(); ~SingleLink(); Node* head; void append(int); }; 新建一个链表,初始化如下: SingleLink::SingleLink(){ head = new Node(); head->item = 0; head->next = NULL; } 在head = new Node()时,指针head便有了个新的对象 详解链表尾插法实现原理 1.插入第一个元素,指针n有个新对象 Node* n = new Node(); n->item = 11; n->next = NULL; 指针next等于指针n,表示next的指向与n的指向一致 head->next = n; n->next = NULL; 2.插入第二个元素,即n又有了个新对象 Node* n = new Node(); n-

二、容器

安稳与你 提交于 2020-03-07 19:56:43
java容器有哪些 数组、String(底层是char数组)、java.util下 的 List、Set、Map、Queue,画图说明如下: Collection和Collections有什么区别 Collection为集合的通用接口,提供了对集合进行操作的通用接口方法 Collections为集合操作的工具类,提供了集合的静态操作方法,不能实力化 List、set、Map之间的区别是什么 三个集合操作的不同 HashMap和HashTable有什么区别 HashMap:线程不安全,效率高;key和value可以为空 HashTable:线程安排,效率低;key和value都不能为空 如何决定使用HashMap还是TreeMap HashMap不支持排序,查询效率高;TreeMap默认用key排序,也支持自定义排序,查询效率低;如无排序要求,尽量使用HashMap HashMap的实现原理 利用key的hashCode重新hash计算出当前对象的元素在数组中的下标 存储时,如果没有该hash值得key,则放入;如果出现hash值相同的key,此时有两种情况。(1)如果key相同,则覆盖原始值;(2)如果key不同(出现冲突),则将当前的key-value放入链表中 获取时,直接找到hash值对应的下标,在进一步判断key是否相同,如果相同,取出该值;如果不同,从链表中找对应值。

leetcode 21.合并两个有序链表

故事扮演 提交于 2020-03-07 12:08:54
题目 将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 解法 递归 每次确定有序链表的第一个元素。 /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public : ListNode * mergeTwoLists ( ListNode * l1 , ListNode * l2 ) { if ( l1 == NULL && l2 == NULL ) return NULL ; else if ( l1 == NULL && l2 != NULL ) return l2 ; else if ( l2 == NULL && l1 != NULL ) return l1 ; if ( l1 - > val < l2 - > val ) { ListNode * tmp = l1 - > next ; l1 - > next = mergeTwoLists ( tmp , l2 ) ; return

Java实现 LeetCode 234 回文链表

蓝咒 提交于 2020-03-07 11:03:04
234. 回文链表 请判断一个链表是否为回文链表。 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶: 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题? /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public boolean isPalindrome ( ListNode head ) { // 要实现 O(n) 的时间复杂度和 O(1) 的空间复杂度,需要翻转后半部分 if ( head == null || head . next == null ) { return true ; } ListNode fast = head ; ListNode slow = head ; // 根据快慢指针,找到链表的中点 while ( fast . next != null && fast . next . next != null ) { fast = fast . next . next ; slow = slow . next ; } slow

LeetCode 面试题 02.08. 环路检测

孤街醉人 提交于 2020-03-07 10:27:37
题目链接: https://leetcode-cn.com/problems/linked-list-cycle-lcci/ 给定一个有环链表,实现一个算法返回环路的开头节点。 有环链表的定义:在链表中某个节点的next元素指向在它前面出现过的节点,则表明该链表存在环路。 示例 1: 输入:head = [3,2,0,-4], pos = 1 输出:tail connects to node index 1 解释:链表中有一个环,其尾部连接到第二个节点。 示例 2: 输入:head = [1,2], pos = 0 输出:tail connects to node index 0 解释:链表中有一个环,其尾部连接到第一个节点。 示例 3: 输入:head = [1], pos = -1 输出:no cycle 解释:链表中没有环。 1 struct ListNode *detectCycle(struct ListNode *head) { 2 struct ListNode *fast=head,*slow=head; 3 while(fast&&fast->next){ 4 slow=slow->next; 5 fast=fast->next->next; 6 if(fast==slow) break; 7 } 8 if (fast==NULL||fast->next=

ConcurrentHashMap 的实现原理

若如初见. 提交于 2020-03-07 08:57:19
概述 我们在之前的博文中了解到关于 HashMap 和 Hashtable 这两种集合。其中 HashMap 是非线程安全的,当我们只有一个线程在使用 HashMap 的时候,自然不会有问题,但如果涉及到多个线程,并且有读有写的过程中,HashMap 就不能满足我们的需要了(fail-fast)。在不考虑性能问题的时候,我们的解决方案有 Hashtable 或者Collections.synchronizedMap(hashMap),这两种方式基本都是对整个 hash 表结构做锁定操作的,这样在锁表的期间,别的线程就需要等待了,无疑性能不高。 所以我们在本文中学习一个 util.concurrent 包的重要成员,ConcurrentHashMap。 ConcurrentHashMap 的实现是依赖于 Java 内存模型,所以我们在了解 ConcurrentHashMap 的前提是必须了解Java 内存模型。但 Java 内存模型并不是本文的重点,所以我假设读者已经对 Java 内存模型有所了解。 ConcurrentHashMap 分析 ConcurrentHashMap 的结构是比较复杂的,都深究去本质,其实也就是数组和链表而已。我们由浅入深慢慢的分析其结构。 先简单分析一下,ConcurrentHashMap 的成员变量中,包含了一个 Segment 的数组( final

找链表最小值,并判断奇偶,对链表进行不同操作

帅比萌擦擦* 提交于 2020-03-07 06:57:27
题目描述 设有一一个由正整数组成的无序单链表,编写算法实现下列功能: 1.找出最小值结点,且显示该数值。 2.若该数值为奇数,则将其与直接后继结点的数值交换。 3.若为偶数,则将其直接后继结点删除。 输入 5 7 5 4 8 6 5 7 5 3 8 6 输出 最小值为: 4 7 5 4 6 最小值为: 3 7 5 8 3 6 解题思路 在链表结构体中存两个值,一个为下标,一个为对应的值。一开始让最小值等于第一个节点的值,然后循环到最后,一直和最小值进行比较,找到最小值,并记录下标。随后判断奇数偶数,让指针指到对应位置,进行操作。 解释一下删除操作 源代码 # include <stdio.h> # include <stdlib.h> typedef int ElementType ; typedef struct Node * PtrToNode ; struct Node { ElementType Data ; ElementType Num ; PtrToNode Next ; } ; typedef PtrToNode List ; List Read ( ) ; List Min ( List L ) ; void Print ( List L ) ; int main ( ) { List L ; L = Read ( ) ; L = Min ( L ) ;

21、删除链表中的节点

拟墨画扇 提交于 2020-03-07 06:09:32
21、删除链表中的节点 请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点。 现有一个链表 -- head = [4,5,1,9],它可以表示为: 示例 1: 输入: head = [4,5,1,9], node = 5 输出: [4,1,9] 解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9. 示例 2: 输入: head = [4,5,1,9], node = 1 输出: [4,5,9] 解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9. 说明: 链表至少包含两个节点。 链表中所有节点的值都是唯一的。 给定的节点为非末尾节点并且一定是链表中的一个有效节点。 不要从你的函数中返回任何结果。 答案解析: /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public void deleteNode(ListNode node) { //https://www.cnblogs.com

数据结构之链表与数组(三)-单向链表上的简单操作

北战南征 提交于 2020-03-07 06:07:18
4 反转单向链表(非递归实现) 思路: 图1 非递归反转链表 如图1所示,假设已经反转了前面的若干节点,且前一段链表的头节点指针为pre,则现在要做的事情是首先保存当前节点cur后面的链表,然后让当前节点cur的指针与后面的节点断开(step1),接下来再将当前节点的next指针指向前一段链表的头节点pre (step2)。处理完当前节点的连接反转后,所有的指针都向后移一位。开始处理下一个节点。 注意点: 1,反转后原来的头节点就变成了反转链表的尾节点,要注意将此结点next指针设为空,否则可能会产生死循环等问题 2,要记得处理链表中没有节点或只有一个的情况。 代码实现: //反转链表(非递归的方式) //输入参数:单链表的头指针 //输出参数:无 //返回值:反转后的单链表指针 SingleList* Reverse_NRecu(SingleList *head) { SingleList *pre,*cur,*lat; //链表中没有节点或只有一个节点 if((head == NULL)||(head->next == NULL)) { return head; } pre = head; cur = head->next; head->next = NULL;//在链表中应该注意边界情况的处理,尾结点一定要为空 lat = cur->next; while(lat !=

1025 反转链表 (25分)

白昼怎懂夜的黑 提交于 2020-03-07 05:05:50
# include <stdio.h> # include <algorithm> using namespace std ; struct Node { int now ; int data ; int next ; int order ; } node [ 100010 ] ; bool cmp ( Node a , Node b ) { return a . order < b . order ; } int main ( ) { int first , n , m ; scanf ( "%d%d%d" , & first , & n , & m ) ; for ( int i = 0 ; i <= 100010 ; i ++ ) { node [ i ] . order = 100010 ; } for ( int i = 1 ; i <= n ; i ++ ) { int now ; scanf ( "%d" , & now ) ; scanf ( "%d%d" , & node [ now ] . data , & node [ now ] . next ) ; node [ now ] . now = now ; } int p = first , count = 0 ; while ( p != - 1 ) { node [ p ] . order = count