链表

Java8新特性之引导篇----为什么速度更快

我与影子孤独终老i 提交于 2020-02-10 17:33:26
为什么要学习java8新特性? 简单而言就是使一个程序员的代码更加简洁高效,这也是语言发展的必然性,当然我这样说太笼统了,所以我特意去网上找了一张图,相信这张图就很能说明问题了。 何来速度更快? 为什么说java8速度更快呢?因为它对底层的数据结构做了改动,对垃圾回收机制(内存结构)做了改变,对并行做了一个扩展和支持,当然还有一些小的改动就不一一例举了。 数据结构的改变 最典型的就是HashMap,说到它就不得不说一下哈希表了,相信作为程序员大部分应该都知道,HashMap底层其实就是一个链表,说白了就是类似于一个数组+链表的结构(当然它还多了其它东西,嘿嘿,想知道你就得去看看HashMap详解了),然后根据索引来放你想存放的东西,而这个索引是怎么产生的呢,就是通过哈希算法产生的,所以说这一下就提高了多少的运算效率呢,如果没有它,你要放一个新元素去这个数组中,它就需要和数组中已经存在的每一个元素进行一次比较,但有了哈希表后,你每次放一个新元素,只需要计算这个新元素的哈希值,然后通过哈希值找到这个数组的索引,然后往这索引的位置插入就可以了,这样是不是就只需要比较一次了呢。 当然废了这么多话,还没说到HashMap在java7和java8中的区别(坐下,放下你手中的40米大刀),那么,你想下,每次计算到相同的hash值,新的值会代替老的值,那么它是怎么插入的呢(懂得已经懂了,嘿嘿)

剑指offer---从尾到头打印链表

浪子不回头ぞ 提交于 2020-02-10 14:03:39
输入一个链表,按链表从尾到头的顺序返回一个ArrayList。 #!/usr/bin/env python # _*_ coding:utf-8 _*_ class ListNode : def __init__ ( self , x ) : self . val = x self . next = None # #方法一简单列表保存输出 # class Solution: # # 返回从尾部到头部的列表值序列,例如[1,2,3] # def printListFromTailToHead(self, listNode): # # write code here # new_list = [] # while listNode: # new_list.append(listNode) # listNode = listNode.next # return [i.val for i in new_list[::-1]] #方法二 递归 class Solution : # 返回从尾部到头部的列表值序列,例如[1,2,3] def printListFromTailToHead ( self , listNode ) : res = [ ] def printNode ( listNode ) : if listNode : printNode ( listNode . next )

Leetcode160.相交链表(C语言)

