赞
踩
目录
2.2.10.根据index与size的大小关系快速定位指定index位置的节点
既要存储下一个节点地址,还要存储前一个节点地址。是Java的集合框架中LinkedList底层实现。
- /**
- * 车厢类
- */
- class DoubleNode{
- //指向前驱节点
- DoubleNode prev;
- //存储的具体元素
- int val;
- //指向后继节点
- DoubleNode next;
-
- //有参构造
- public DoubleNode(int val){
- this.val=val;
- }
- }

- /**
- * 火车类 基于int的双向链表
- */
- public class DoubleLinkedList {
- //存储的具体车厢个数
- private int size;
- //头节点
- private DoubleNode first;
- //尾节点
- private DoubleNode last;
-
- //具体方法实现
- //...
- }
- /**
- * 头插
- * @param val
- */
- public void addFirst(int val) {
- //引入一个局部变量,暂时存储一下头节点的地址
- DoubleNode f = first;
- //要插入一个节点,首先要new一个节点
- DoubleNode node = new DoubleNode(val);
- first = node; //因为是头插,那么这行代码不管当前链表是否为空都会执行
- if(f == null) { //若链表为空,则新建的节点既是头节点又是尾节点
- last = node;
- } else {
- node.next = f;
- f.prev = node;
- }
- size++;
- }

- /**
- * 尾插
- * @param val
- */
- public void addLast(int val) {
- //引入一个局部变量,暂时存储一下尾节点的地址
- DoubleNode l = last;
- DoubleNode node = new DoubleNode(val);
- last = node;
- if(l == null) {
- first = node;
- } else {
- node.prev = l;
- l.next = node;
- }
- size++;
- }

- /**
- * 任意index处添加元素
- * @param val
- */
- public void addIndex(int index, int val) {
- if(index < 0 || index > size) {
- System.err.println("add index illegal!");
- return;
- } else if(index == 0) {
- addFirst(val);
- } else if(index == size) {
- addLast(val);
- } else {
- //此时0 < index < size
- //在报错方法(未写)上使用快捷键Alt+Enter,自动生成指定方法
- DoubleNode node = node(index);
- //指向当前位置的前驱节点
- DoubleNode prev = node.prev;
- //要插入的新节点
- DoubleNode newNode = new DoubleNode(val);
- //先处理后半部分引用链
- newNode.next = node; ①
- node.prev = newNode; ②
- //再处理前半部分引用链
- prev.next = newNode; ③
- newNode.prev = prev; ④
- size++;
- }
- }

- /**
- * 根据index索引取得节点值
- * @param index
- * @return
- */
- public int get(int index) {
- if(rangeCheck(index)) {
- DoubleNode node = node(index);
- return node.val;
- } else {
- System.out.println("get index illegal!");
- return -1;
- }
- }
- /**
- * 修改index处的值为newVal
- * @param index
- * @param newVal
- */
- public void set(int index, int newVal) {
- if(rangeCheck(index)) {
- DoubleNode node = node(index);
- node.val = newVal;
- } else {
- System.out.println("set index illegal!");
- }
- }
- /**
- * 传入一个双向链表节点,将该节点从双向链表中删除
- * 核心思想 分治,先处理前驱或后继,再处理另一半的情况
- * @param node
- */
- private void unlinkNode(DoubleNode node) {
- //待删除节点的前驱
- DoubleNode prev = node.prev;
- //待删除结点的后继
- DoubleNode next = node.next;
-
- //先处理前半部分引用链
- //判断边界
- if(prev == null) {
- //说明此时待删除的节点恰好是头节点
- first = next;
- } else {
- //此时前驱节点不为空
- prev.next = next;
- node.prev = null;
- }
-
- //再处理后半部分引用链
- if(next == null) {
- last = prev;
- } else {
- //此时后继节点不为空
- next.prev = prev;
- node.next = null;
- }
- size--;
- }

- /**
- * 删除第一次出现值为val的元素
- * @param val
- */
- public void removeValueOnce(int val) {
- //只需要从头开始遍历
- for (DoubleNode x = first; x != null; x = x.next) {
- if(x.val == val) {
- unlinkNode(x);
- return;
- }
- }
- }
- /**
- * 删除单链表中所有值为val的节点
- * @param val
- */
- public void removeAllValue(int val) {
- for(DoubleNode x = first; x != null;) {
- if(x.val == val){
- //x就是待删除的元素
- //先暂存一下next的节点地址
- DoubleNode next = x.next;
- unlinkNode(x);
- x = next; //真正让x走向next
- } else {
- x = x.next;
- }
- }
- }

- /**
- * 判断链表的index是否合法
- * @param index
- * @return
- */
- private boolean rangeCheck(int index) {
- if(index < 0 || index >= size) {
- return false;
- }
- return true;
- }
- /**
- * 根据index与size的大小关系快速定位指定index位置的节点
- * @param index
- * @return
- */
- private DoubleNode node(int index) {
- if(index < size >> 1) {
- //从头向后
- DoubleNode node = first;
- for (int i = 0; i < index; i++) {
- node = node.next;
- }
- return node;
- } else {
- //从后向前
- DoubleNode node = last;
- for (int i = size-1; i > index; i--) {
- node = node.prev;
- }
- return node;
- }
- }

