JAVA实现数据结构:双链表

  1. 节点类(以内部类形式使用)
    链表中内部类和嵌套类的区别:
    https://blog.csdn.net/WelcomeSpring/article/details/79430546
	// 节点类,以内部类形式
	private class Node<E> {
		private E date; // 数据
		private Node next; // 前驱
		private Node prev; // 后继

		public Node() {
			date = null;
			next = null;
			prev = null;
		}

		public Node(E date) {
			this.date = date;
		}

		public Node(E date, Node next, Node prev) {
			this.date = date;
			this.next = next;
			this.prev = prev;
		}

		public E getData() {
			return date;
		}

		public void setData(E data) {
			this.date = data;
		}

		public Node getNext() {
			return next;
		}

		public void setNext(Node next) {
			this.next = next;
		}

		public Node getprev() {
			return prev;
		}

		public void setprev(Node prev) {
			this.prev = prev;
		}
	}
  1. 双链表的实现
    链表接口见https://blog.csdn.net/qq_44467578/article/details/103946997
package 数据结构;

//双链表
public class myLinkedList<E> implements List<E> {
	private Node<E> head = new Node<>();
	private int size = 0;

	@Override
	public int getSize() {
		return size;
	}

	@Override
	public boolean isEmploy() {
		if (head.getNext() == null)
			return true;
		else
			return false;
	}

	@Override
	public boolean contains(E val) {
		Node<E> nNode = head.getNext();
		while (nNode != null) {
			if (nNode.getData() == val)
				return true;
			else
				nNode = nNode.getNext();
		}
		return false;
	}

	@Override
	public boolean headadd(E val) {

		Node<E> node = new Node(val);
		Node<E> nNode = head.getNext();
		if (isEmploy()) {
			head.setNext(node);
			node.setprev(head);
			size++;
		} else {
			head.setNext(node);
			nNode.setprev(node);
			node.setNext(nNode);
			node.setprev(head);
			size++;
		}
		return true;
	}

	@Override
	public boolean tailadd(E val) {
		Node<E> node = new Node(val);
		Node<E> pNode = head;
		while (pNode.getNext() != null) {
			pNode = pNode.getNext();
		}
		pNode.setNext(node);
		node.setprev(pNode);
		node.setNext(null);
		size++;
		return true;
	}

	// 尾删法
	public boolean remove() {
		Node<E> node = head;
		while (node.getNext() != null)
			node = node.getNext();
		node.getprev().setNext(null);
		node = null;
		size--;
		return true;
	}

	@Override
	public int indexOf(E val) {
		int i = 0;
		Node<E> nNode = head.getNext();
		while (nNode != null) {
			if (val == nNode.getData())
				return i;
			else {
				nNode = nNode.getNext();
				i++;
			}

		}
		return -1;
	}

	@Override
	public boolean insert(int i, E val) {
		if (i == 0)
			headadd(val);
		if (i == size)
			tailadd(val);
		else if(i>0&i<size) {
			Node<E> node = new Node<>(val);
			Node<E> pNode = head.getNext();
			for (int j = 0; j < i; j++) {
				pNode = pNode.getNext();
			}
			pNode.getprev().setNext(node);
			pNode.setprev(node);
			node.setprev(pNode.getprev());
			node.setNext(pNode);
			size++;
			return true;
		}
		return false;
	}

	@Override
	public boolean remove(int i) {
		Node<E> pNode = head.getNext();
		if (i == size - 1) {
			return remove();
		}
		for (int j = 0; j < i; j++) {
			pNode = pNode.getNext();
		}
		pNode.getprev().setNext(pNode.getNext());
		pNode.getNext().setprev(pNode.getprev());
		pNode = null;
		size--;
		return true;

	}

	@Override
	public boolean remove(E val) {
		Node<E> nNode = head.getNext();
		while (nNode.getNext() != null) {
			if (nNode.getData() == val) {
				nNode.getprev().setNext(nNode.getNext());
				nNode.getNext().setprev(nNode.getprev());
				nNode = null;
				size--;
				return true;
			} else
				nNode = nNode.getNext();
		}
		if(nNode.getData() == val)
			return remove();
		return false;
	}

	@Override
	public void replace(int i, E val) {
		Node<E> pNode = head;
		for (int j = 0; j < i; j++) {
			pNode = pNode.getNext();
		}
		pNode.setData(val);

	}

	@Override
	public Object getval(int i) {
		Node<E> pNode = head;
		for (int j = 0; j <= i; j++) {
			pNode = pNode.getNext();
		}
		return pNode.getData();
	}

	@Override
	public void print() {
		if (isEmploy())
			System.out.println("为空");
		else {
			Node<E> pNode = head;
			for (int j = 0; j < size; j++) {
				pNode = pNode.getNext();
				System.out.print(pNode.getData() + "> ");
			}
		}
	}

	public void reverseList() {
		Node<E> node, nNode;
		node = head.getNext();
		node.setprev(node.getNext());
		node = node.getNext();
		nNode = node.getNext();
		head.getNext().setNext(null);
		while (nNode != null) {
			node.setNext(node.getprev());
			node.setprev(nNode);
			node = node.getprev();
			nNode = node.getNext();
		}
		node.setNext(node.getprev());
		node.setprev(head);
		head.setNext(node);
	}

	// 节点类,以内部类形式
	private class Node<E> {
		private E date; // 数据
		private Node next; // 前驱
		private Node prev; // 后继

		public Node() {
			date = null;
			next = null;
			prev = null;
		}

		public Node(E date) {
			this.date = date;
		}

		public Node(E date, Node next, Node prev) {
			this.date = date;
			this.next = next;
			this.prev = prev;
		}

		public E getData() {
			return date;
		}

		public void setData(E data) {
			this.date = data;
		}

		public Node getNext() {
			return next;
		}

		public void setNext(Node next) {
			this.next = next;
		}

		public Node getprev() {
			return prev;
		}

		public void setprev(Node prev) {
			this.prev = prev;
		}
	}
}


  1. 双链表的实例
package 数据结构;

public class Main {
public static void main(String[] args) {
	myLinkedList<Integer> LL=new myLinkedList<>();
	LL.headadd(6);//6
	LL.tailadd(7);//6 7
	LL.insert(2, 8);//6 7 8
	LL.remove(1);//6 8
	LL.print();
	System.out.println();
	LL.reverseList();//8 6
	LL.print();
	System.out.println();
	System.out.print(LL.getSize()+" "+LL.getval(1)+" "+LL.contains(7)+" "+
		LL.indexOf(7)+" "+LL.isEmploy());
		}
	}

在这里插入图片描述

  1. 扩展
    双链表去掉前驱指针即为单链表
    将尾节点的后继指针指向头节点即为循环链表
    链表的转置有三个地方需要修改:
    *尾节点变头节点:尾节点的前驱指针指向null,后继指针指向前驱节点
    *头节点变尾节点:头节点的前驱指针指向后继节点,后继指针指向null
    *中间节点:前驱后继对换
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值