我的梦境 提交于 2020-02-10 13:06:31
Leetcode160.相交链表(C语言) 数据结构-链表: 算法与数据结构参考 题目: 例如以下示例中 A 和 B 两个链表相交于 c1: 若存在则返回c1,如果不存在交点则返回 null。 要求时间复杂度为 O(N),空间复杂度为 O(1)。 思路: 使得A,B两个链表剩下的长度相同,再进行逐个比较找出交点。 A,B各自长度未知,重点在于长度的处理 代码: /** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) { if(headA==NULL || headB==NULL) return NULL; int lena,lenb; struct ListNode *p=headA; struct ListNode *q=headB; for(lena=0;p=p->next;lena++); for(lenb=0;q=q->next;lenb++); int diff=lena-lenb; //计算两个链表的长度差 while(diff>0){ headA

jdk8 hashmap 链表resize 源码分析

妖精的绣舞 提交于 2020-02-10 10:52:17
重点看这部分代码 for (int j = 0; j < oldCap; ++j) { Node<K,V> e; if ((e = oldTab[j]) != null) { oldTab[j] = null; if (e.next == null) newTab[e.hash & (newCap - 1)] = e; else if (e instanceof TreeNode) ((TreeNode<K,V>)e).split(this, newTab, j, oldCap); else { // preserve order Node<K,V> loHead = null, loTail = null; Node<K,V> hiHead = null, hiTail = null; Node<K,V> next; do { next = e.next; if ((e.hash & oldCap) == 0) { if (loTail == null) loHead = e; else loTail.next = e; loTail = e; } else { if (hiTail == null) hiHead = e; else hiTail.next = e; hiTail = e; } } while ((e = next) != null); if (loTail !

LeetCode19 移除倒数第N个元素

混江龙づ霸主 提交于 2020-02-10 08:43:28
链接 Remove Nth Node From End of List 难度 Medium 描述 Given a linked list, remove the n -th node from the end of list and return its head. 给定一个链表,要求移除导数第n个元素,并且返回新链表的head 样例: Given linked list: **1- >2->3->4->5**, and **_n_ = 2**. After removing the second node from the end, the linked list becomes **1- >2->3->5**. 注意: Given n will always be valid. 给定的n永远有效 Follow up: Could you do this in one pass? 你能一发通过么???官方嘲讽。 题解 题目的意思非常直白,不需要太多思考就能理解。但是上手去做的话会有一点小问题,因为如果是数组很好办,我们直接可以求到数组的长度,导数第N个元素也非常容易确定。但是如果是链表的话就不同了,因为我们并不知道链表的长度,所以没办法直接获取需要删除节点的位置。 既然直接没有办法求到,那么可以间接去求嘛,所以很自然地可以想到两次遍历的方法。 两次遍历 这个方法非常直观

数组

ⅰ亾dé卋堺 提交于 2020-02-10 04:27:23
1.List接口 ArrayList(查询快,增删慢,查询快)    内部通过数组实现,当数组大小不满足时需要增加存储能力,将已有的数组的数据复制到新的存储空间,当插入或者删除元素时候,需要对数组进行复制移动,代价高,   默认容量时10,扩容1.5倍 Vector(数组实现,线程同步)   支持线程同步,即某一时刻只有一个线程能够写vector,因为访问比ArrayList慢 LinkList(双链表结构,增删慢,查询快)    不支持高效的随机元素访问,LinkedList 是一个实现了 List 接口和 Deque 接口的双端链表。使得 LinkedList 类也具有队列的特性; LinkedList 不是线程安全的,如果想使   LinkedList 变 成 线 程 安 全 的 , 可 以 调 用 静 态 类 Collections 类 中 的 synchronizedList 方 法 : List list=Collections.synchronizedList(new LinkedList(...)); 2.Set接口     hashCode存储,如果想让两个不同的对象相等,必须覆盖object的hashCode方法和equals方法 HashSet(无序,哈希表)    按照哈希值存取数据,通过hashcode方法来获取,HashSet首先判断两个元素的哈希值

线性数据结构案例4 —— 合并两个有序的单链表 合并之后依然有序

我与影子孤独终老i 提交于 2020-02-10 01:38:04
一、介绍 emsp; 我们定义一个新链表然后,将两个链表的元素依次比较,放入比较最小的放到新链表前面。 二、代码 public static Node mergeByOrder(Node l1, Node l2) { if(l1.next == null || l2.next == null) { return l1.next == null ? l2 : l1; } Node newLinkedHead = new Node(0, ""); l1 = l1.next; // 头节点没有数据我们不要 l2 = l2.next; // 头节点没有数据我们不要 Node temp = newLinkedHead; while (l1 != null && l2 != null) { if (l1.no <= l2.no) { temp.next = l1; temp = temp.next; l1 = l1.next; } else { temp.next = l2; temp = temp.next; l2 = l2.next; } } if (l1 == null) { temp.next= l2; // 连接剩余节点 } if (l2 == null) { temp.next= l1; // 连接剩余节点 } return newLinkedHead; } } 来源: https

java实现双向链表

心不动则不痛 提交于 2020-02-10 01:25:47
一 前言 之前知识知识追寻者写了一篇单链表的实现,感觉不是很满意,写的逻辑不够清晰,有些地方实现的不过好,不能连成一个整体,伪单链表;为此研究了一会双向链表的简单实现;本篇的实现方式是以方法的形式展现,读者可以将其整合为一个类; 二 双向链表简介 双向链表的定义是,一个节点有两个方向,分别储存当前节点的前驱节点,和后续节点;双向链表的删除只需要指定前驱节点,或者后续节点就可以进行删除操作;但是缺点也很明显每次添加节点时都需要2个指向,额外增加了内存空间消耗; 三 双向链表的实现 3.1 定义链表节点 定义data存储数据,知识追寻者使用的时int类型,读者可以改为object类型; 定义前驱节点previous 定义后续节点next /** * @Author lsc * <p> 双向链表节点 </p> */ public class DoubleNode { //数据 private Integer data; //后续节点节点 private DoubleNode next; //前驱节点 private DoubleNode previous; // 省略set get } 3.2 插入头节点 思路如下 将新节点的前驱节点指向nul 新节点的后续节点指向表头 将表头的前驱节点指向新节点 public class DoubleList { private DoubleNode

单链表反转方法之双指针遍历就地反转法

老子叫甜甜 提交于 2020-02-10 00:23:10
public class LinkedNode { Integer id; LinkedNode next; public LinkedNode(Integer id) { this.id = id; } // 打印链表 public void print(){ System.out.print(this.id); if (this.next != null) { System.out.print("->"); this.next.print(); } else { System.out.println(); } } } public class TestLinkedNode { public static void main(String[] args) { LinkedNode node1 = new LinkedNode(1); LinkedNode node2 = new LinkedNode(2); LinkedNode node3 = new LinkedNode(3); LinkedNode node4 = new LinkedNode(4); LinkedNode node5 = new LinkedNode(5); node1.next = node2; node2.next = node3; node3.next = node4; node4.next =

Threadx 系统定时器线程_tx_timer_thread_entry

点点圈 提交于 2020-02-09 23:42:49
“System Timer Thread” 系统定时器线程用于判断定时器超时,并调用定时器超时处理函数。 _tx_timer_initialize 先来看看定时器线程创建初始化。_tx_timer_initialize初始化系统一系列与时间,定时器相关全局变量,链表,线程等。 VOID _tx_timer_initialize ( VOID ) { REG_1 UINT i ; /* Working index variable */ REG_2 TX_INTERNAL_TIMER * * timer_ptr ; /* Working timer pointer */ UINT32 b_is_os_test = 0 ; /* Initialize the system clock to 0. */ #def 系统时钟,用于时间相关 _tx_timer_system_clock = 0 ; /* Initialize the time-slice value to 0 to make sure it is disabled. */ #def 初始化时间片全局变量,用于基于时间片的线程调度 _tx_timer_time_slice = 0 ; /* Clear the expired flags. */ #def 时间片耗尽标志 _tx_timer_expired_time_slice