- public String toString() {
- String ret = "";
- DoubleNode node = first;
- while(node != null) {
- ret += node.val + "->";
- node = node.next;
- }
- ret += "NULL";
- return ret;
- }
- /**
- * 车厢类
- */
- class DoubleNode{
- //指向前驱节点
- DoubleNode prev;
- //存储的具体元素
- int val;
- //指向后继节点
- DoubleNode next;
-
- //有参构造
- public DoubleNode(int val){
- this.val=val;
- }
- }
-
- /**
- * 火车类 基于int的双向链表
- */
- public class DoubleLinkedList {
- //存储的具体车厢个数
- private int size;
- //头节点
- private DoubleNode first;
- //尾节点
- private DoubleNode last;
-
- /**
- * 头插
- * @param val
- */
- public void addFirst(int val){
- //引入一个局部变量,暂时存储一下头节点的地址
- DoubleNode f=first;
- //要插入一个节点,首先要new一个节点
- DoubleNode node=new DoubleNode(val);
- first=node;
- if(f==null){
- last=node;
- }else{
- node.next=f;
- f.prev=node;
- }
- size++;
- }
-
- /**
- * 尾插
- * @param val
- */
- public void addLast(int val) {
- //引入一个局部变量,暂时存储一下尾节点的地址
- DoubleNode l = last;
- DoubleNode node = new DoubleNode(val);
- last = node;
- if(l == null) {
- first = node;
- } else {
- node.prev = l;
- l.next = node;
- }
- size++;
- }
-
- /**
- * 任意index处添加元素
- * @param val
- */
- public void addIndex(int index, int val) {
- if(index < 0 || index > size) {
- System.err.println("add index illegal!");
- return;
- } else if(index == 0) {
- addFirst(val);
- } else if(index == size) {
- addLast(val);
- } else {
- //此时0 < index < size
- //在报错方法(未写)上使用快捷键Alt+Enter,自动生成指定方法
- DoubleNode node = node(index);
- //指向当前位置的前驱节点
- DoubleNode prev = node.prev;
- //要插入的新节点
- DoubleNode newNode = new DoubleNode(val);
- //先处理后半部分引用链
- newNode.next = node;
- node.prev = newNode;
- //再处理前半部分引用链
- prev.next = newNode;
- newNode.prev = prev;
- size++;
- }
- }
-
- /**
- * 根据index索引取得节点值
- * @param index
- * @return
- */
- public int get(int index) {
- if(rangeCheck(index)) {
- DoubleNode node = node(index);
- return node.val;
- } else {
- System.out.println("get index illegal!");
- return -1;
- }
- }
-
- /**
- * 修改index处的值为newVal
- * @param index
- * @param newVal
- */
- public void set(int index, int newVal) {
- if(rangeCheck(index)) {
- DoubleNode node = node(index);
- node.val = newVal;
- } else {
- System.out.println("set index illegal!");
- }
- }
-
- /**
- * 传入一个双向链表节点,将该节点从双向链表中删除
- * 核心思想 分治,先处理前驱或后继,再处理另一半的情况
- * @param node
- */
- private void unlinkNode(DoubleNode node) {
- //待删除节点的前驱
- DoubleNode prev = node.prev;
- //待删除结点的后继
- DoubleNode next = node.next;
-
- //先处理前半部分引用链
- //判断边界
- if(prev == null) {
- //说明此时待删除的节点恰好是头节点
- first = next;
- } else {
- //此时前驱节点不为空
- prev.next = next;
- node.prev = null;
- }
-
- //再处理后半部分引用链
- if(next == null) {
- last = prev;
- } else {
- //此时后继节点不为空
- next.prev = prev;
- node.next = null;
- }
- size--;
- }
-
- /**
- * 删除第一次出现值为val的元素
- * @param val
- */
- public void removeValueOnce(int val) {
- //只需要从头开始遍历
- for (DoubleNode x = first; x != null; x = x.next) {
- if(x.val == val) {
- unlinkNode(x);
- return;
- }
- }
- }
-
- /**
- * 删除单链表中所有值为val的节点
- * @param val
- */
- public void removeAllValue(int val){
- for(DoubleNode x=first;x!=null;){
- if(x.val==val){
- //x就是待删除的元素
- //先暂存一下next的节点地址
- DoubleNode next=x.next;
- unlinkNode(x);
- x=next;
- }else{
- x=x.next;
- }
- }
- }
-
- /**
- * 根据index与size的大小关系快速定位指定index位置的节点
- * @param index
- * @return
- */
- private DoubleNode node(int index) {
- if(index < size >> 1) {
- //从头向后
- DoubleNode node = first;
- for (int i = 0; i < index; i++) {
- node = node.next;
- }
- return node;
- } else {
- //从后向前
- DoubleNode node = last;
- for (int i = size-1; i > index; i--) {
- node = node.prev;
- }
- return node;
- }
- }
-
- /**
- * 判断链表的index是否合法
- * @param index
- * @return
- */
- private boolean rangeCheck(int index) {
- if(index < 0 || index >= size) {
- return false;
- }
- return true;
- }
-
- public String toString() {
- String ret = "";
- DoubleNode node = first;
- while(node != null) {
- ret += node.val + "->";
- node = node.next;
- }
- ret += "NULL";
- return ret;
- }
-
- public static void main(String[] args) {
- DoubleLinkedList doubleLinkedList=new DoubleLinkedList();
- doubleLinkedList.addFirst(1);
- doubleLinkedList.addFirst(2);
- doubleLinkedList.addFirst(3);
- doubleLinkedList.addLast(3);
- doubleLinkedList.addLast(3);
- doubleLinkedList.addLast(3);
- //3->2->1->3->3->3->NULL
- doubleLinkedList.addIndex(1,99);
- //3->99->2->1->3->3->3->NULL
- doubleLinkedList.removeValueOnce(99);
- //3->2->1->3->3->3->NULL
- doubleLinkedList.removeAllValue(3);
- //2->1->NULL
- System.out.println(doubleLinkedList);
- }
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。