目录
结构框图
下面的是头插法,傀儡节点一直是头节点,是不会变动的,所以头插法只能从傀儡节点下一个插入
其他方法和不带头的双链表是差不多的
链表源码
class ListNode {
public int val;
public ListNode prev;
public ListNode next;
public ListNode(int val) {
this.val = val;
}
}
//带头傀儡节点双链表
public class HeadLinkedList {
public ListNode head = new ListNode(-1);//傀儡节点
public ListNode last;
//头插法
public void addFirst(int data) {
ListNode node = new ListNode(data);
//1.链表中只有傀儡节点的情况下
if(this.head.next == null) {
this.head.next = node;
node.prev = this.head;
this.last = node;
}else {
//链表中有两个节点起,从后面往前连
node.next = this.head.next;
this.head.next.prev = node;
this.head.next = node;
node.prev = this.head;
}
}
//尾插法
public void addLast(int data) {
ListNode node = new ListNode(data);
if (this.head.next == null) {
this.head.next = node;
node.prev = this.head;
this.last = node;
}else {
this.last.next = node;
node.prev = this.last;
this.last = node;
}
}
//打印链表
public void display() {
ListNode cur = this.head;
while (cur != null) {
System.out.print(cur.val+" ");
cur = cur.next;
}
System.out.println();
}
//找到要插入的位置
public ListNode searchIndex (int index) {
ListNode cur = this.head;
while (index != 0) {
cur = cur.next;
index--;
}
return cur;
}
//任意位置插入(先找到要插入的位置),第一个数据节点为0下标
public void addIndex(int index,int data) {
ListNode node = new ListNode(data);
//不合法情况
if (index < 0 || index >size()) {
System.out.println("index位置不合法");
return;
}
//头插
if (index == 0) {
addFirst(data);
return;
}
//尾插
if (index == size()) {
addLast(data);
return;
}
//中间部位插
ListNode cur = searchIndex(index);
node.next = cur;
cur.prev.next = node;
node.prev = cur.prev;
cur.prev = node;
}
//链表的长度
public int size() {
ListNode cur = this.head;
int count = 0;
while (cur != null) {
count++;
cur = cur.next;
}
return count;
}
//查找是否包含关键字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.next;
while (cur != null) {
if (cur.val == key) {
//从第二个开始
if (this.head.next.val == key) {
this.head.next = cur.next;
cur.next.prev = this.head;
} else {
//中间位置
cur.prev.next = cur.next;
if (cur.next != null) {
cur.next.prev = cur.prev;
} else {
//删了尾巴就往前走
this.last = this.last.prev;
}
}
return;
}
cur = cur.next;
}
}
//删除重复节点//考虑的位置和无头链表有区别(要注意)
public void removeAllKey(int key) {
//因为第一个是傀儡节点,所以从第二个开始
ListNode cur = this.head.next;
while (cur != null) {
if (cur.val == key) {
//从第二个开始
if (this.head.next.val == key) {
this.head.next = cur.next;
cur.next.prev = this.head;
}else {
//中间位置
cur.prev.next = cur.next;
if (cur.next != null) {
cur.next.prev = cur.prev;
}else {
this.last = this.last.prev;
}
}
// return;//就是在删除一次的前提下继续往后走,直到走完链表
}
cur = cur.next;
}
}
//清空链表
public void clear() {
ListNode cur = this.head;
while (cur != null) {
ListNode curNext = cur.next;
cur.next = null;
cur.prev = null;
cur = curNext;
}
//傀儡节点最后再清空
head = null;
this.last = null;
}
}
函数主体
里面是链表的一些方法实现展示
public class TestDemo {
public static void main(String[] args) {
HeadLinkedList headLinkedList = new HeadLinkedList();
System.out.print("头插:");
headLinkedList.addFirst(2);
headLinkedList.addFirst(5);
headLinkedList.display();
System.out.print("尾插:");
headLinkedList.addLast(2);
headLinkedList.addLast(5);
headLinkedList.display();
int ret = headLinkedList.size();
System.out.println("链表长度:"+ret);
System.out.print("任意位置插入:");
headLinkedList.addIndex(2,10);
headLinkedList.display();
headLinkedList.remove(2);
System.out.print("删除第一次出现关键字2后:");
headLinkedList.display();
int ret2 = headLinkedList.size();
System.out.println("链表长度:"+ret2);
headLinkedList.removeAllKey(5);
System.out.print("删除关键字为5后:");
headLinkedList.display();
headLinkedList.clear();
System.out.print("清空链表后:");
headLinkedList.display();
}
}
扫描二维码关注公众号,回复:
14313562 查看本文章