链表之双向链表
话不多说,直接看代码,你懂的!!!!!!
无头双向链表的定义:
class ListNode {
public int val;
public ListNode next;
public ListNode prev;
public ListNode(int val) {
this.val = val;
}
}
public class DoubleList {
public ListNode head;
public ListNode last;//永远标志双向链表的尾巴
//下面写方法
}
无头双向链表的实现:
class ListNode {
public int val;
public ListNode next;
public ListNode prev;
public ListNode(int val) {
this.val = val;
}
}
public class DoubleList {
public ListNode head;
public ListNode last;//永远标志双向链表的尾巴
//头插法
public void addFirst(int data){
ListNode node = new ListNode(data);
if(this.head == null) {
this.head = node;
this.last = node;
}else {
node.next = this.head;
this.head.prev = node;
this.head = node;
}
}
//尾插法
public void addLast(int data){
ListNode node = new ListNode(data);
if(this.head == null) {
this.head = node;
this.last = node;
}else {
this.last.next = node;
node.prev = this.last;
this.last = node;
}
}
public ListNode searchIndex(int index) {
if(index < 0 || index > size()) {
return null;
}
ListNode cur = this.head;
while (index != 0) {
cur = cur.next;
index--;
}
return cur;
}
//任意位置插入,第一个数据节点为0号下标
public void addIndex(int index,int data){
if(index == 0) {
addFirst(data);
return;
}
if(index == size()) {
addLast(data);
return;
}
ListNode node = new ListNode(data);
ListNode cur = searchIndex(index);
if(cur == null) {
return;
}
node.next = cur;
cur.prev.next = node;
node.prev = cur.prev;
cur.prev = node;
}
//查找是否包含关键字key是否在单链表当中
public boolean contains(int key){
ListNode cur = this.head;
while (cur != null) {
if(cur.val == key) {
return true;
}
cur = cur.next;
}
return false;
}
//删除第一次出现关键字为key的节点
//返回值代表你要删除的数字
public void remove(int key){
ListNode cur = this.head;
while (cur != null) {
if(cur.val == key) {
if(this.head.val == key) {
this.head = this.head.next;
this.head.prev = null;
}else {
cur.prev.next = cur.next;
if(cur.next!=null) {
//当前的cur不是最后一个节点
cur.next.prev = cur.prev;
}else {
this.last = this.last.prev;
}
}
return;
}else {
cur = cur.next;
}
}
}
//删除所有值为key的节点
public void removeAllKey(int key){
ListNode cur = this.head;
while (cur != null) {
if(cur.val == key) {
if(this.head.val == key) {
if(this.head.next == null) {
this.head = null;
return;
}
this.head = this.head.next;
this.head.prev = null;
}else {
cur.prev.next = cur.next;
if(cur.next!=null) {
//当前的cur不是最后一个节点
cur.next.prev = cur.prev;
}else {
this.last = this.last.prev;
}
}
}
cur = cur.next;
}
}
//得到单链表的长度
public int size(){
int count = 0;
ListNode cur = this.head;
while (cur != null) {
count++;
cur = cur.next;
}
return count;
}
public void display(){
ListNode cur = this.head;
while (cur != null) {
System.out.print (cur.val+" ");
cur = cur.next;
}
System.out.println();
}
public void clear(){
this.last = null;
this.head = null;
}
}
测试:
public class TestDemo {
public static void main(String[] args) {
DoubleList doubleList = new DoubleList();
doubleList.addLast(4);
doubleList.addLast(4);
doubleList.addLast(4);
doubleList.addLast(4);
//等等
}
}
总结一下:无头双向链表比较简单,还是要注意插入时next,和prev的顺序关系
下面是有头双向链表,参考一下:
package test01;
class ListNode{
public int val;
public ListNode next;
public ListNode prev;
public ListNode(int val) {
this.val = val;
}
}
public class DoubleLinkedList {
public ListNode dummyHead;//头
public ListNode last;//尾巴
public DoubleLinkedList () {
this.dummyHead = new ListNode(-1);
}
//头插法
public void addFirst(int data) {
ListNode node = new ListNode(data);
if (this.dummyHead.next == null) {
this.dummyHead.next = node;
node.prev = this.dummyHead;
this.last = node;
return;
}
node.next = dummyHead.next;
node.prev = this.dummyHead;
dummyHead.next.prev = node;
dummyHead.next = node;
}
//尾插法
public void addLast(int data) {
ListNode node = new ListNode(data);
if (this.dummyHead.next == null) {
this.dummyHead.next = node;
node.prev = this.dummyHead;
last = node;
return;
}
last.next = node;
node.prev = last;
last = node;
}
//
//任意位置插入,第一个数据节点为0号下标
public void addIndex(int index,int data) {
ListNode node = new ListNode(data);
if (index < 0 || index > size()) {
System.out.println("下标不合法");
return;
}
if (index == 0) {
addFirst(data);
return;
}
if (index == size()) {
addLast(data);
return;
}
ListNode cur = dummyHead.next;
while (index > 0) {
cur = cur.next;
index--;
}
if (cur == null) {
return;
}
cur.prev.next = node;
node.next = cur;
node.prev = cur.prev;
cur.prev = node;
}
//查找是否包含关键字key是否在链表当中
public boolean contains(int key) {
ListNode cur = this.dummyHead.next;
while (cur != null) {
if (cur.val == key) {
return true;
}
cur = cur.next;
}
return false;
}
//删除第一次出现关键字为key的节点
public void remove(int key) {
ListNode cur = this.dummyHead.next;
while (cur != null) {
if (cur.val == key) {
if (cur == last) {
cur.prev.next = cur.next;
}else {
cur.prev.next = cur.next;
cur.next.prev = cur.prev;
}
return;
}else {
cur = cur.next;
}
}
}
//删除所有值为key的节点
public void removeAllKey(int key) {
ListNode cur = this.dummyHead.next;
while (cur != null) {
if (cur.val == key) {
if (cur == last) {
cur.prev.next = cur.next;
}else {
cur.prev.next = cur.next;
cur.next.prev = cur.prev;
}
}
cur = cur.next;
}
}
//得到带傀儡节点双链表的长度
public int size() {
ListNode cur = this.dummyHead.next;
int count = 0;
while (cur != null) {
cur = cur.next;
count++;
}
return count;
}
//遍历
public void display() {
ListNode cur = dummyHead;
while (cur != null) {
System.out.print(cur.val + " ");
cur = cur.next;
}
System.out.println();
}
public void clear() {
this.dummyHead.next = null;
this.last = null;
}
}
测试:
package test01;
public class testdemo01 {
public static void main(String[] args) {
DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
// doubleLinkedList.addFirst(1);
// doubleLinkedList.addFirst(2);
doubleLinkedList.addLast(11);
doubleLinkedList.addLast(11);
doubleLinkedList.addLast(11);
doubleLinkedList.addLast(11);
// doubleLinkedList.addIndex(3,11);
doubleLinkedList.display();
doubleLinkedList.removeAllKey(11);
// doubleLinkedList.addFirst(3);
// doubleLinkedList.addFirst(4);
// doubleLinkedList.addFirst(5);
doubleLinkedList.display();
int ret = doubleLinkedList.size();
System.out.println(ret);
// doubleLinkedList.clear();
// System.out.println("jfkldsafkdlaf");
// doubleLinkedList.display();
// int ret1 = doubleLinkedList.size();
// System.out.println(ret1);
}
}
有头双向链表比较简单,不是主要的,了解就行