作业
-
class Test{ public static void hello(){ System.out.println("hello"); } } public class MyApplication { public static void main(String[] args) { Test test=null; test.hello(); } }
静态的方法,不依赖于对象的
-
public class MyApplication { String s; public static void main(String[] args) { String s; MyApplication myApplication = new MyApplication(); // System.out.println(s);报错 System.out.println(myApplication.s); } }
局部变量需要初始化,否则就报错,成员变量不初始化的话,会自动赋值默认值,例如上面的成员变量s,默认赋值为null;
-
public class Test { public int aMethod(){ static int i = 0; i++; return i; } public static void main(String args[]){ Test test = new Test(); test.aMethod(); int j = test.aMethod(); System.out.println(j); } }
方法中的变量i是静态变量,但是方法不是静态,编译失败。
-
public class Pvf{ static boolean Paddy; public static void main(String args[]){ System.out.println(Paddy); } 编译成功
双向链表
-
双向链表的节点构造
class ListNode{ private int val; public ListNode prev; public ListNode next; public ListNode(int val){ this.val=val; } }
-
创造头指针和尾指针
public ListNode head; public ListNode last;
-
头插法
public void addFirst(int data){ ListNode node = new ListNode(data); if (head==null){ head=node; last=node; }else{ head.prev=node; node.next=head; head=node; } }
-
尾插法
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; } }
-
删除第一次出现Key的节点
public void remove(int key){ ListNode cur=head; while(cur!=null){ if (cur.val==key){ if (cur==head){ head=head.next; head.prev=null; return; }else if (cur==last){ cur.prev.next=cur.next; last=last.prev; return; }else{ cur.prev.next=cur.next; cur.next.prev=cur.prev; return; } }else { cur=cur.next; } } System.out.println("该链表为空"); }
head=head.next;head.prev=null;head前面的节点没有被引用就会被jvm回收
上面的代码有一处代码会报空指针
head=head.next;head.prev=null;
如果此时head==null,那么head.prev就是空指针异常了,改进办法就是:
head=head.next; if (head!=null){ head.prev=null; } else{ last=null; }
-
删除所有出现Key的节点
将上面的代码中的return去掉
-
任意位置插入一个数据
public int size(){ return 0; } public ListNode searchIndex(int index){ ListNode cur =head; if (index<0||index>size()){ System.out.println("你输入数据不对"); return null; } while(index!=0){ cur=cur.next; index--; } return cur; } public void addIndex(int index,int data){ ListNode node =new ListNode(data); if (index==0){ addFirst(data); return; } if (index==size()){ addLast(data); return; } ListNode cur=searchIndex(index); if (cur!=null){ cur.prev.next=node; node.prev=cur.prev; node.next=cur; cur.prev=node; return; } }
-
将链表清除
public void clear(){ ListNode cur =head; while(cur!=null){ ListNode nextNode=cur.next; cur.prev=null; cur.next=null; cur=nextNode; } head=null; last=null; }
面试问题的总结
-
顺序表和链表的区别?
-
数组和链表的区别?
-
ArrayList和LinkedList的区别?
集合框架当中的两个类
集合框架就是将所有的数据结构,封装成了java自己的类
-
技巧:当面试官问到xxxx和xxxx的区别的时候,一般从共同点出发。
组织:
- 顺序表底层是一个数组,逻辑上和物理上都是连续的
- 链表是一个有若干节点组成的一个数据结构,逻辑上是连续的,但是在物理上(内存上)是不一定连续的
操作:
- 顺序表适合,查找相关的操作,因为可以使用下标,直接获取某个位置的元素
- 链表适合于,频繁的插入和删除操作,此时不需要像顺序表一样,移动元素,只需要修改指向。不支持随机访问
- 顺序表不好的的地方,看是否溢出,满了要扩容,扩容之后,不一定就能放完,所以空间利用率不高