1、模板链表
描述
请你实现一个链表。
方法:
insert x y:将y加入链表,插入在第一个值为x的结点之前。若链表中不存在值为x的结点,则插入在链表末尾。保证x,y为int型整数。
delete x:删除链表中第一个值为x的结点。若不存在值为x的结点,则不删除。
class LinkList {
//利用数组存储链表值
int[] data;
//设置链表长度
int size;
//设置链表头
int front = 0;
//设置链表尾
int rear = 0;
//链表构造器
public LinkList(int size) {
data = new int[size];
}
//重新tostring方法,按照想要的方式输出对象值
public String toString(){
String str="";
for(int j=0;j<rear;j++){
str+=data[j]+" ";
}
return str;
};
public boolean isEmpty(){
return size==0?true:false;
}
//往链表中加元素,规则为如果链表中存在x元素,则将y插入到x之前,没有的话就插入到链表尾
public void insert(int x, int y) {
//设置一个flag判断是否有x元素在数组中
int b = -1;
//表明数组满了,所以要进行数组扩容
if (size == data.length) {
//利用Arrays.copyof方法将满的数组赋值到新的数组,并且设置新的数组长度为原来数组长度的两倍
int[] temp = Arrays.copyOf(data, data.length * 2);
//将新数组赋值给旧的数组
data = temp;
//数组没满,就可以判断是否有x元素在数组内
} else {
//遍历链表看是否有x元素,如果有就将元素x的位置赋值给b
for (int i = 0; i < data.length; i++) {
if (data[i] == x) {
b = i;
//找到第一个元素x的位置就退出遍历
break;
}
}
//利用b的值判断链表中是否有x元素,如果b==-1就没有
if (b == -1) {
//将尾指针的位置赋值y,并且将rear指针后移
data[rear++] = y;
//链表大小+1
size++;
//b不等于-1就表示链表中有x元素
} else {
//遍历链表数组将b位置的元素后移一位
for (int i = rear; i > b; i--) {
data[i] = data[i - 1];
}
data[b] = y;
rear++;
size++;
}
}
}
//删除第一个指定元素
public void delete (int x) {
//设置一个flag判断链表中是否有x
int b = -1;
//判断链表是否为空
if (size == 0) {
return;
} else {
//遍历链表数组,看是否有x元素
for (int i = 0; i < rear; i++) {
//如果存在就保存x的位置给b,然后跳出遍历
if (data[i] == x) {
b = i;
break;
}
}
//判断是否操作x元素值,如果b不等于-1就表示有
if(b!=-1){
//遍历元素将元素前移动一个位置
for(int i=b;i<rear;i++){
data[i]=data[i+1];
}
//尾指针-1和链表大小-1
rear--;
size--;
}
}
}
}
2、思想
本次数组存储实现链表的关键是用数组来存储链表节点的值,在实现插入方法的时候要判断链表是不是已经满了,如果满了就进行扩容,就是通过扩大一倍数组,然后将原来数据存储在新的数组中,如果不是满的,那么根据要求还得判断链表中是否有x元素,如果有的话就得将y元素存储在x元素之前,这就是要求对x元素及其以后的元素要往后移动一位,如果没有的话就直接存储在链表的尾部。在实现删除的方法的时候,要判断x元素是否存在数组中,如果存在的话要对该元素后面的元素进行往前移动一位,如果不存在就不用操作。
3、节点实现链表
public static class ListNode {
//节点值
public int val;
//下一个节点的位置
public ListNode next;
//节点构造器
public ListNode(int val){
this.val=val;
}
}
//创建一个头结点,头结点值为-1
public static ListNode head=new ListNode(-1);
//往链表插入节点
public static void insert(int x,int y){
//创建一个值为y的新节点
ListNode newNode=new ListNode(y);
//将头节点赋值给名为node的节点
ListNode node=head;
//设置一个标志
int sign=0;
//如果node的下一个节点不是null
while(null!=node.next){
//如果下一个节点的节点值是x
if(node.next.val==x){
//将新建的节点的下一个节点设置为node的下一个节点
newNode.next=node.next;
//
node.next=newNode;
//将标志设置为1,表示已经插入了
sign=1;
//跳出循环
break;
}
//将下一个节点设置为下一次循环的节点
node=node.next;
}
//判断flag,如果flag==0表示上面的代码没有插入节点
if(sign==0){
//将新建的节点赋值给节点尾
node.next=newNode;
}
}
//删除节点值为x的节点
public static void delete(int x){
//创建一个头结点
ListNode node=head;
//如果下一个节点不是null的条件实现遍历链表
while(node.next!=null){
//判断下一个节点的节点值是否为x
if(node.next.val==x){
//如果是的话就将node的下一个节点设置为node的下一个的下一个节点
node.next=node.next.next;
//跳出循环
break;
}
//将node设置为下一个节点
node=node.next;
}
}
4、思想:本次利用节点实现链表主要是利用while语句实现对链表的遍历,在此前提是节点类要设置节点值和下一个节点,然后利用下一个节点不是null实现对链表的遍历,每次遍历最后都得将节点设置为下一个节点,在遍历也可以实现对节点值的访问。本次实现利用static将头节点固定了!!!
5、对比:数组实现和节点实现链表相比,数组实现的代码更多,也更加需要维护,链表实现的话每次加一个节点就是new了一个节点对象。个人感觉数组实心对于初学者更容易理解,但是个人推荐节点实现链表,因为数组实现插入和删除时可能要移动多个数据,节点实现的话就不需要这么麻烦。