数据结构-单链表

一、介绍

链表是有序的列表,但是它在内存中是存储如下:

小结:

  1. 链表是以节点的方式来存储,是链式存储。
  2. 每个节点包含 data 域, next 域:指向下一个节点。
  3. 如上图:发现链表的的next存放的是下一个节点的地址,所以各个节点不一定是连续存储。
  4. 链表分带头节点的链表和没有头节点的链表,根据实际的需求来确定。

二、单链表介绍

1.逻辑结构

单链表(带头结点) 逻辑结构示意图如下:

2.具体应用

任务要求:使用带head(头结点)的单向链表实现 – 水浒英雄排行榜管理

  1. 完成对英雄人物的增(头插、尾插、按顺序插)删改查操作
  2. 求单链表中有效节点的个数
  3. 查找单链表中的倒数第k个结点
  4. 单链表的反转
  5. 从尾到头打印单链表
  6. 合并两个有序的单链表,合并之后的链表依然有序

代码实现:

  • 核心实现:

    1. 创建HeroNode类,用来充当节点,类中属性包括:id(排名),name(姓名),nickName(花名),next(指向下一个节点的域)

    2. 创建类SingleLinkedList,里面维护一个头结点,该类具备对节点的增删查改功能

    3. 代码实现:

      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;}
      }
      
  • 其它功能实现:

    1. 完成对英雄人物的增(头插、尾插、按顺序插)删改查操作

      • 具体代码:

            /*** 尾插法插入数据* 思路分析:找到节点的最后一个元素,将待插入的节点插入到后面* @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;}
        
      • 效果图:

    2. 求单链表中有效节点的个数

      • 具体代码:

            /*** 获取链表长度* @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;}
        
      • 效果图:

    3. 查找单链表中的倒数第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;}
      • 效果图:

    4. 单链表的反转

      • 具体代码:

            /*** 单链表的反转* @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());}
      • 效果图:

    5. 从尾到头打印单链表

      • 具体代码:

            /*** 反向遍历单链表* 方法一:使用递归 * 方法二:创建新链表,反向,再遍历如上反向链表*/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;}}
      • 效果图:

    6. 合并两个有序的单链表,合并之后的链表依然有序

      • 具体代码:

            /*** 合并两个单链表,返回的链表依然有序* @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;}
      • 效果图:

三、注意事项

  1. 重新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. 数据结构(三)之单链表反向查找

    一.反向查找单链表 1.简单查找 先遍历获取单链表单长度n,然后通过计算得到倒数第k个元素的下标为n-k,然后查找下标为n-k的元素. 2.优化查找 先找到下标为k的元素为记录点p1,然后设置新的记录 ...

  2. 数据结构上机-尾、头插法建立单链表-单链表遍历C语言完整代码实现

    点击此处跳转视频链接:数据结构上机-尾.头插法建立单链表-单链表遍历C语言完整代码实现

  3. 数据结构学习(C++)——单链表应用(一元多项式【1】) (转)

    数据结构学习(C++)--单链表应用(一元多项式[1]) (转)[@more@] 总算到了这里,这时,你会很得意的说,辛辛苦苦学的单链表总算知道能干点什么了.但是很不幸,如果你和我一样看的是那本书,到 ...

  4. 建立单链表 单链表的插入_单链列表插入

    建立单链表 单链表的插入 All possible cases: 所有可能的情况: Inserting at beginning 开始插入 Inserting at the ending 在末尾插入 ...

  5. 数据结构与算法笔记(三)—— 链表(单链表、循环链表、双向链表)

    一.前沿 1.1.为什么需要链表 顺序表的构建需要预先知道数据大小来申请连续的存储空间,而在进行扩充时又需要进行数据的搬迁,所以使用起来并不是很灵活. 链表结构可以充分利用计算机内存空间,实现灵活的内 ...

  6. 数据结构-链表-单链表(java实现)

    今天和大家分享数据结构中链表的相关知识.在数据结构中有线性结构和非线性结构两种类别的区分,虽然链表属于线性结构是有序的列表,但是它在内存中却是不连续的. 关于数组和链表的优缺点. 数组静态分配内存,链 ...

  7. Java数据结构和算法(七)——链表

    前面博客我们在讲解数组中,知道数组作为数据存储结构有一定的缺陷.在无序数组中,搜索性能差,在有序数组中,插入效率又很低,而且这两种数组的删除效率都很低,并且数组在创建后,其大小是固定了,设置的过大会造 ...

  8. 数据结构_Java_基于 线性表-单链表的初始化、逆序、去重、非递减序列的合并(开辟新链表先整体插入一个链表全部元素,再遍历另外一个链表寻找合适位置插入 、开辟新链表实现舍弃原链表)等操作实现

    写在前面 不久前学习了数据结构线性表-数组-链表的相关知识,用C/C++语言实现了 单链表的系列相关操作 .见往期博客: 数据结构实验2_C语言_基于顺序表的非递减有序表的合并.线性表元素的增.删.改 ...

  9. 数据结构之 链表( 单链表, 双链表,循环链表)

    前篇.链表的概括 1.链表(Linked list)说明 是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer).由于不必须按 ...

最新文章

  1. Git之提交项目到远程github
  2. 如何使用命令行中的“message”和“description”进行更改? [重复]
  3. mybatis整合spring下的的各种配置文件
  4. 基于java封装的语言_封装在java中的应用
  5. NLP预训练模型学习全攻略(内附前沿论文解读直播)
  6. Java web对试卷进行单选多选答题进行打分_2020年大学慕课Java程序设计作业答案...
  7. 【转】C#中ToString()格式详解
  8. 实战系列-分布式锁的Redis实现
  9. C语言——计算标准差公式
  10. Python批量复制文件夹及其内容、并按Excel表格遍历重命名文件夹
  11. 编程中汉字编码和英文编码的语言融合
  12. fiddler抓包,搞定接口
  13. English Grammer-01
  14. 分子生物学 第三章 基因、基因组及基因组学
  15. PCIE_基于YOLO3D的目标检测算法移植与测试
  16. android 拨号上网流程
  17. vfifo控制mig_Xilinx MIG IP核的研究及大容量数据缓冲区的实现
  18. GPT4.0一句话实现各类图表制作,让数据可视化变得更简单!类图、流程图、ER图.....
  19. java 微信海报的实现
  20. 苹果笔记本上的计算机在哪里找到,在哪里查自己电脑的mac地址

热门文章

  1. 带你走出计算机安全防范的六个误区
  2. 台式计算机网线插哪里,电脑主机网线插哪里?
  3. Android:修改默认音量等级
  4. SVN Cleanup的意思
  5. 中兴c300 OLT配置SFU
  6. 元宇宙大热,是风口还是虎口
  7. 无MAC法安装genymotion的解决办法_Invalid reply from server..
  8. JUC编程java多线程并发详细总结
  9. 我的世界java版怎么选择版本_《我的世界》游戏版本太多,玩家该如何选择?听听老玩家怎么说...
  10. java大写md5_java 字符按字母排序-拼接-md5加密-大写