双向链表学习笔记

来源:互联网 发布:淘宝评分动态头像 编辑:程序博客网 时间:2024/09/21 09:02

1.链表接口定义

package com.ncs.datastructure.linklist;public interface ILinkList {/** * 链表是否为空 * @return */public abstract boolean isEmpty();/** * 在链表的第一个节点前插入节点 * @param data */public abstract void addToHead(Object data);/** * 在链表的最后一个节点追加节点 * @param data */public abstract void addToTail(Object data);/** * 删除链表中的第一个节点 * @return */public abstract Object deleteFromHead();/** * 删除链表中的最后一个节点 * @return */public abstract Object deleteFromTail();/** * 链表中是否存在指定的节点 * @param data * @return */public abstract boolean isContains(Object data);/** * 删除指定的节点 * @param data */public abstract void deleteNode(Object data);}

2.双向链表的简单实现

package com.ncs.datastructure.linklist;import com.ncs.datastructure.linklist.SingleLinkList.Node;/** * 双向链表的简单实现 * @author yuanli * */public class DoubleLinkList implements ILinkList {/** * 之所以定义为内部类,是因为用户并不关心链表节点的结构,而只关心链表存储的数据 * @author yuanli * */public class Node {//数据域private Object data;//前驱节点private Node prev;//后继节点private Node next;public Node() {super();}public Node(Object data) {this(data, null, null);}public Node(Object data, Node prev, Node next) {super();this.data = data;this.prev = prev;this.next = next;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}public Node getPrev() {return prev;}public void setPrev(Node prev) {this.prev = prev;}public Node getNext() {return next;}public void setNext(Node next) {this.next = next;}}//表示链表的第一个节点protected Node head;//表示链表的最后一个节点protected Node tail;public void addToHead(Object data) {if (this.head == null) {this.head = new Node(data);if (this.tail == null ) this.tail = this.head;} else {Node temp = new Node(data,null,this.head);this.head.prev = temp;this.head = temp;}}public void addToTail(Object data) {if (!isEmpty()) {this.tail = new Node(data, this.tail, null);this.tail.prev.next = this.tail;} else {this.tail = this.head = new Node(data); }}public Object deleteFromHead() {Node delete = null;if (this.head == this.tail) {delete = this.head;this.head = this.tail = null;} else {delete = this.head;this.head = this.head.next;this.head.prev = null;}return delete;}public Object deleteFromTail() {Node delete = null;if (this.head == this.tail) {delete = this.head;this.head = this.tail = null;} else {delete = this.tail;this.tail = this.tail.prev;this.tail.next = null;}return delete;}public void deleteNode(Object data) {if (!isEmpty()) {//如果只有一个节点if (this.head == this.tail) {this.head = this.tail = null;return;}//如果是删除第一个节点if (this.head.data.equals(data)) {this.deleteFromHead();return;}//如果是删除最后一个节点if (this.tail.data.equals(data)) {this.deleteFromTail();return;}//删除中间节点for (Node temp = this.head; temp.next != null; temp = temp.next) {if (temp.data.equals(data)) {//Node prev = temp.prev;//Node next = temp.next;//prev.next = next;//next.prev = prev;temp.prev.next = temp.next;temp.next.prev = temp.prev;}}}}public boolean isContains(Object data) {if (!isEmpty()) {Node temp = this.head;for (; temp.next != null; temp = temp.next) {if (temp.data.equals(data)) {return true;}}}return false;}public boolean isEmpty() {return this.head == null;}/** * 遍历链表的所有节点,并打印出节点数据信息 */public void printAll() {Node temp = this.head;for (; temp != null; temp = temp.next) {System.out.println("node data is " + temp.data);}}/** * @param args */public static void main(String[] args) {//实例化一个单向链表对象DoubleLinkList dll = new DoubleLinkList();//向单向链表中添加节点dll.addToHead("node1");dll.addToTail("node2");dll.addToTail("node3");dll.addToTail("node4");dll.addToTail("node5");//输出所有节点数据dll.printAll();//删除第一个节点dll.deleteFromHead();//删除最后一个节点dll.deleteFromTail();//输出所有节点数据dll.printAll();//链表中是否包含指定的节点boolean isExsist = dll.isContains("node11");System.out.println(isExsist);//删除指定的节点dll.deleteNode("node3");dll.printAll();}}

3.总结

双向链表弥补了单向链表的不足,可以双向获取相邻节点,比如删除最后一个节点时就不需要遍历整个链表,而可以直接操作最后一个节点。


原创粉丝点击