链表

java源码学习---HashMap

橙三吉。 提交于 2020-02-25 19:07:46
开门见山,直接干 HashMap是java常用的一个集合,每个元素的key经过哈希算法后储存在链表或红黑树的一种键值对数据集合(JDK1.8) 从HashMap新增元素说起 map.put( "key" , "value" ); 这是我们日常向HashMap插入元素的其中一种方式,put(k,v)的源码 public V put( K key, V value) { return putVal( hash (key), key, value, false , true ); } put()会再调用一个putVal(),但是在这之前key会通过hash()计算出对应位置的值,真正的put操作,就是从这里开始 final V putVal( int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node< K , V >[] tab; Node< K , V > p; int n, i; if ((tab = table ) == null || (n = tab. length ) == 0 ) n = (tab = resize()). length ; if ((p = tab[i = (n - 1 ) & hash]) == null ) tab[i] = newNode(hash, key,

线性表之单向循环链表

喜欢而已 提交于 2020-02-25 18:59:24
一,循环链表的概念 1.什么是循环链表   所谓的循环链表就是让单向链表的首尾相连,组成一个环状。 2.循环链表的典型应用   约瑟夫环问题。 3.实现循环链表的重点   1,循环链表在插入第一个元素的时候,需要我们将第一元素的指针域指向其自身,也就构成了循环链表。   2,循环链表基于单向链表而生,单是比循环链表多了游标这个概念。要想实现循环链表的插入,删除的关键是考虑头结点问题,因为在头插法方式(往链表的头部插入数据)中,需要将末尾数据元素的指针域指向新插入的节点。将新插入的节点的指针域指向头结点的指针域的指针域,还需要将头结点指向新插入的结点。(插入相同)。 二,循环链表新增概念和功能 1,什么是游标   所谓的游标就是在链表中可以移动的指针,游标初始化一般是指向链表的第一个结点。 2,游标的功能 初始化游标 移动游标:将移动前的游标所对应得结点返回,并将游标指向下一个数据元素。 获取游标:获取当前游标所对应得数据元素 删除游标:删除当前游标所对应得数据元素,并将游标指向下一个数据元素。 三,循环链表的实现 1,循环链表的功能 # ifndef CIRCLE_LINK_LIST # define CIRCLE_LINK_LIST /* 业务节点 */ typedef void Node; /* 链表节点(被包含) */ typedef struct CircleNode {

两个链表的第一个公共结点

旧巷老猫 提交于 2020-02-25 15:51:11
题目描述: 输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的) 代码描述: /* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ public class Solution { public ListNode FindFirstCommonNode ( ListNode pHead1 , ListNode pHead2 ) { if ( pHead1 == null || pHead2 == null ) { return null ; } ListNode p1 = pHead1 ; ListNode p2 = pHead2 ; while ( p1 != p2 ) { p1 = p1 . next ; p2 = p2 . next ; if ( p1 != p2 ) { //若其中某个链表的指针已经遍历为null,则把该指针指向另一链表的头结点,较长链表也到null时也指正指向另一链表头结点。如此一来两个链表的遍历就是同步状态,继续遍历还是没有共同节点的话,最后结果就是同是指向两个链表的尾部null,循环结束。 if ( p1 == null ) p1 =

快慢指针实现不依赖计数器寻找中位数(linked list)

夙愿已清 提交于 2020-02-25 12:33:19
该方法在不借助 计数器 变量实现寻找中位数的功能。原理是:快指针的移动速度是慢指针移动速度的2倍,因此当快指针到达 链表 尾时,慢指针到达中点。程序还要考虑链表结点个数的奇偶数因素,当快指针移动x次后到达表尾(1+2x),说明链表有奇数个结点,直接返回慢指针指向的数据即可。如果快指针是倒数第二个结点,说明链表结点个数是偶数,这时 可以 根据 “规则”返回上中位数或下中位数或(上中位数+下中位数)的一半。 while (fast&&slow)   {   if (fast->next==NULL)   return slow ->data;   else if (fast->next!= NULL && fast->next->next== NULL)   return (slow ->data + slow ->next->data)/2;   else   {   fast= fast->next;   fast= fast->next;   slow = slow ->next;   }   } 来源: https://www.cnblogs.com/mdz-great-world/p/6549816.html

第二次作业--线性表

大憨熊 提交于 2020-02-25 11:47:27
一、PTA实验作业 本周要求挑3道题目写设计思路、调试过程。设计思路用伪代码描述。题目选做要求: 顺序表选择一题(6-2,6-3,7-1选一题),代码必须用顺序结构抽象数据类型封装 单链表选择一题(6-1不能选) 有序表选择一题 题目: 6-3 jmu-ds- 顺序表删除重复元素(25 分) 设计一个算法,从顺序表中删除重复的元素,并使剩余元素间的相对次序保存不变 设计思路: int i=0,j=0,k; 先定义三个计数下标 for(i=0;i<L->length;i++){ j=i+1; 让j始终比i大1,才能让两个相邻的数比较 while(j<L->length){ if(L->data[i]==L->data[j]){ 判断相邻两个数是否相等 for(k=j;k<L->length-1;k++){ L->data[k]=L->data[k+1]; 如果相等让下标为J的数等与j+1然后在与下标为i的数相比 } L->length--; 如果有相等的就表长减一 } else j++; } } 代码截图: PTA测试结果 ; 6-3 jmu-ds-链表倒数第m个数(20 分) 已知一个带有表头节点的单链表,查找链表中倒数第m个位置上的节点 设计思路: int Find(LinkList L, int m ) { LinkList p; p=L;

邻接表(数组实现)

假装没事ソ 提交于 2020-02-25 05:11:11
之前我们介绍过图的邻接矩阵存储法,它的空间和时间复杂度都是N2,现在我来介绍另外一种存储图的方法:邻接表,这样空间和时间复杂度就都是M。对于稀疏图来说,M要远远小于N2。先上数据,如下。 4 5 1 4 9 4 3 8 1 2 5 2 4 6 1 3 7 第一行两个整数n m。n表示顶点个数(顶点编号为1~n),m表示边的条数。接下来m行表示,每行有3个数x y z,表示顶点x到顶点y的边的权值为z。下图就是一种使用链表来实现邻接表的方法。 上面这种实现方法为图中的每一个顶点(左边部分)都建立了一个单链表(右边部分)。这样我们就可以通过遍历每个顶点的链表,从而得到该顶点所有的边了。使用链表来实现邻接表对于痛恨指针的的朋友来说,这简直就是噩梦。这里我将为大家介绍另一种使用数组来实现的邻接表,这是一种在实际应用中非常容易实现的方法。这种方法为每个顶点i(i从1~n)也都保存了一个类似“链表”的东西,里面保存的是从顶点i出发的所有的边,具体如下。 首先我们按照读入的顺序为每一条边进行编号(1~m)。比如第一条边“1 4 9”的编号就是1,“1 3 7”这条边的编号是5。 这里用u、v和w三个数组用来记录每条边的具体信息,即u[i]、v[i]和w[i]表示第i条边是从第u[i]号顶点到v[i]号顶点(u[i]àv[i]),且权值为w[i]。

巧妙的邻接表(数组实现)

别等时光非礼了梦想. 提交于 2020-02-25 05:08:55
之前我们介绍过图的邻接矩阵存储法,它的空间和时间复杂度都是N2,现在我来介绍另外一种存储图的方法:邻接表,这样空间和时间复杂度就都是M。对于稀疏图来说,M要远远小于N2。先上数据,如下。 4 51 4 94 3 81 2 52 4 61 3 7 第一行两个整数n m。n表示顶点个数(顶点编号为1~n),m表示边的条数。接下来m行表示,每行有3个数x y z,表示顶点x到顶点y的边的权值为z。下图就是一种使用链表来实现邻接表的方法。 上面这种实现方法为图中的每一个顶点(左边部分)都建立了一个单链表(右边部分)。这样我们就可以通过遍历每个顶点的链表,从而得到该顶点所有的边了。使用链表来实现邻接表对于痛恨指针的的朋友来说,这简直就是噩梦。这里我将为大家介绍另一种使用数组来实现的邻接表,这是一种在实际应用中非常容易实现的方法。这种方法为每个顶点i(i从1~n)也都保存了一个类似“链表”的东西,里面保存的是从顶点i出发的所有的边,具体如下。 首先我们按照读入的顺序为每一条边进行编号(1~m)。比如第一条边“1 4 9”的编号就是1,“1 3 7”这条边的编号是5。 这里用u、v和w三个数组用来记录每条边的具体信息,即u[i]、v[i]和w[i]表示第i条边是从第u[i]号顶点到v[i]号顶点(u[i]àv[i]),且权值为w[i]。 再用一个first数组来存储每个顶点其中一条边的编号

L2-002 链表去重

久未见 提交于 2020-02-25 01:52:01
L2-002 链表去重 给定一个带整数键值的链表 L,你需要把其中 绝对值 重复的键值结点删掉。即对每个键值 K,只有第一个绝对值等于 K 的结点被保留。同时,所有被删除的结点须被 保存在另一个链表上 。例如给定 L 为 21→-15→-15→-7→15,你需要输出去重后的链表 21→-15→-7,还有被删除的链表 -15→15。 输入格式 输入在第一行给出 L 的第一个结点的地址和一个正整数 N(≤10 5 ,为结点总数)。一个结点的地址是非负的 5 位整数,空地址 NULL 用 −1 来表示。 随后 N 行,每行按以下格式描述一个结点: 地址 键值 下一个结点 其中 地址 是该结点的地址, 键值 是绝对值不超过10 4 ​ 的整数, 下一个结点 是下个结点的地址。 输出格式 首先输出去重后的链表,然后输出被删除的链表。 每个结点占一行 ,按输入的格式输出。 输入样例 00100 5 99999 -7 87654 23854 -15 00000 87654 15 -1 00000 -15 99999 00100 21 23854 输出样例 00100 21 23854 23854 -15 99999 99999 -7 -1 00000 -15 87654 87654 15 -1 # include <iostream> # include <cstdio> # include

LinkedList-5

最后都变了- 提交于 2020-02-25 01:34:33
LinkedList 适用于集合元素先入先出和先入后出的场景,在队列源码中被频繁使用. LinkedList 底层数据结构是一个双向链表,整体结构如下图所示: 我们有几个概念如下: 链表每个节点我们叫做 Node,Node 有 prev 属性,代表前一个节点的位置,next 属性,代表后一个节点的位置; first 是双向链表的头节点,它的前一个节点是 null。 last 是双向链表的尾节点,它的后一个节点是 null。 当链表中没有数据时,first 和 last 是同一个节点,前后指向都是 null。 Node 的组成部分: private static class Node<E> { E item;// 节点值 Node<E> next; // 指向的下一个节点 Node<E> prev; // 指向的前一个节点 // 初始化参数顺序分别是:前一个节点、本身节点值、后一个节点 Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } } 1.追加(新增) 追加节点时,我们可以选择追加到链表头部,还是追加到链表尾部,add 方法默认是从尾部开始追加,addFirst 方法是从头部开始追加,我们分别来看下两种不同的追加方式:

数据结构与算法常见面试题1

烈酒焚心 提交于 2020-02-24 20:22:00
1.八大数据结构及其应用场景(数组、栈、链表、树、图、堆、散列表) 1.数组 数据结构中最基本的一个结构就是线性结构,而线性结构又分为连续存储结构和离散存储结构。连续存储结构其实就是数组。 在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类数据元素的集合称为数组。一个数组可以分解为多个数组元素,这些数组元素可以是基本数据类型或是构造类型。因此按数组元素的类型不同,数组又可分为数值数组、字符数组、指针数组、结构数组等各种类别。 使用场景 数组在以下三个情形下很有用: 1)数据量较小。 2)数据规模已知。 3)随机访问,修改元素值。 如果插入速度很重要,选择无序数组。如果查找速度很重要,选择有序数组,并使用二分查找。 缺点 1)需要预先知道数据规模 2)插入效率低,因为需要移动大量元素。 2.栈 是只能在某一端插入和删除的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。 使用场景 1.十进制与其它进制间的转换 125→1111111 2.行编辑器 #退格 @清除 3.平衡符号的判断 {[()()]} 4.中缀表达式转后缀表达式 顺序栈 优点 1)在输入数据量可预知的情形下,可以使用数组实现栈,并且数组实现的栈效率更高