Java数据结构第三个-链表-单链表
数据结构-单链表
一、介绍
链表是有序的列表,但是它在内存中是存储如下:
小结:
- 链表是以节点的方式来存储,是链式存储。
- 每个节点包含 data 域, next 域:指向下一个节点。
- 如上图:发现链表的的next存放的是下一个节点的地址,所以各个节点不一定是连续存储。
- 链表分带头节点的链表和没有头节点的链表,根据实际的需求来确定。
二、单链表介绍
1.逻辑结构
单链表(带头结点) 逻辑结构示意图如下:
2.具体应用
任务要求:使用带head(头结点)的单向链表实现 – 水浒英雄排行榜管理
- 完成对英雄人物的增(头插、尾插、按顺序插)删改查操作
- 求单链表中有效节点的个数
- 查找单链表中的倒数第k个结点
- 单链表的反转
- 从尾到头打印单链表
- 合并两个有序的单链表,合并之后的链表依然有序
代码实现:
核心实现:
创建HeroNode类,用来充当节点,类中属性包括:id(排名),name(姓名),nickName(花名),next(指向下一个节点的域)
创建类SingleLinkedList,里面维护一个头结点,该类具备对节点的增删查改功能
代码实现:
public class HeroNode {private Integer id;private String name;private String nickName;private HeroNode next;public HeroNode(Integer id, String name, String nickName) {this.id = id;this.name = name;this.nickName = nickName;}public HeroNode(Integer id, String name, String nickName, HeroNode next) {this.id = id;this.name = name;this.nickName = nickName;this.next = next;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getNickName() {return nickName;}public void setNickName(String nickName) {this.nickName = nickName;}public HeroNode getNext() {return next;}public void setNext(HeroNode next) {this.next = next;}@Overridepublic String toString() {return "HeroNode{" +"id=" + id +", name='" + name + '\'' +", nickName='" + nickName + '\'' +'}';} }
public class SingleLinkedList {/*** 维护一个空节点头部*/HeroNode head = new HeroNode(0,"","",null);public SingleLinkedList() {}/*** 获取头结点*/ public HeroNode getHead() {return head;}public void setHead(HeroNode head) {this.head = head;} }
其它功能实现:
完成对英雄人物的增(头插、尾插、按顺序插)删改查操作
具体代码:
/*** 尾插法插入数据* 思路分析:找到节点的最后一个元素,将待插入的节点插入到后面* @param heroNode 待插入节点*/public void addToTail(HeroNode heroNode){//由于头结点不能移动,创建移动指针HeroNode pMove = head;//遍历到最后while (pMove.getNext() != null){pMove = pMove.getNext();}//添加pMove.setNext(heroNode);}/*** 头插法插入数据* 思路分析:待插入节点连接头节点的下一个,头结点连接待插入节点* @param heroNode 待插入节点*/public void addToHead(HeroNode heroNode){//让加入节点的后面接上头结点的后面heroNode.setNext(head.getNext());//头结点的后面介绍添加的节点head.setNext(heroNode);}/*** 按顺序插入数据* 思路分析:找打待插入节点的位置,位置是该节点的前一个位置* @param heroNode 待插入节点*/public void addByOrderAsc(HeroNode heroNode){//由于头结点不能移动,创建移动指针HeroNode pMove = head;//定义辅助遍历,找到需要添加的前一个节点boolean flag = false;//遍历到最后while (true){//到了链表尾部if (pMove.getNext() == null){break;}//if (pMove.getNext().getId() > heroNode.getId()){break;}else if (pMove.getNext().getId().equals(heroNode.getId())){flag = true;break;}pMove = pMove.getNext();}if (flag){System.out.println("该节点编号"+heroNode.getId()+"已存在,无法插入");}else {//添加heroNode.setNext(pMove.getNext());pMove.setNext(heroNode);}}/*** 删除指定编号的节点* 思路分析:找到需要删除元素的前一个节点* @param id 编号*/public void remove(Integer id){if (head.getNext() == null){System.out.println("无法删除,链表为空!!!");return;}//由于头结点不能移动,创建移动指针HeroNode pMove = head;//定义辅助遍历,找到需要删除的前一个节点boolean flag = false;while (true){//找到链表尾部还找不到,没有该节点if (pMove.getNext() == null){break;}//找到了if (pMove.getNext().getId().equals(id)){flag = true;break;}//找不到,指针后移pMove = pMove.getNext();}if (flag){pMove.setNext(pMove.getNext().getNext());}else {System.out.println("无法删除,该节点编号"+id+"不存在");}}/*** 修改节点的内容,不修改编号* @param heroNode 待修改节点*/public void update(HeroNode heroNode){if (head.getNext() == null){System.out.println("无法修改,链表为空!!!");return;}//由于头结点不能移动,创建移动指针HeroNode pMove = head.getNext();//定义辅助遍历,找到需要修改的前一个节点boolean flag = false;while (true){//找到链表尾部还找不到,没有该节点if (pMove == null){break;}//找到了if (pMove.getId().equals(heroNode.getId())){flag = true;break;}//找不到,指针后移pMove = pMove.getNext();}if (flag){pMove.setName(heroNode.getName());pMove.setNickName(heroNode.getNickName());}else {System.out.println("无法修改,该节点编号"+heroNode.getId()+"不存在");}}/*** 获取链表长度* @return 长度*/public int size(){if (head.getNext() == null){return 0;}int len = 0;HeroNode pMove = head.getNext();while (pMove != null){len++;pMove = pMove.getNext();}return len;}/*** 查找节点* @param index 待查找的索引* @return 返回找到的节点*/public HeroNode select(Integer index){if (index <= 0 || index > size()){System.out.println("索引越界");return null;}//由于头结点不能移动,创建移动指针HeroNode pMove = head.getNext();boolean flag = false;//遍历到最后while (pMove != null){if (pMove.getId().equals(index)){flag = true;break;}pMove = pMove.getNext();}if (flag){return pMove;}else {return null;}}public HeroNode get(int index){if (index <= 0 || index > size()){return null;}HeroNode pMove = head.getNext();for (int i = 1; i < index; i++) {pMove = pMove.getNext();}pMove.setNext(null);return pMove;}
效果图:
求单链表中有效节点的个数
具体代码:
/*** 获取链表长度* @return 长度*/public int size(){if (head.getNext() == null){return 0;}int len = 0;HeroNode pMove = head.getNext();while (pMove != null){len++;pMove = pMove.getNext();}return len;}
效果图:
查找单链表中的倒数第k个结点
具体代码:
/*** 找到单链表的倒数第index节点* @param index 倒数第index* @return 找到的节点*/public HeroNode findLastIndexHeroNode(Integer index){//判断范围if (index <= 0 || index > size()){System.out.println("索引越界");return null;}//遍历找到范围HeroNode pMove = head.getNext();for (int i = 0; i < size() - index; i++) {pMove = pMove.getNext();}return pMove;}
效果图:
单链表的反转
具体代码:
/*** 单链表的反转* @param*/public void reverse(HeroNode head){//如果链表为空或者只有一个元素,无需反转if (head.getNext() == null || head.getNext().getNext() == null){return;}//定义一个新链表的头HeroNode newHead = new HeroNode(0,"","",null);//定义一个指针指向原头节点,另一个指针指向原头结点的下一个HeroNode pMove = head.getNext();HeroNode pMoveNext = null;while (pMove != null){pMoveNext = pMove.getNext();pMove.setNext(newHead.getNext());newHead.setNext(pMove);pMove = pMoveNext;}head.setNext(newHead.getNext());}
效果图:
从尾到头打印单链表
具体代码:
/*** 反向遍历单链表* 方法一:使用递归 * 方法二:创建新链表,反向,再遍历如上反向链表*/public void reverseTraverse(){if (head.getNext() == null){System.out.println("无法遍历,链表为空!!!");return;}HeroNode pMove = head.getNext();findNext(pMove);}private void findNext(HeroNode pMove) {if (pMove != null){findNext(pMove.getNext());System.out.println(pMove);}else {return;}}
效果图:
合并两个有序的单链表,合并之后的链表依然有序
具体代码:
/*** 合并两个单链表,返回的链表依然有序* @param s1 单链表1* @param s2 单链表2*/public static SingleLinkedList mergeSingleLinkedList(SingleLinkedList s1,SingleLinkedList s2){SingleLinkedList linkedList = new SingleLinkedList();HeroNode tmp = linkedList.getHead();HeroNode tmp1 = s1.getHead().getNext();HeroNode tmp2 = s2.getHead().getNext();while (tmp1 != null && tmp2 != null){if (tmp1.getId() < tmp2.getId()){tmp.setNext(tmp1);tmp1 = tmp1.getNext();}else if (tmp1.getId() > tmp2.getId()){tmp.setNext(tmp2);tmp2 = tmp2.getNext();}tmp = tmp.getNext();}if (tmp1 == null){tmp.setNext(tmp2);}if (tmp2 == null){tmp.setNext(tmp1);}return linkedList;}
效果图:
三、注意事项
- 重新HeroNode的toString方法不要加上next,不然会打出它之后的节点
四、全部代码
public class SingleLinkedList {/*** 维护一个空节点头部*/HeroNode head = new HeroNode(0,"","",null);public SingleLinkedList() {}/*** 尾插法插入数据* 思路分析:找到节点的最后一个元素,将待插入的节点插入到后面* @param heroNode 待插入节点*/public void addToTail(HeroNode heroNode){//由于头结点不能移动,创建移动指针HeroNode pMove = head;//遍历到最后while (pMove.getNext() != null){pMove = pMove.getNext();}//添加pMove.setNext(heroNode);}/*** 头插法插入数据* 思路分析:待插入节点连接头节点的下一个,头结点连接待插入节点* @param heroNode 待插入节点*/public void addToHead(HeroNode heroNode){//让加入节点的后面接上头结点的后面heroNode.setNext(head.getNext());//头结点的后面介绍添加的节点head.setNext(heroNode);}/*** 按顺序插入数据* 思路分析:找打待插入节点的位置,位置是该节点的前一个位置* @param heroNode 待插入节点*/public void addByOrderAsc(HeroNode heroNode){//由于头结点不能移动,创建移动指针HeroNode pMove = head;//定义辅助遍历,找到需要添加的前一个节点boolean flag = false;//遍历到最后while (true){//到了链表尾部if (pMove.getNext() == null){break;}//if (pMove.getNext().getId() > heroNode.getId()){break;}else if (pMove.getNext().getId().equals(heroNode.getId())){flag = true;break;}pMove = pMove.getNext();}if (flag){System.out.println("该节点编号"+heroNode.getId()+"已存在,无法插入");}else {//添加heroNode.setNext(pMove.getNext());pMove.setNext(heroNode);}}/*** 删除指定编号的节点* 思路分析:找到需要删除元素的前一个节点* @param id 编号*/public void remove(Integer id){if (head.getNext() == null){System.out.println("无法删除,链表为空!!!");return;}//由于头结点不能移动,创建移动指针HeroNode pMove = head;//定义辅助遍历,找到需要删除的前一个节点boolean flag = false;while (true){//找到链表尾部还找不到,没有该节点if (pMove.getNext() == null){break;}//找到了if (pMove.getNext().getId().equals(id)){flag = true;break;}//找不到,指针后移pMove = pMove.getNext();}if (flag){pMove.setNext(pMove.getNext().getNext());}else {System.out.println("无法删除,该节点编号"+id+"不存在");}}/*** 修改节点的内容,不修改编号* @param heroNode 待修改节点*/public void update(HeroNode heroNode){if (head.getNext() == null){System.out.println("无法修改,链表为空!!!");return;}//由于头结点不能移动,创建移动指针HeroNode pMove = head.getNext();//定义辅助遍历,找到需要修改的前一个节点boolean flag = false;while (true){//找到链表尾部还找不到,没有该节点if (pMove == null){break;}//找到了if (pMove.getId().equals(heroNode.getId())){flag = true;break;}//找不到,指针后移pMove = pMove.getNext();}if (flag){pMove.setName(heroNode.getName());pMove.setNickName(heroNode.getNickName());}else {System.out.println("无法修改,该节点编号"+heroNode.getId()+"不存在");}}/*** 获取链表长度* @return 长度*/public int size(){if (head.getNext() == null){return 0;}int len = 0;HeroNode pMove = head.getNext();while (pMove != null){len++;pMove = pMove.getNext();}return len;}/*** 查找节点* @param index 待查找的索引* @return 返回找到的节点*/public HeroNode select(Integer index){if (index <= 0 || index > size()){System.out.println("索引越界");return null;}//由于头结点不能移动,创建移动指针HeroNode pMove = head.getNext();boolean flag = false;//遍历到最后while (pMove != null){if (pMove.getId().equals(index)){flag = true;break;}pMove = pMove.getNext();}if (flag){return pMove;}else {return null;}}public HeroNode get(int index){if (index <= 0 || index > size()){return null;}HeroNode pMove = head.getNext();for (int i = 1; i < index; i++) {pMove = pMove.getNext();}pMove.setNext(null);return pMove;}/*** 找到单链表的倒数第index节点* @param index 倒数第index* @return 找到的节点*/public HeroNode findLastIndexHeroNode(Integer index){//判断范围if (index <= 0 || index > size()){System.out.println("索引越界");return null;}//遍历找到范围HeroNode pMove = head.getNext();for (int i = 0; i < size() - index; i++) {pMove = pMove.getNext();}return pMove;}/*** 遍历单链表*/public void traverse(){if (head.getNext() == null){System.out.println("无法遍历,链表为空!!!");return;}//由于头结点不能移动,创建移动指针HeroNode pMove = head.getNext();//遍历到最后while (pMove != null){System.out.println(pMove);pMove = pMove.getNext();}}/*** 反向遍历单链表*/public void reverseTraverse(){if (head.getNext() == null){System.out.println("无法遍历,链表为空!!!");return;}HeroNode pMove = head.getNext();findNext(pMove);}private void findNext(HeroNode pMove) {if (pMove != null){findNext(pMove.getNext());System.out.println(pMove);}else {return;}}/*** 合并两个单链表,返回的链表依然有序* @param s1 单链表1* @param s2 单链表2*/public static SingleLinkedList mergeSingleLinkedList(SingleLinkedList s1,SingleLinkedList s2){SingleLinkedList linkedList = new SingleLinkedList();HeroNode tmp = linkedList.getHead();HeroNode tmp1 = s1.getHead().getNext();HeroNode tmp2 = s2.getHead().getNext();while (tmp1 != null && tmp2 != null){if (tmp1.getId() < tmp2.getId()){tmp.setNext(tmp1);tmp1 = tmp1.getNext();}else if (tmp1.getId() > tmp2.getId()){tmp.setNext(tmp2);tmp2 = tmp2.getNext();}tmp = tmp.getNext();}if (tmp1 == null){tmp.setNext(tmp2);}if (tmp2 == null){tmp.setNext(tmp1);}return linkedList;}public static void nodeToString(HeroNode node){HeroNode currNode = node;while (currNode != null){System.out.println(currNode);currNode = currNode.getNext();}}/*** 单链表的反转* @param*/public void reverse(HeroNode head){//如果链表为空或者只有一个元素,无需反转if (head.getNext() == null || head.getNext().getNext() == null){return;}//定义一个新链表的头HeroNode newHead = new HeroNode(0,"","",null);//定义一个指针指向原头节点,另一个指针指向原头结点的下一个HeroNode pMove = head.getNext();HeroNode pMoveNext = null;while (pMove != null){pMoveNext = pMove.getNext();pMove.setNext(newHead.getNext());newHead.setNext(pMove);pMove = pMoveNext;}head.setNext(newHead.getNext());}public HeroNode getHead() {return head;}public void setHead(HeroNode head) {this.head = head;}
}
测试方法
public class SingleLinkedListTest {@Testpublic void addToTailTest(){SingleLinkedList singleLinkedList = new SingleLinkedList();HeroNode heroNode1 = new HeroNode(1,"宋江","及时雨");HeroNode heroNode2 = new HeroNode(2,"玉麒麟","卢俊义");HeroNode heroNode3 = new HeroNode(3,"吴用","吴用");HeroNode heroNode4 = new HeroNode(4,"入云龙","公孙胜");HeroNode heroNode5 = new HeroNode(5,"大刀","关胜");singleLinkedList.addToTail(heroNode1);singleLinkedList.addToTail(heroNode2);singleLinkedList.addToTail(heroNode3);singleLinkedList.addToTail(heroNode4);singleLinkedList.addToTail(heroNode5);singleLinkedList.traverse();}@Testpublic void addToHeadTest(){SingleLinkedList singleLinkedList = new SingleLinkedList();HeroNode heroNode1 = new HeroNode(1,"宋江","及时雨");HeroNode heroNode2 = new HeroNode(2,"玉麒麟","卢俊义");HeroNode heroNode3 = new HeroNode(3,"吴用","吴用");HeroNode heroNode4 = new HeroNode(4,"入云龙","公孙胜");HeroNode heroNode5 = new HeroNode(5,"大刀","关胜");singleLinkedList.addToHead(heroNode1);singleLinkedList.addToHead(heroNode2);singleLinkedList.addToHead(heroNode3);singleLinkedList.addToHead(heroNode4);singleLinkedList.addToHead(heroNode5);singleLinkedList.traverse();}@Testpublic void addByOrderAscTest(){SingleLinkedList singleLinkedList = new SingleLinkedList();HeroNode heroNode1 = new HeroNode(1,"宋江","及时雨");HeroNode heroNode2 = new HeroNode(2,"玉麒麟","卢俊义");HeroNode heroNode3 = new HeroNode(3,"吴用","吴用");HeroNode heroNode4 = new HeroNode(4,"入云龙","公孙胜");HeroNode heroNode5 = new HeroNode(5,"大刀","关胜");singleLinkedList.addByOrderAsc(heroNode1);singleLinkedList.addByOrderAsc(heroNode3);singleLinkedList.addByOrderAsc(heroNode4);singleLinkedList.addByOrderAsc(heroNode2);singleLinkedList.addByOrderAsc(heroNode2);singleLinkedList.traverse();}@Testpublic void removeAndUpdateTest(){SingleLinkedList singleLinkedList = new SingleLinkedList();HeroNode heroNode1 = new HeroNode(1,"宋江","及时雨");HeroNode heroNode2 = new HeroNode(2,"玉麒麟","卢俊义");HeroNode heroNode3 = new HeroNode(3,"吴用","吴用");HeroNode heroNode4 = new HeroNode(4,"入云龙","公孙胜");HeroNode heroNode5 = new HeroNode(5,"大刀","关胜");singleLinkedList.addByOrderAsc(heroNode1);singleLinkedList.addByOrderAsc(heroNode3);singleLinkedList.addByOrderAsc(heroNode4);singleLinkedList.addByOrderAsc(heroNode2);singleLinkedList.addByOrderAsc(heroNode2);singleLinkedList.traverse();System.out.println("删除:> ");singleLinkedList.remove(2);singleLinkedList.traverse();singleLinkedList.remove(1);singleLinkedList.remove(2);singleLinkedList.remove(3);singleLinkedList.remove(4);singleLinkedList.traverse();System.out.println("修改:> ");singleLinkedList.addByOrderAsc(heroNode1);singleLinkedList.addByOrderAsc(heroNode3);singleLinkedList.addByOrderAsc(heroNode4);singleLinkedList.traverse();singleLinkedList.update(new HeroNode(1,"文泰","奔雷手"));singleLinkedList.update(new HeroNode(2,"周杰伦","低唱小子"));System.out.println("修改后:> ");singleLinkedList.traverse();}@Testpublic void selectTest(){SingleLinkedList singleLinkedList = new SingleLinkedList();HeroNode heroNode1 = new HeroNode(1,"宋江","及时雨");HeroNode heroNode2 = new HeroNode(2,"玉麒麟","卢俊义");HeroNode heroNode3 = new HeroNode(3,"吴用","吴用");HeroNode heroNode4 = new HeroNode(4,"入云龙","公孙胜");HeroNode heroNode5 = new HeroNode(5,"大刀","关胜");singleLinkedList.addByOrderAsc(heroNode1);singleLinkedList.addByOrderAsc(heroNode3);singleLinkedList.addByOrderAsc(heroNode4);singleLinkedList.addByOrderAsc(heroNode2);singleLinkedList.addByOrderAsc(heroNode2);System.out.println("singleLinkedList.size() = " + singleLinkedList.size());singleLinkedList.traverse();HeroNode select = singleLinkedList.select(0);System.out.println("select = " + select);System.out.println("singleLinkedList.select(2) = " + singleLinkedList.select(2));System.out.println("singleLinkedList.findLastIndexHeroNode(1) = " + singleLinkedList.findLastIndexHeroNode(1));System.out.println("singleLinkedList.findLastIndexHeroNode(4) = " + singleLinkedList.findLastIndexHeroNode(4));System.out.println("singleLinkedList.findLastIndexHeroNode(5) = " + singleLinkedList.findLastIndexHeroNode(5));singleLinkedList.traverse();//System.out.println("反转:> ");//singleLinkedList.reverse(singleLinkedList.getHead());System.out.println("反向遍历:> ");singleLinkedList.reverseTraverse();}@Testpublic void mergeTest(){SingleLinkedList s1 = new SingleLinkedList();SingleLinkedList s2 = new SingleLinkedList();HeroNode heroNode1 = new HeroNode(1,"宋江","及时雨");HeroNode heroNode2 = new HeroNode(2,"玉麒麟","卢俊义");HeroNode heroNode3 = new HeroNode(3,"吴用","吴用");HeroNode heroNode4 = new HeroNode(4,"入云龙","公孙胜");HeroNode heroNode5 = new HeroNode(5,"大刀","关胜");s1.addByOrderAsc(heroNode1);s1.addByOrderAsc(heroNode3);System.out.println("s1:> ");s1.traverse();s2.addByOrderAsc(heroNode2);s2.addByOrderAsc(heroNode4);System.out.println("s2:> ");s2.traverse();System.out.println("linkedlist:> ");SingleLinkedList linkedList = SingleLinkedList.mergeSingleLinkedList(s1, s2);linkedList.traverse();}
}
Java数据结构第三个-链表-单链表相关推荐
- 数据结构(三)之单链表反向查找
一.反向查找单链表 1.简单查找 先遍历获取单链表单长度n,然后通过计算得到倒数第k个元素的下标为n-k,然后查找下标为n-k的元素. 2.优化查找 先找到下标为k的元素为记录点p1,然后设置新的记录 ...
- 数据结构上机-尾、头插法建立单链表-单链表遍历C语言完整代码实现
点击此处跳转视频链接:数据结构上机-尾.头插法建立单链表-单链表遍历C语言完整代码实现
- 数据结构学习(C++)——单链表应用(一元多项式【1】) (转)
数据结构学习(C++)--单链表应用(一元多项式[1]) (转)[@more@] 总算到了这里,这时,你会很得意的说,辛辛苦苦学的单链表总算知道能干点什么了.但是很不幸,如果你和我一样看的是那本书,到 ...
- 建立单链表 单链表的插入_单链列表插入
建立单链表 单链表的插入 All possible cases: 所有可能的情况: Inserting at beginning 开始插入 Inserting at the ending 在末尾插入 ...
- 数据结构与算法笔记(三)—— 链表(单链表、循环链表、双向链表)
一.前沿 1.1.为什么需要链表 顺序表的构建需要预先知道数据大小来申请连续的存储空间,而在进行扩充时又需要进行数据的搬迁,所以使用起来并不是很灵活. 链表结构可以充分利用计算机内存空间,实现灵活的内 ...
- 数据结构-链表-单链表(java实现)
今天和大家分享数据结构中链表的相关知识.在数据结构中有线性结构和非线性结构两种类别的区分,虽然链表属于线性结构是有序的列表,但是它在内存中却是不连续的. 关于数组和链表的优缺点. 数组静态分配内存,链 ...
- Java数据结构和算法(七)——链表
前面博客我们在讲解数组中,知道数组作为数据存储结构有一定的缺陷.在无序数组中,搜索性能差,在有序数组中,插入效率又很低,而且这两种数组的删除效率都很低,并且数组在创建后,其大小是固定了,设置的过大会造 ...
- 数据结构_Java_基于 线性表-单链表的初始化、逆序、去重、非递减序列的合并(开辟新链表先整体插入一个链表全部元素,再遍历另外一个链表寻找合适位置插入 、开辟新链表实现舍弃原链表)等操作实现
写在前面 不久前学习了数据结构线性表-数组-链表的相关知识,用C/C++语言实现了 单链表的系列相关操作 .见往期博客: 数据结构实验2_C语言_基于顺序表的非递减有序表的合并.线性表元素的增.删.改 ...
- 数据结构之 链表( 单链表, 双链表,循环链表)
前篇.链表的概括 1.链表(Linked list)说明 是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer).由于不必须按 ...
最新文章
- Git之提交项目到远程github
- 如何使用命令行中的“message”和“description”进行更改? [重复]
- mybatis整合spring下的的各种配置文件
- 基于java封装的语言_封装在java中的应用
- NLP预训练模型学习全攻略(内附前沿论文解读直播)
- Java web对试卷进行单选多选答题进行打分_2020年大学慕课Java程序设计作业答案...
- 【转】C#中ToString()格式详解
- 实战系列-分布式锁的Redis实现
- C语言——计算标准差公式
- Python批量复制文件夹及其内容、并按Excel表格遍历重命名文件夹
- 编程中汉字编码和英文编码的语言融合
- fiddler抓包,搞定接口
- English Grammer-01
- 分子生物学 第三章 基因、基因组及基因组学
- PCIE_基于YOLO3D的目标检测算法移植与测试
- android 拨号上网流程
- vfifo控制mig_Xilinx MIG IP核的研究及大容量数据缓冲区的实现
- GPT4.0一句话实现各类图表制作,让数据可视化变得更简单!类图、流程图、ER图.....
- java 微信海报的实现
- 苹果笔记本上的计算机在哪里找到,在哪里查自己电脑的mac地址
热门文章
- 带你走出计算机安全防范的六个误区
- 台式计算机网线插哪里,电脑主机网线插哪里?
- Android:修改默认音量等级
- SVN Cleanup的意思
- 中兴c300 OLT配置SFU
- 元宇宙大热,是风口还是虎口
- 无MAC法安装genymotion的解决办法_Invalid reply from server..
- JUC编程java多线程并发详细总结
- 我的世界java版怎么选择版本_《我的世界》游戏版本太多,玩家该如何选择?听听老玩家怎么说...
- java大写md5_java 字符按字母排序-拼接-md5加密-大写