数据结构与算法(Java版)_05_单链表及其增、删、改、查
单链表:
链表是以节点的方式来存储数据的,是链式存储结构。
每个节点包含data域和next域,next域指向下一个节点。
链表的各个节点在内存中不一定是连续存储的。
链表分为带头节点的链表和不带头节点的链表,根据实际需求来确定。
单链表图示:
代码实现:
package dataStructureAtShangGuiGu; public class LinkedListDemo { public static void main(String[] args) { MyLinkedList myLinkedList = new MyLinkedList(); LinkedNode linkedNode1 = new LinkedNode(1,"小明"); LinkedNode linkedNode2 = new LinkedNode(2,"小李"); LinkedNode linkedNode3 = new LinkedNode(3,"小王"); myLinkedList.add(linkedNode1); myLinkedList.add(linkedNode2); myLinkedList.add(linkedNode3); myLinkedList.list(); } } class MyLinkedList{ private LinkedNode headNode = new LinkedNode(0,""); //头节点 public void add(LinkedNode linkedNode) { LinkedNode tmp = headNode; while(null!=tmp.getNext()) { //遍历节点,若该节点的next若为null,则说明该节点是链表最后一个节点 tmp = tmp.getNext(); // } tmp.setNext(linkedNode);//将该节点连接到链表尾部 } public void list() { if(null==headNode.getNext()) { System.err.println("链表为空"); return; } LinkedNode tmp = this.headNode.getNext(); while(null!=tmp) { System.out.println(tmp); tmp = tmp.getNext(); } } } class LinkedNode { private int no; private String name; private LinkedNode next; public LinkedNode(int no, String name) { this.no = no; this.name = name; } public LinkedNode getNext() { return next; } public void setNext(LinkedNode next) { this.next = next; } public int getNo() { return no; } public void setNo(int no) { this.no = no; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "LinkedNode [no=" + no + ", name=" + name +"]"; } }
运行测试:
添加元素的时候希望按元素的no属性从小到大排序:
public void addByOrder(LinkedNode linkedNode) { LinkedNode tmp = this.headNode; while(null!=tmp.getNext()) { if(linkedNode.getNo()==tmp.getNo()) { //编号已经存在的情况 System.err.println("链表已经存在[no=:"+linkedNode.getNo()+","+linkedNode.getName()+"]的元素"); return; } if(linkedNode.getNo()<tmp.getNext().getNo()) break; //找到了 tmp = tmp.getNext(); } linkedNode.setNext(tmp.getNext()); //将添加的节点的next指向指针的下一个节点 tmp.setNext(linkedNode); //将指针的next指向添加的节点 }
这里我将元素顺序打乱后再添加,并添加相同的元素:
运行测试:
可以很直接地看到,元素存入单链表的时候是按照no属性排好序存放的,并且重复的元素不让其存入。
根据no属性查找节点并修改节点name属性:
public void update(LinkedNode linkedNode) { //根据编号查找节点并修改节点名称 LinkedNode tmp = this.headNode.getNext(); while(null!=tmp) { //遍历链表 if(linkedNode.getNo()==tmp.getNo()) { //查找对应编号的元素 tmp.setName(linkedNode.getName()); return; } tmp = tmp.getNext(); } System.err.println("没有找到编号为:"+linkedNode.getNo()+"的节点!"); }
这里我修改no为2的节点的name属性:
运行测试:
可以看到,修改成功!
删除单链表中的某个节点
public void delete(int no) { LinkedNode tmp = this.headNode; while(null!=tmp.getNext()) { if(tmp.getNext().getNo()==no) { tmp.setNext(tmp.getNext().getNext()); //关键点,让删除目标节点的前一个节点的next指向删除目标节点的next return; } tmp = tmp.getNext(); } System.err.println("没有找到编号为:"+no+"的节点!"); }
这里我删除几个节点:
运行测试:
完美删除!