链表

泛型单链表

放肆的年华 提交于 2020-02-28 14:22:14
泛型单链表 单链表将每个数据分为节点,每个节点存储数据和指向下一个节点的指针。这样数据就不用在内存中使用连续的存储空间,有更大的灵活性。 这里将单链表分为节点类(Node)和链表类(singleLinkedList),由于链表类需要访问到Node类的数据,因此将Node类的数据声明为 public ,也可以将链表类声明为节点类的友元类。 抽向数据类型(ADT) :(linearList.h) /************************************************************************* > File Name : linearList.h > Author : Harold > Mail : 2106562095@qq.com > Github : www.github.com/Haroldcc > Created Time : 2020年02月26日 11时02分58秒 ************************************************************************/ /***** 线性表的抽象定义 *****/ # ifndef LINEARLIST_H # define LINEARLIST_H # include <iostream> template < typename

HashMap 如何解决hash冲突

落爺英雄遲暮 提交于 2020-02-28 13:36:02
在Java编程语言中,最基本的结构就是两种,一种是数组,一种是模拟指针(引用),所有的数据结构都可以用这两个基本结构构造,HashMap也一样。 当程序试图将多个 key-value 放入 HashMap 中时,以如下代码片段为例: HashMap<String,Object> m=new HashMap<String,Object>(); m.put("a", "rrr1"); m.put("b", "tt9"); m.put("c", "tt8"); m.put("d", "g7"); m.put("e", "d6"); m.put("f", "d4"); m.put("g", "d4"); m.put("h", "d3"); m.put("i", "d2"); m.put("j", "d1"); m.put("k", "1"); m.put("o", "2"); m.put("p", "3"); m.put("q", "4"); m.put("r", "5"); m.put("s", "6"); m.put("t", "7"); m.put("u", "8"); m.put("v", "9"); HashMap 采用一种所谓的“Hash 算法”来决定每个元素的存储位置。 当 程序执行 map.put(String,Obect)方法 时,系统将调用String的

java HashMap、HashTable、ConcurrentHashMap区别

