数据结构与算法——链表
java实现单链表
链表介绍
简化图,实际存储并不一定这样
添加操作
直接添加到尾部
/**
* 直接添加到链表的最后
*
* @param node
*/
public void add(Node node) {
// 定义一个辅助节点用于寻找链表的最后
Node temp = head;
while (true) {
// 当下一个节点为空是结束循环
if (temp.getNext() == null) {
break;
}
temp = temp.getNext();
}
// 当循环结束时 temp 就指向了最后一个节点,此时直接将新节点添加到该节点的下一个节点
temp.setNext(node);
}
按顺序添加
/**
* 按顺序添加节点,当有与该节点 no 相同的节点是提示:编号为 xxx 的节点已存在
* 需要注意的是:
* 要使用当前节点的下一个节点的编号与要添加的节点比较,如果满足条件则,添加为当前节点的下一个节点
* 如果是用当前节点与要添加的节点比较,则无法添加,因为当前节点无法获取上一个节点
*
* @param node
*/
public void addOrder(Node node) {
// 定义一个辅助节点用于寻找链表的最后
Node temp = head;
//用于判断是以何种方式退出循环
boolean flag = false;
while (true) {
// 此时添加到链表的末端
if (temp.getNext() == null) {
break;
}
if(temp.getNext().getNo() > node.getNo()) {//找到要添加的位置
break;
}
if(temp.getNext().getNo() == node.getNo()) {
flag = true;
break;
}
temp = temp.getNext();
}
if(!flag) {
//顺序要注意,先将当前节点的下一个节点为新添加节点的下一个节点,
//再将新节点设置为 temp 的下一个节点
node.setNext(temp.getNext());
temp.setNext(node);
}else {
System.out.println("编号为 " + node.getNo() + "的节点已存在");
}
}
遍历
/**
* 遍历链表
*/
public void show() {
if(head.getNext() == null) {
System.out.println("该链表为空");
return;
}
//头节点无需打印
Node temp = head.getNext();
while(temp != null) {
System.out.println(temp);
temp = temp.getNext();
}
}
删除
/**
* 通过 no 删除节点
* 同样删除节点也要使用前一个节点,单链表不能自删除(双链表可以)
*
* @param no
*/
public void delete(int no) {
Node temp = head;
boolean flag = false;
while(true) {
if(temp.getNext() == null) {//没有找到要删除的节点
break;
}
if(temp.getNext().getNo() == no) {
flag = true;
break;
}
temp = temp.getNext();
}
if(flag) {
temp.setNext(temp.getNext().getNext());
}else {
System.out.println("编号为 " + no + "的节点不存在");
}
}
完整代码
package com.kc.c03_linkedList.test1;
public class LinkedListTest {
public static void main(String[] args) {
Node n1 = new Node(1);
Node n2 = new Node(2);
Node n3 = new Node(3);
Node n4 = new Node(4);
Node n5 = new Node(5);
Node n6 = new Node(6);
Node n7 = new Node(7);
NodeManger manger = new NodeManger();
// manger.add(n1);
// manger.add(n7);
// manger.add(n2);
// manger.add(n6);
// manger.add(n4);
// manger.add(n5);
// manger.add(n3);
manger.addOrder(n1);
manger.addOrder(n7);
manger.addOrder(n2);
manger.addOrder(n6);
manger.addOrder(n4);
manger.addOrder(n4);
manger.addOrder(n5);
manger.addOrder(n3);
manger.show();
System.out.println("----------------------------------------------");
manger.delete(0);
manger.show();
}
}
class NodeManger {
// 定义一个头节点,该节点固定不动
private Node head = new Node(0);
/**
* 直接添加到链表的最后
*
* @param node
*/
public void add(Node node) {
// 定义一个辅助节点用于寻找链表的最后
Node temp = head;
while (true) {
// 当下一个节点为空是结束循环
if (temp.getNext() == null) {
break;
}
temp = temp.getNext();
}
// 当循环结束时 temp 就指向了最后一个节点,此时直接将新节点添加到该节点的下一个节点
temp.setNext(node);
}
/**
* 按顺序添加节点,当有与该节点 no 相同的节点是提示:编号为 xxx 的节点已存在
* 需要注意的是:
* 要使用当前节点的下一个节点的编号与要添加的节点比较,如果满足条件则,添加为当前节点的下一个节点
* 如果是用当前节点与要添加的节点比较,则无法添加,因为当前节点无法获取上一个节点
*
* @param node
*/
public void addOrder(Node node) {
// 定义一个辅助节点用于寻找链表的最后
Node temp = head;
//用于判断是以何种方式退出循环
boolean flag = false;
while (true) {
// 此时添加到链表的末端
if (temp.getNext() == null) {
break;
}
if(temp.getNext().getNo() > node.getNo()) {//找到要添加的位置
break;
}
if(temp.getNext().getNo() == node.getNo()) {
flag = true;
break;
}
temp = temp.getNext();
}
if(!flag) {
//顺序要注意,先将当前节点的下一个节点为新添加节点的下一个节点,
//再将新节点设置为 temp 的下一个节点
node.setNext(temp.getNext());
temp.setNext(node);
}else {
System.out.println("编号为 " + node.getNo() + "的节点已存在");
}
}
/**
* 通过 no 删除节点
* 同样删除节点也要使用前一个节点,单链表不能自删除(双链表可以)
*
* @param no
*/
public void delete(int no) {
Node temp = head;
boolean flag = false;
while(true) {
if(temp.getNext() == null) {//没有找到要删除的节点
break;
}
if(temp.getNext().getNo() == no) {
flag = true;
break;
}
temp = temp.getNext();
}
if(flag) {
temp.setNext(temp.getNext().getNext());
}else {
System.out.println("编号为 " + no + "的节点不存在");
}
}
/**
* 遍历链表
*/
public void show() {
if(head.getNext() == null) {
System.out.println("该链表为空");
return;
}
//头节点无需打印
Node temp = head.getNext();
while(temp != null) {
System.out.println(temp);
temp = temp.getNext();
}
}
}
/**
* 定义一个节点类
*
* @author wen
*
*/
class Node {
private int no;
private Node next;// next域,指向下一个节点
public Node(int no) {
this.no = no;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
@Override
public String toString() {
return "Node [no=" + no + "]";
}
}
有兴趣的可以自己完成一下修改,查找指定节点的操作
!!!图片来源于百度