目录
一.查看底层源码
或者转到对应函数
测试代码要两边中间都要查
二.建立类
在以类名建立的文件下才可以用pUBLIC修饰,其他的都不可以
三.引用变量(后期重点看)
变量的实质就是一小块内存单元
当变量指向一个对象的时候,这个变量就被称为引用变量
a指向了一个A对象,或者说a引用了一个A对象.我们通过操纵这个a来操作A对象.此时,变量a的值就是为他所引用对象的地址.
java的引用变量实际上是一个指针,是指向的堆内存中的对象实例,相当于为数组或者对象气的一个别名,就可以从程序中使用栈中的引用变量来访问堆上的数组或者对象.
所以我们可以得知这里为什么Next就可以用Mynode为类型,并且类的对象名就是一个地址
四.查找关键字看是否在单链表中
建立返回值boolean
public boolean search(int k){
MyNode cul=this.head;
while (cul!=null){
if(cul.val==k){
return true;
}
cul=cul.Next;
}
return false;
}
五.得到单链表长度
public int linkLen(){
int count=0;
MyNode cul=head;
while(cul!=null){
cul=cul.Next;
count++;
}
return count;
}
}
六.头插法
//头插法
public void addFirst(int data){
MyNode node=new MyNode(data);//->建立一个节点将数据放入节点中
node.Next=this.head;
this.head=node;//如果是空的表,head就是null.就相当于插入第一个元素方法1所以不需要判断是否有
/* if(head==null){//方法2
this.head=node;
}else{
node.Next=this.head;
this.head=node;
}*/
}
单链表的增删查改要注意是否为空表.
七.尾插法
这里注意如果是空表,head的NEXt是空的,
会有空指针异常
public void addList(int data){
MyNode node=new MyNode(6);
if(head==null) {
//先判断是否是空表
node.Next=null;
this.head=node;
}
MyNode cul=this.head;
while(cul.Next!=null){
//如果判断条件是cul直接变成空指针,就没办法插入了根本找不到了\
cul=cul.Next;
}//这里就来到了尾结点
cul.Next=node;//链接在一起了
node.Next=null;//因为是尾结点
}
八.任意位置插入
1.插入任何元素都要注意位置是否合法
2.插入的时候注意是否是空表,但是第一步已经判断过了,就算是空表并且要在第0个位置
插入那还是一样的,程序冗余了,所以不需要再判断了.
3.如果是头尾直接引入函数
4.找到index前的一个节点,来插入
//任意位置插入,(第一个数据节点为0的下标)
public void addIndex(int index,int data){
//第一步要先判断是否合法
int len=linkLen();
if(index<0||index>len-1){
System.out.println("不合法");return;
}
MyNode node=new MyNode(data);
/*if(head==null) {
//先判断是否是空表
if(index==0){
this.head=node;
}
return;
}*/
if(index==0){//如果是头节点
addFirst(data);
return;
}
if(index==len-1){//如果是尾结点直接引入尾插法函数
addList(data);
return;
}
//函数到了这里就是去掉头尾的地方了.就用正常方式
MyNode cul=head;
/*int count=0;
while(count==index){
cul=cul.Next;
count++;
}//循环结束,就找到了下标为index的元素很明显我们需要index前的一个元素这里为了方便我们构建一个寻找下标的函数.*/
cul=searchSubsricpt(index-1);
node.Next=cul.Next;
cul.Next=node;
}
//找寻下标为index的元素
public MyNode searchSubsricpt(int index) {
//还要判断是否合法
int len=linkLen();
if(index<0||index>len-1){
System.out.println("不合法");return null;
}
int count = 0;
MyNode cul = head;
while (count == index) {
cul = cul.Next;
count++;
}
return cul;
}
九.查找是否包含关键字KEY
这里注意不需要判断是否是空表,需要跟之前的区分开不要混淆.
.如果cur已经是空指针,就不存在cur,next这一步会报错.
而这里,因为cul已经是空指针无法进入循环所以不会报错
//查找是否包含关键字key是否在单链表当中
public boolean searchKey(int key){
//if(head==null) return -1;//如果是空表后期会空指针异常
MyNode cul=this.head;
//int count=0;
while(cul!=null){
if(cul.val==key){
return true;
}
cul=cul.Next;
}
return false;
}
十.isEmpty和null的区别
.isEmpty是对象是否为空(IsNull),null是值为空(IsEmpty)
isEmpty() 用于判断List内容是否为空,必须在 list 本身不是空的引用的情况下才行;
null 用于判断有没有这个集合对象;
是否为空 IsNull函数:
功能:返回Boolean的值,指明表达是否不包含任何有效数据。NULL表示的是数据值未知或不可用,它不表示零(数字值或二进制值)、零长度的字符串或空白(字符值)。
IsEmpty函数:
功能:用于判断一个变量是否已初始化,如果变量未初始化或显式地设置为Empty,则函数IsEmpty返回True;否则函数返回False
举个栗子说就是假如一个容器,null是用来判断有没有这个容器,而isEmpty是有这个容器,来判断这个容器中的内容有没有东西是不是空的!
十二.删除第一次出现关键字为key的节点
1.我的方法
首先出现了报错,是因为我的if语句没有写好,这里其他的方法是判断了一下是否表是空的,我这里没有
因为我的方法一开始就判断表里是否有这个关键字,没有直接返回.
这里我在测试最后一个元素出现了问题,因为我发现我没有写如果条件不满足的循环增加,导致变成了死循环
我这里的思路就是先判断是否有,然后判断表头是否有,因为后期的循环无法看到表头,
先建立一个变量放在要删除的元素前面(这一块是这道题的重点)
///删除第一次出现关键字为key的节点
public void remove(int key){
boolean a=searchKey(key);
if(a==false) return;
MyNode cul=this.head;
MyNode prev=this.head;
if(head.val==key){
this.head=head.Next;
return;
}
while(cul!=null){
if(cul.Next.val==key){
prev=cul;
cul=cul.Next;
prev.Next=cul.Next;
return;
}
cul=cul.Next;
}
}
2.其他方法
public void teacherRomove(int key){
if(this.head==null){
System.out.println("单链表为空");
return;
}
if(this.head.val==key){
this.head=this.head.Next;
return;
}
MyNode cul=searchKey1(key);
if(cul==null){
System.out.println("没有要找的元素");
return;
}
MyNode del=cul.Next;//如果del是最后一个元素.del.NEXT就是NULL
cul.Next=del.Next;
}
public MyNode searchKey1(int key){
MyNode cul=this.head;
while(cul.Next!=null){
if(cul.Next.val==key){
return cul;
}
cul=cul.Next;
}
return null;
}
思路:先判断是否为空,因为如果不判断.可能会空指针异常.然后判断表头是否是,
再建立一个变量来接收找寻关键字前面一个函数的值
注意!
十三,删除列表里关键字为key的所有元素
1.注意要判断是否为空,否则会空指针异常
2.多画图
3.最后一步处理头节点的时候,因为被删除的元素无人引用就自动被回收了
//删除表中所有值为key的节点 public void removeAllKey(int key){ if(this.head==null){ System.out.println("表为空"); return; } MyNode prev=head; MyNode cul=head.Next;//这里如果不判断,会显示空指针异常 while(cul!=null){ if(cul.val==key){ cul=cul.Next;//如果是最后一个元素,cul就变成空指针了 prev.Next=cul; }else{ prev=cul;//一定要跟一下,不然假如前面没有,会导致prev的Next放入cul的地址但是val还是别人的 cul=cul.Next; } } if(head.val==key){ head=head.Next;//因为被删除的元素没人引用就会被回收 } }
十四.清空表
1.粗暴方法
直接把头节点变成空
2.把表中元素一个个变成空
//清空表
public void clear(){
//粗暴方法
//this.head=null;
MyNode node=this.head;
// MyNode cul=this.head;
while(node!=null){
node=this.head.Next;
this.head=null;
this.head=node;
}
}
十五.查看进程
第一步打断点先调试
第二步.进入文件找到OUT目录
第三步.按住shift打开powershell窗口
输入jps得到进程号
第四步输入TestSun的进程号
将得到的文件放入指定文件夹
第五步,完成剩下的调试
这样就可以在对应文件夹下看到
第六步分析
这里instances表示当前代码下有多少实例
CTRL+f找一下mynode情况
表示有五个节点11.2