一笑奈何 提交于 2020-02-28 12:22:39
HashTable 底层数组+链表实现,无论key还是value都 不能为null ,线程 安全 ,实现线程安全的方式是在修改数据时锁住整个HashTable,效率低,ConcurrentHashMap做了相关优化 初始size为 11 ,扩容:newsize = olesize*2+1 计算index的方法:index = (hash & 0x7FFFFFFF) % tab.length Hashtable的enumerator迭代器不是fail-fast HashMap 底层数组+链表实现,可 以存储null键和null值 ,线程 不安全 初始size为 16 ,扩容:newsize = oldsize*2,size一定为2的n次幂 扩容针对整个Map,每次扩容时,原来数组中的元素依次重新计算存放位置,并重新插入 当Map中元素总数超过Entry数组的75%,触发扩容操作,为了减少链表长度,元素分配更均匀 HashMap的迭代器(Iterator)是fail-fast迭代器 在HashMap中,null可以作为键,这样的键只有一个,但可以有一个或多个键所对应的值为null。 当get()方法返回null值时,即可以表示HashMap中没有该key,也可以表示该key所对应的value为null 。因此,在HashMap中不能由get(

hashMap与concurrentHashMap

杀马特。学长 韩版系。学妹 提交于 2020-02-28 12:22:30
一 功能简介 hashMap与concurrentHashMap 都属于集合,用于存储键值对数据,它两最明显的区别是,hashMap是非线程安全的,concurrentHashMap是线程安全的, concunrrentHashMap还有另外的称呼,如 并发容器 概述 HashMap jdk 1.7 实现方式:底层 数组+链表 jdk 1.8 实现方式:底层 数组+链表+红黑树 初始大小:16 负载因子:0.75 扩容:newSize = oldSize*2; map中元素总数超过Entry数组的75%,触发扩容操作 存放键值对要求:key 和 value 都允许为null,这种key只能有1个 线程安全性:不安全 父类:AbstractMap ConcurrentHashMap jdk 1.7 实现方式:底层 segment数组 + hashEntry数组+链表 segment 数组初始化:在申明 ConcurrentHashMap对象的时候 jdk 1.8 实现方式:底层 node数组+链表+红黑树 node数组初始化:put()第一个元素的时候 默认初始大小 16 负载因子:0.75 线程安全 父类 AbstractMap 二 实现逻辑 2.1 hashMap的内部实现逻辑 JDK1.7 hashmap 里面是一个数组,数组中每个元素是一个Entry类型的实例

1290. 二进制链表转整数

最后都变了- 提交于 2020-02-28 10:38:29
给你一个单链表的引用结点 head。链表中每个结点的值不是 0 就是 1。已知此链表是一个整数数字的二进制表示形式。 请你返回该链表所表示数字的 十进制值 。 示例 1: 输入:head = [1,0,1] 输出:5 解释:二进制数 (101) 转化为十进制数 (5) 示例 2: 输入:head = [0] 输出:0 提示: 链表不为空。 链表的结点总数不超过 30。 每个结点的值不是 0 就是 1。 /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public : int getDecimalValue ( ListNode * head ) { vector < int > arr ; while ( head != NULL ) { arr . push_back ( head - > val ) ; head = head - > next ; } int num = 0 ; for ( int i = arr . size ( ) - 1 ; i >= 0 ; i -- ) { if ( arr [ i ] =

线性表 - 双链表

[亡魂溺海] 提交于 2020-02-28 07:45:49
线性表 - 单链表 、 线性表 - 顺序存储结构 双向链表(double linked list):在单链表的每个结点中,再设置一个指向其前驱结点的指针域 view source print ? 01 /// <summary> 02 /// 定义双向链表结点类 03 /// </summary> 04 public sealed class DoubleLinkedListNode<t> 05 { 06 //存放数据 07 private T tData; 08 //后继结点 09 private DoubleLinkedListNode<t> nNext; 10 //前继结点 11 private DoubleLinkedListNode<t> nPrev; 12 13 public T Data 14 { 15 get { return this .tData; } 16 set { this .tData = value; } 17 } 18 public DoubleLinkedListNode<t> Next 19 { 20 get { return this .nNext; } 21 set { nNext = value; } 22 } 23 public DoubleLinkedListNode<t> Prev 24 { 25 get { return this

链表之链表的基本操作

空扰寡人 提交于 2020-02-28 07:42:37
链表的基本操作 链表的基本操作包括创建、销毁、插入、删除、查找、打印。这里附上代码: list.h typedef struct Node { int data; Node *next; } PNode; typedef struct List{ Node head; Node *last; } List; void list_init(List *list); void list_destroy(List *list); void list_insert(List *list,int data); void list_erase(List *list,int data); Node * list_find(List *list,int data); void list_print(List *list); int get_list_max(List *list); int get_list_count(List *list); int get_list_min(List *list); list.c #include "list.h"; #include <stdio.h>; #include<stdlib.h>; void list_init(List *list){ Node node; node.data=0; node.next=NULL; list->head=node

趣味编程:函数式链表的快速排序

这一生的挚爱 提交于 2020-02-28 07:04:07
前一段时间有朋友问我,以下这段Haskell快速排序的代码,是否可以转化成C#中等价的Lambda表达式实现: qsort [] = [] qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs) 我当时回答,C#中缺少一些基础的数据结构,因此不行。经过补充之后,就没有任何问题了。后来,我觉得这个问题挺有意思,难度适中,也挺考察“基础编程”能力的,于是就自己写了一个。如果您感兴趣的话,也不妨一试。 这段代码是经典的,常用的体现“函数式编程”省时省力的例子,用短短两行代码实现了一个快速排序的确了不起。您可能不了解Haskell,那么我在这里先解释一下。 首先,这里用到了函数式编程语言中最常用的一种数据结构:不可变的链表。这个数据结构事实上是一个单向链表,并且是“不可变”的。这种数据结构在F#中也有存在,它的结构用大致是这样的: 可见,这是一种递归的数据结构。如果我们把这种数据结构叫做是ImmutableList的话,那么每个ImmutableList对象就会包含一个元素的“值”,以及另一个ImmutableList对象(在上图中,每个框就是一个ImmutableList对象)。对于每个ImmutableList对象来说,这个“值”便是它的“头(Head)”

双向链表数据结构

我与影子孤独终老i 提交于 2020-02-28 04:17:50
一. 认识双向链表 双向链表介绍 单向链表: 只能从头遍历到尾或者从尾遍历到头(一般从头到尾) 也就是链表相连的过程是单向的. 实现的原理是上一个链表中有一个指向下一个的引用. 单向链表有一个比较明显的缺点: 我们可以轻松的到达下一个节点, 但是回到钱一个节点是很难的. 但是, 在实际开发中, 经常会遇到需要回到上一个节点的情况 举个例子: 假设一个文本编辑用链表来存储文本. 每一行用一个String对象存储在链表的一个节点中. 当编辑器用户向下移动光标时, 链表直接操作到下一个节点即可. 但是当用于将光标向上移动呢? 这个时候为了回到上一个节点, 我们可能需要从first开始, 依次走到想要的节点上. 双向链表 既可以从头遍历到尾, 又可以从尾遍历到头 也就是链表相连的过程是双向的. 那么它的实现原理, 你能猜到吗? 一个节点既有向前连接的引用, 也有一个向后连接的引用. 双向链表可以有效的解决单向链表中提到的问题. 双向链表有什么缺点呢? 每次在插入或删除某个节点时, 需要处理四个节点的引用, 而不是两个. 也就是实现起来要困难一些 并且相当于单向链表, 必然占用内存空间更大一些. 但是这些缺点和我们使用起来的方便程度相比, 是微不足道的. 双向连接的图解: img 双向链表的创建 我们来创建一个双向链表的类 // 创建双向链表的构造函数 function

LeetCode刷题笔记 234

╄→гoц情女王★ 提交于 2020-02-28 03:37:25
题目:回文链表 请判断一个链表是否为回文链表。 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶: 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题? 答案: 1.用快慢指针向后遍历,同时翻转链表的前半部分,然后与链表后半部分进行比较 快指针走到最后时,慢指针走到中间节点,边走边翻转链表前半部分。 class Solution { public boolean isPalindrome ( ListNode head ) { if ( head == null || head . next == null ) return true ; ListNode p = null , pre = null ; ListNode fast = head , slow = head ; while ( fast != null && fast . next != null ) { p = slow ; slow = slow . next ; //快慢遍历 fast = fast . next . next ; p . next = pre ; //翻转 pre = p ; } if ( fast != null ) { //奇数个节点时跳过中间节点 slow = slow . next ; } while ( p