链表---双向链表的解析与实现
来源:互联网 发布:精通qt4编程 源码 编辑:程序博客网 时间:2024/06/04 23:20
(1)如果为每个节点保留两个引用prve和next,让prev指向当前节点的上一个节点,让next指向当前节点的下一个节点。此时链表既可以向前依次访问每个节点,也可以向后依次访问每个节点,这种形式的节点称为双向链表。
(2)双向链表的查找
因为双向链表既可以向前搜索也可以向后搜索,当被搜索节点更靠近head或者tail中的某一端时,就从那一端开始搜索index<size/2从head开始搜索,index>size/2从tail开始搜索
(3)双向链表的插入
(4)双向链表的删除
实现
public class DoubleLinkedList<T>{//节点类 private class Node { //每个节点有三个成员变量 private T data; private Node next; private Node prev; public Node() {} public Node(T data,Node next,Node prev) { this.data = data; this.next = next; this.prev = prev; } } //分别用来指向链表的头节点、尾节点、保存链表的长度 private Node head; private Node tail; private int size; //链表的构造函数 public DoubleLinkedList() { head = null; tail = null; } public DoubleLinkedList(T element) { head = new Node(element,null,null); tail = head; size++; } //链表的长度 public int length() { return size; } //查找指定索引处的节点 private Node getNodeByIndex(int index) { if(index < 0 || index > size-1) { throw new IndexOutOfBoundsException("双向链表索引越界"); } if(index < size / 2)//如果索引在前半段的位置则从头节点开始遍历 { Node current = head; for (int i = 0; i < size / 2 && current != null; i++,current = current.next){if(i == index){return current;}} } else { Node current = tail; for (int i = size-1; i > size / 2 && current!= null; i++,current = current.prev){if(i == index ){return current;}} }return null; } //查找指定元素的索引位置 public int locateIndexByElement(T element) { Node current = head; for (int i = 0; i < size && current != null; i++,current = current.next){if(current.data == element){return i;}} return -1; } //插入 将指定的元素插入到指定的位置处 public void insert(T element,int index) { if(index < 0 || index > size ) { throw new IndexOutOfBoundsException("双向链表插入索引越界"); } if(null == head) {add(element); } else { if(index == 0) { addAtHead(element); } else { Node prev = getNodeByIndex(index-1);//获取要出入位置的前一个节点 Node next = prev.next;//第index位置的节点将会变为新节点的下一个节点 Node newNode = new Node(element,next,prev);//新节点的前一个节点是prev 后一个节点是next prev.next = newNode; next.prev = newNode; size++; } } } //插入 尾差法 public void add(T element) { if (head == null) { addAtHead(element); } else {Node newNode = new Node(element,null,tail);tail.next = newNode;tail = newNode; } size++; } //插入 头差法 public void addAtHead(T element) { Node newNode = new Node(element,head,null); if(head==null) { head = newNode; tail = head; } else { head.prev = newNode; head = newNode; } size++; } //删除 public T delete(int index) { if(index < 0 || index > size) { throw new IndexOutOfBoundsException("双向链表插入索引越界"); } Node deleteNode; if(index == 0)//若是删除第一个节点 要重新得到头节点 { deleteNode = head; head = head.next;//新的头节点的是原来头节点的下一个节点 deleteNode.next = null; } else{Node prev = getNodeByIndex(index-1);//找到要删除节点的前一个节点deleteNode = prev.next;//找到要删除的节点prev.next = deleteNode.next;//把prev的next指向要删除节点的下一个节点if(deleteNode.next != null){deleteNode.next.prev = prev;//要删除节点的下一个节点指向的前一个节点是prev}deleteNode.prev = null;deleteNode.next = null;} size--; return deleteNode.data; } //判断链表是否为空 public boolean isEmpty() { return size == 0; } //清空线性变 public void clear() { head = null; tail = null; size = 0; } public String toString() { if(isEmpty()) { return "[]"; } else { StringBuilder sb = new StringBuilder("["); for ( Node current = head;current != null; current = current.next) {sb.append(current.data.toString() + ","); } int len = sb.length(); return sb.delete(len-1,len).append("]").toString(); } } }测试
public class DoubleLlinkedListTest{public static void main(String[] args){DoubleLinkedList<String> list = new DoubleLinkedList<String>();list.addAtHead("HELLO");list.add("world");System.out.println(list);list.insert("111",1);list.insert("222",1);System.out.println(list);list.addAtHead("head"); System.out.println(list);list.delete(2);System.out.println(list);list.clear();System.out.println(list );}}结果
[HELLO,world]
[HELLO,222,111,world]
[head,HELLO,222,111,world]
[head,HELLO,111,world]
[]
0 0
- 链表---双向链表的解析与实现
- 双向链表的实现与操作(C语言实现)
- 链表-双向链表&&UVa12657 Boxes in a Line(移动盒子)的理解与解析
- Java的单链表与双向链表的实现
- uva12657 双向链表的实现与痛苦的调试
- 数据结构与算法分析-双向链表的实现
- 双向链表、队列与栈的C/C++实现
- 单链表与双向链表的Java实现
- 双向链表的表示与实现(C++版)
- 双向链表的两种实现与封装性
- 详谈双向链表的实现与简单操作
- 双向链表的宏实现——解析shttpd的链表实现
- 双向链表的实现
- 双向链表的实现
- 双向链表的实现
- 双向链表的实现
- 双向链表的实现
- 双向链表的实现
- solr+zookeeper集群搭建
- uart 摘录 尚未整理
- java导出word模板
- Object-C 中各数据类型转换 NSData转NSString,Byte,UIImage
- TOEFL speaking——verbs & phrasal verbs
- 链表---双向链表的解析与实现
- 根据文字计算cell的高度
- github发布项目
- 为视图绘制单(多)个圆角
- qq1368391900
- 自定义控件之水波纹的实现
- CouchDB介绍
- The project was not built since its build path is incomplete
- 调用Android的相机与图库并进行剪切