在实现双向链表前,我们需要定义一个链表类,
public class LinkedList {
//定义一个静态内部类,节点
static class ListNode{
ListNode prev;
ListNode next;
int val;
//给定一个带有参数的构造方法
public ListNode(int val) {
this.val = val;
}
}
//分别定义一个指向头节点和尾节点的引用
ListNode head;
ListNode last;
}
在定义好了类中的基本成员和构造方法后,我们可以对类中要实现的方法进行编写
1.头插法
public void addFirst(int data){
//开辟一个节点
ListNode node=new ListNode(data);
//若链表为空,此时head和last指向唯一的节点
if(head==null){
head=last=node;
}else {
node.next=head;
node=head.prev;
head=node;
}
}
2.尾插法
public void addLast(int data) {
//开辟一个节点
ListNode node=new ListNode(data);
//若链表为空,此时head和last指向唯一的节点
if(head==null){
head=last=node;
}else {
last.next=node;
node.prev=last;
last=node;
}
}
3.任意位置插入
public void addIndex(int index,int data){
if(index<0||index>size()){
System.out.println("插入位置错误");
return;
}
if(index==0){
addFirst(data);
return;
}
if(index==size()){//size()计算链表长度
addLast(data);
return;
}
ListNode node=new ListNode(data);
ListNode cur=searchIndex(index);//找到要插入的位置节点
node.next=cur;
cur.prev.next=node;
node.prev = cur.prev;
cur.prev = node;
}
4.找到要插入位置
public ListNode searchIndex(int index){
ListNode cur=head;
int count=0;
while(count!=index){
cur=cur.next;
count++;
}
return cur;
}
5.求链表长度
public int size(){
int count=0;
ListNode cur=head;
while (cur!=null){
count++;
cur=cur.next;
}
return count;
}
6.链表的打印
public void display(){
ListNode cur=head;
while (cur!=null){
System.out.print(cur.val+" ");
cur=cur.next;
}
}
7.查找是否包含关键字key是否在单链表当中
public boolean contains(int key){
ListNode cur = head;
while (cur != null) {
if(cur.val == key) {
return true;
}
cur =cur.next;
}
return false;
}
8.删除第一次出现关键字为key的节点
public void removeKey(int key){
//1.链表为空
if(head==null){
return;
}
//2.链表不为空
ListNode cur=head;
while (cur!=null){
if(cur.val==key){
//如果头节点为要删除关键字为key的节点
if(head==cur){
//如果头节点的next为空,则说明当前链表中只有一个节点,需要把head和last都置空
if(head.next==null){
head=last=null;
return;//删除一次后直接退出,否则会造成多次删除
}else{
//若链表中有多个节点
head.next.prev=null;
head=head.next;
return;//删除一次后直接退出,否则会造成多次删除
}
}//ok
//若走到了尾节点,说明没有进入head==cur的判断,说明链表不可能只有一个节点,所以不用考虑节点为1个的情况
if(last==cur){
last.prev.next=null;
return;
}//ok
cur.prev.next=cur.next;
cur.next.prev=cur.prev;
return;//删除一次后直接退出,否则会造成多次删除
}
cur=cur.next;
}
}
9.链表的清空
public void clear(){
ListNode cur = head;
while (cur != null) {
ListNode curN = cur.next;
cur.next = null;
cur.prev = null;
cur = curN;
}
head = null;
last = null;
}
以上,就是双向链表的基本操作,谢谢大家!