2.2 java实现双向链表

双向链表

  1. 单链表的缺点
    (1)查找的方向只能是一个方向
    (2)单链表不能自我删除,需要依靠辅助节点
  2. 双向链表的特点
    (1)查找的方向有两个。
    (2)可以进行自我删除,删除操作不需要辅助节点

节点

双向链表中每个节点需要有两个指向其它节点的指针,它们分别指向链表中的下一个节点,和链表中的上一个节点。
代码:

/**
 * 节点类:四个属性id, name, next, pre
 * @author dxt
 *
 */
class Node2{
	public int id;	//节点的唯一标识符
	public String name;	//模拟节点中的数据
	public Node2 next;	//指向下一个节点的指针,默认初始为空
	public Node2 pre;	//指向上一个节点的指针默认初始为空
	
	//构造器
	public Node2(int id, String name) {
		this.id = id;
		this.name = name;
	}
	//重写toString()方法
	@Override
	public String toString() {
		return "Node2 [id=" + id + ", name=" + name + "]";
	}
}

实现的方法

  1. void add(Node2 node):向双向链表尾添加节点。
  2. void printList():从头遍历,输出链表。
  3. void update(Node2 node):将链表中与 node节点相同id的节点的 数据(name)改为node节点的数据。
  4. void delete(int nodeId):删除链表中节点id为nodeId的节点。

实现代码

代码

/**
 * 实现双链表类
 */
public class DoubleLinkedListDemo {
	public static void main(String[] args) {
		//测试DoubleLinkedList类
		System.out.println("测试双向链表的实现");
		//1. 创建节点
		Node2 n1 = new Node2(1, "张三");
		Node2 n2 = new Node2(2, "李四");
		Node2 n3 = new Node2(3, "王五");
		Node2 n4 = new Node2(4, "王老五");
		//2. 创建一个双向链表
		DoubleLinkedList dll = new DoubleLinkedList();
		dll.add(n1);
		dll.add(n2);
		dll.add(n3);
		dll.add(n4);
		dll.printList();
		dll.delete(1);
		dll.delete(0);
		dll.printList();
		Node2 n5 = new Node2(4, "灰太狼");
		dll.update(n5);
		dll.printList();
	}
}

/**
 * 节点类:四个属性id, name, next, pre
 * @author dxt
 *
 */
class Node2{
	public int id;	//节点的唯一标识符
	public String name;	//模拟节点中的数据
	public Node2 next;	//指向下一个节点的指针,默认初始为空
	public Node2 pre;	//指向上一个节点的指针默认初始为空
	
	//构造器
	public Node2(int id, String name) {
		this.id = id;
		this.name = name;
	}
	//重写toString()方法
	@Override
	public String toString() {
		return "Node2 [id=" + id + ", name=" + name + "]";
	}
}
/**
 * 实现一个具有头节点的双向链表
 * @author dxt
 *
 */
class DoubleLinkedList{
	//头节点
	private Node2 headNode = new Node2(0, "");
	
	//获取头节点
	public Node2 getHeadNode() {
		return headNode;
	}
	/**
	 * 向链表尾添加节点
	 * @param node
	 */
	public void add(Node2 node) {
		//定义一个辅助节点
		Node2 temp = headNode;
		while(true) {	//定位到链表尾
			if(temp.next == null) {
				break;
			}
			temp = temp.next;
		}
		temp.next = node;	//添加到链表尾
		node.pre = temp;
	}
	/**
	 * 从头遍历 输出链表
	 */
	public void printList() {
		//1.判断链表是否为空
		if(headNode.next == null) {
			System.out.println("链表为空。。。");
			return;
		}
		//2. 遍历输出
		Node2 temp = headNode.next;
		while(temp != null) {
			System.out.println(temp);
			temp = temp.next;	//后移
		}
	}
	/**
	 * 将链表中与 node节点相同id的节点的 数据(name)改为node节点的数据
	 * @param node
	 */
	public void update(Node2 node) {
		//1. 判断链表是否为空
		if(headNode.next == null) {
			System.out.println("链表为空,没有数据可以更改。");
			return;
		}
		//2. 查找到对应节点。需要注意:链表不为空时,也可能不包括要修改的节点
		Node2 temp = headNode.next;
		boolean find = false;
		while(true) {
			if(temp == null) {
				break;
			}
			if(temp.id == node.id) {
				find = true;
				break;
			}
			temp = temp.next;
		}
		//3. 更改节点数据
		if(find) {
			temp.name = node.name;
		}else {
			System.out.println("链表中没有对应节点,修改失败。");
		}
	}
	/**
	 * 删除链表中节点id为nodeId的节点
	 * @param id
	 */
	public void delete(int nodeId) {
		//1. 判断链表是否为空
		if(headNode.next == null) {
			System.out.println("链表为空,删除失败。");
			return;
		}
		//2. 查找对应节点。需要注意链表中没有对应id的节点
		Node2 temp = headNode.next;
		boolean find = false;	//表示链表中没有对应id的节点
		while(true) {
			if(temp == null) {
				break;
			}
			if(temp.id == nodeId) {
				find = true;	//找到对应节点
				break;
			}
			temp = temp.next;
		}
		//3. 删除操作
		if(find) {
			temp.pre.next = temp.next;
			if(temp.next != null) {	//当删除最后一个节点时,temp.next=null
				temp.next.pre = temp.pre;
			}
		}else {
			System.out.println("链表中没有对应id的节点,删除失败。");
		}
	}
}

结果
result

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值