目录
实现一个双向链表,可以对链表进行方法的实现。
一、定义方法
列出链表要实现的方法,定义成一个接口,让MyLinkList来实现。
java
public interface IList {
//打印
void display();
//头插法
void addFist(int data);
//尾插法
void addLast(int data);
//在任意位置插入
void addIndex(int index,int data);
//查找关键字key是否在单链表中
boolean contains(int key);
//删除第一个关键字为key的节点
void remove(int key);
//删除所有为key的节点
void removeAllKey(int key);
//单链表长度
int size();
//清空单链表
void clear();
}
二、实现方法
定义一个双向链表:
java
public class MyLinkList implements IList {
static class ListNode {
public int val;
public ListNode next;
public ListNode prev;
public ListNode(int val) {
this.val = val;
}
}
public ListNode head;
public ListNode last;
}
1、打印链表
定义一个节点cur从头节点开始对链表进行遍历,打印链表的值。
java
public void display() {
ListNode cur=head;
while (cur!=null){
System.out.print(cur.val+" ");
cur=cur.next;
}
System.out.println();
}
2、头插法
先定义出要插入的对象node,判断要插入的链表是否为空,为空中间让要插入的节点成为头节点,不为空就让插入的节点和头节点进行前后绑定,让新插入的节点成为新的头节点。
java
public void addFist(int data) {
ListNode node=new ListNode(data);
if (head==null){
head=node;
}else {
node.next=head;
head.prev=node;
head=node;
}
}
3、尾插法
先判断链表是否为空,为空直接让插入的节点成为新的头节点和尾节点,不为空新插入的节点和尾节点前后绑定,让新插入的节点成为新的尾节点。
java
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;
}
}
4、链表长度
定义一个节点cur,从头节点往后遍历,用count来记录遍历节点的个数,返回count就是链表的长度。
java
public int size() {
ListNode cur=head;
int count=0;
while (cur!=null){
count++;
cur=cur.next;
}
return count;
}
5、在任意位置插入
先定义一个异常,如果插入的位置错误,就抛出这个异常。定义一个findIndex方法来查找要插入节点的位置cur,cur在要插入的节点node后面。再判断插入的位置是否在链表的最前和最后,使用头插法和尾插法。在链表内部插入,让新插入的节点和cur绑定,然后和原来在cur前面的节点进行绑定。
在任意位置插入是在任意位置的后面插入
java
class CheckIndex extends RuntimeException {
public CheckIndex(String message) {
super(message);
}
}
private ListNode findIndex(int index) {
ListNode cur = head;
while (index != 0) {
cur = cur.next;
index--;
}
return cur;
}
public void addIndex(int index, int data) {
if (index < 0 || index > size()) {
throw new CheckIndex("插入位置异常");
}
if (index == 0) {
addFist(index);
}
if (index == size()) {
addLast(index);
}
ListNode node = new ListNode(data);
ListNode cur = findIndex(index);
node.next = cur;
cur.prev.next = node;
node.prev = cur.prev;
cur.prev = node;
}
6、判断是否包含目标节点
先判断链表是否为空,不为空就让cur从头节点往后进行遍历,找到目标节点就返回ture,没有找到就返回false。
java
public boolean contains(int key) {
if (head==null){
System.out.println("链表为空");
}else {
ListNode cur=head;
while (cur!=null) {
if (cur.val == key) {
return true;
}
cur=cur.next;
}
}
return false;
}
7、删除key节点
让cur从头节点往后进行遍历,找到要删除的节点,判断节点所在位置。在头节点,判断是否链表中只有头节点这一个节点,只有这一个节点就将last置为空,不只有这一个节点,就让让新的头节点的prev置为空。要删除的节点在链表中或者在链表的最后,让要删除的节点的前后节点进行绑定,如果是最后的节点,让last等于前一个节点。
java
public void remove(int key) {
ListNode cur=head;
while (cur!=null){
if (cur.val==key){ //有这个值
if (cur==head){ //head等于这个值
head=head.next;
if (head==null){ //就head这一个节点
last=null;
}else {
head.prev=null; //还有其他节点
}
}else {
cur.prev.next=cur.next;
if (cur.next==null){ //last等于这个值
last=last.prev;
}else {
cur.next.prev=cur.prev; //除head和last等于这个值
}
}
return;
}
cur=cur.next;
}
}
8、删除所有为key的节点
删除所有为key的节点,就是让cur继续向后进行遍历,找到目标节点进行删除。
java
public void removeAllKey(int key) {
ListNode cur = head;
while (cur != null) {
if (cur.val == key) { //有这个值
if (cur == head) { //head等于这个值
head = head.next;
if (head == null) { //就head这一个节点
last = null;
} else {
head.prev = null; //还有其他节点
}
} else {
cur.prev.next = cur.next;
if (cur.next == null) { //last等于这个值
last = last.prev;
} else {
cur.next.prev = cur.prev; //除head和last等于这个值
}
}
}
cur=cur.next;
}
}
9、清空链表
让cur从头节点往后进行遍历,将节点的next和prev都置为空,如果节点中存入的是引用数据类型,将节点的val也置为空
java
public void clear() {
ListNode cur=head;
while (cur!=null){
ListNode tmp=cur.next;
cur.prev=null;
cur.next=null;
cur=tmp;
}
head=null;
last=null;
}
三、使用方法
定义一个Main类,来对方法进行使用。
java
public class Main {
public static void main(String[] args) {
MyLinkList myLinkList1=new MyLinkList();
myLinkList1.addLast(1);
myLinkList1.addLast(2);
myLinkList1.addLast(3);
myLinkList1.addLast(4);
myLinkList1.addLast(1);
myLinkList1.addFist(2);
myLinkList1.display();
myLinkList1.addIndex(3,5); //插入是插入到输入位置的后面
myLinkList1.display();
System.out.println(myLinkList1.contains(2));
System.out.println(myLinkList1.contains(6));
myLinkList1.remove(2);
myLinkList1.display();
myLinkList1.removeAllKey(1);
myLinkList1.display();
myLinkList1.clear();
myLinkList1.display();
}
}
执行结果:
2 1 2 3 4 1
2 1 2 5 3 4 1
true
false
1 2 5 3 4 1
2 5 3 4
以上就是对双向链表进行简单的实现