目录
创建链表
BothwayLinkList类相当于火车类存头节点,尾节点和链表的长度,Node类相当于火车的车厢,存放具体节点的值,和该节点的前驱和后继
public class BothwayLinkList {
int size;
Node head;
Node tail; //尾节点
class Node{
int val;
Node prev;//前驱
Node next;//后继
public Node(int val){this.val=val;}
public Node(Node prev,int val,Node next){
this.prev=prev;
this.next=next;
this.val=val;
}
}
插入节点
1.在头部插入:
public void firstIndex(int val){//头插
Node node=new Node(null,val,head);
if(head==null){
tail=node;
}else {
head.prev=node;
} head=node;
size++;
}
2.在尾部插入:
public void addLast(int val){//尾插
Node node =new Node(tail,val,null);
if (tail==null){
head=node;
}else {
tail.next = node;
}tail=node;
size++;
}
3.在中间位置插入:注意下标(index)是从0开始!
public void addIndex(int index,int val){//在下标为index位置插入值为val的节点
if(index<0||index>size){
System.out.println("illegal!!!");
return;
}else if(index==0){
firstIndex(val);
}
else if (index==size){
addLast(val);
}
else {
Node front=find(index-1);//front是待插入节点的前驱
Node node=new Node(front,val,front.next);
front.next=node;
front.next.prev=node;
size++;
}
}
查找
下面两个方法是为后面的操作做准备,会被多次调用
找索引index对应的节点
private Node find(int index) {//找index对应的节点
Node ret=null;
if (index<size>>1){//从头开始找
ret=head;
for (int i = 0; i <index; i++) {
ret=ret.next;
}
}else {//此时从后向前找
ret=tail;
for (int i = size-1; i > index; i--) {
ret=ret.prev;
}
}return ret;
}
判断用户输入的索引是否合法:
private boolean judgeIll(int index) {//判断合法性
if (index<0||index>=size){return false;
}
return true;
}
1.查找链表中是否含有某个值
public boolean seekVal(int val){//查找值
for (Node temp = head;temp !=null;temp=temp.next) {
if (temp.val==val){
return true;
}
}return false;
}
2.查找某个节点对应的值为多少:调用上面的find()方法找到对应的节点
public int get(int inddex){//查索引对应的值
if(judgeIll(inddex)==true){
return find(inddex).val;//调用方法找到该节点
}else {
System.out.println("输入位置非法");
return -1;
}
}
修改
public int changeVal(int index,int newval){//修改索引对应的值并返回原来的值
if (judgeIll(index)){
int oldVal=find(index).val;
find(index).val=newval;
return oldVal;
}return -1;//输入不合法,返回-1
}
删除
1.删除指定节点:这里采用分治思想,先处理节点的前半部分,再处理后半部分
private void unlink(Node node){//在链表中删除指定节点
Node prev=node.prev;
Node next=node.next;
if (prev==null){//先处理前半部分
head=next;
}else{
prev.next=next;
node.prev=null;
}
if (next==null){//接着处理后半边
tail=prev;
}else {
next.prev=prev;
node.next=null;
}size--;
}
2.删除索引位置的节点:
public void removeIndex(int index){
if(judgeIll(index)){
Node node=find(index);//找到该位置的节点
unlink(node);
}else {
System.out.println("illegal!");
}
}
public void removeFirst(){//删头
removeIndex(0);
}
public void removeLast(){//删尾
removeIndex(size-1);
}
3.删除某个值(只删除第一次出现的值):
public void removeOnce(int val){
for(Node x=head;head!=null;x=x.next){
if (x.val==val){
Node next=x.next;
unlink(x);//调用unlink方法删除x节点
break;
}
}
}
4.删除某个值(对应的值全部删除):
public void removeValAll(int val){
for (Node x=head;x!=null;) {
if (x.val==val){
Node next=x.next;//next是下一个要判断的节点
unlink(x);
x=next;
}else {//继续向后走
x=x.next;
}
}
}
输出语句
public String toString(){
String ret=" ";
Node prev=head;
//LinkLIST.NewNode prev=head;
while (prev!=null){
ret+= prev.val;
ret+="-->";
prev=prev.next;
}
ret+="NULL";
return ret;
}
测试结果
public class Test3 {//双链表的测试
public static void main(String[] args) {
BothwayLinkList b=new BothwayLinkList();
b.firstIndex(7);
b.firstIndex(8);
System.out.println(b);
b.addLast(5);
b.addLast(1);
System.out.println(b);//8>7>5>1
b.addIndex(0,2);
System.out.println(b);//2>8>7>5>1
b.addIndex(6,9);
System.out.println(b);//illegal
b.addIndex(3,7);
System.out.println(b);
System.out.println(b.seekVal(2));
System.out.println(b.seekVal(9));
System.out.println(b.get(2));
System.out.println(b.changeVal(2,10));
b.removeIndex(2);
System.out.println(b);
b.removeOnce(8);
System.out.println(b);
}
}
输出结果为: