本篇博客主要介绍关于双向链表的一些简答操作实现,其中有有部分代码的实现和前两篇博客中的单向链表是相类似的。例如:查找链表中是否包含关键字key、求链表的长度等。
其余的涉及到prev指向的需要特别注意,区分和单向链表之间的差异。
目录
实现双向链表,首先需要自己定义一个结点,结点中包含三个域:val、prev、next;
定义头结点的引用head
定义尾结点的引用last
- static class ListNode{
- public int val;
- public ListNode prev;//前驱
- public ListNode next;//后继
-
- //提供一个构造方法
- public ListNode(int val){
- this.val = val;
- }
- }
- public ListNode head;//代表当前链表头结点的引用
- public ListNode last;//代表当前链表尾结点的引用
- public void addFirst(int data){
- ListNode node = new ListNode(data);
- if(head == null){
- head = node;
- last = node;
- }else {
- node.next = head;
- head.prev = node;
- head = node;
- }
- }
- public void addLast(int data){
- ListNode node = new ListNode(data);
- if(head == null){
- head = node;
- last = node;
- }else{
- last.next = node;
- node.prev = last;
- last = node;
- }
- }
- public void addIndex(int index,int data){
- //首先判断插入位置的合法性;
- if(index < 0 || index >size()){
- throw new ListIndexOutOfException();
- }
- //当下标为0-头插法
- if(index == 0){
- addFirst(data);
- return;
- }
- //当下标为size,尾插法
- if(index == size()){
- addLast(data);
- return;
- }
- //排除其他情况--正常插入
- //定义结点cur指向需要插入到的index位置
- ListNode cur = findIndex(index);
-
- ListNode node = new ListNode(data);
-
- cur.prev.next = node;
- node.prev = cur.prev;
- node.next = cur;
- cur.prev = node;
- }
- public void display(){
- ListNode cur = head;
- while(cur != null){
- System.out.print(cur.val +" ");
- cur = cur.next;
- }
- System.out.println();
- }
- public int size(){
- int len = 0;
- ListNode cur = head;
- while(cur != null){
- len++;
- cur = cur.next;
- }
- return len;
- }
- private ListNode findIndex(int index){
- ListNode cur = head;
- while (index != 0){
- cur = cur.next;
- index--;
- }
- return cur;
- }
- public boolean contains(int key){
- ListNode cur = head;
- while(cur != null){
- if(cur.val == key){
- return true;
- }
- cur = cur.next;
- }
- return false;
- }
- public void remove(int key){
- ListNode cur = head;
- while (cur != null){
- //判断cur的值和所要删除的值是否相同
- //相同
- if(cur.val == key){
- //这里需要分多种情况
- //1.删除的是头结点
- if(cur == head){
- head = head.next;
- //如果链表中有多个结点,则需要将前head.prev置空
- if(head != null){
- head.prev = null;
- }
- }else {//2.删除的不是头结点
- //删除的是尾巴结点
- if(cur.next == null){
- last = last.prev;
- cur.prev.next = null;
- }else {//删除的是中间结点
- cur.prev.next = cur.next;
- cur.next.prev = cur.prev;
- }
- }
- return;
- //不相同
- }
- cur = cur.next;
-
- }
- }
- public void removeAllKey(int key){
- ListNode cur = head;
- while (cur != null){
- //判断cur的值和所要删除的值是否相同
- //相同
- if(cur.val == key){
- //这里需要分多种情况
- //1.删除的是头结点
- if(cur == head){
- head = head.next;
- //如果链表中有多个结点,则需要将前head.prev置空
- if(head != null){
- head.prev = null;
- }
- }else {//2.删除的不是头结点
- //删除的是尾巴结点
- if(cur.next == null){
- last = last.prev;
- cur.prev.next = null;
- }else {//删除的是中间结点
- cur.prev.next = cur.next;
- cur.next.prev = cur.prev;
- }
- }
-
- //不相同
- }
- cur = cur.next;
-
- }
-
- }
- public void clear(){
- ListNode cur = head;
- while (cur != null){
- ListNode curNext = cur.next;
- cur.next = null;
- cur.prev = null;
- cur = curNext;
- }
- head = null;
- last = null;
- }