顺序表
用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储,在数组上完成数据的增删改查。
打印顺序表
public void display() { for (int i = 0; i < useSize; i++) { System.out.println(this.elem[i]+" "); } System.out.println(); }
在数组最后新增元素
public void add(int data) { if (isFull()){ elem= Arrays.copyOf(elem,2*elem.length); } elem[useSize]=data; useSize++; }
在指定位置新增元素
public void add(int pos, int data) { try{ checkAddPos(pos); if (isFull()){ elem= Arrays.copyOf(elem,2*elem.length); } for (int i = useSize-1; i > pos; i--) { elem[i+1]=elem[i]; } elem[pos]=data; useSize++; }catch (PosIndexNotLegalException e){ e.printStackTrace(); } }
判断是否包含某个元素
public boolean contains(int toFind) { for (int i = 0; i < useSize; i++) { if (elem[i]==toFind){ return true; } } return false; }
查找某个元素对应的位置
public int indexOf(int toFind) { for (int i = 0; i < useSize; i++) { if (elem[i]==toFind){ return i; } } return -1; }
获取指定位置的元素
public int get(int pos) { checkGetPos(pos); return elem[pos]; }
给指定位置的元素设值
public void set(int pos, int value) { checkGetPos(pos); elem[pos]=value; }
删除第一次出现的关键字
public void remove(int toRemove) { int index=indexOf(toRemove); if (index==-1){ return; } for (int i = index; i < useSize-1; i++) { elem[i]=elem[i+1]; } useSize--; }
获取顺序表长度
public int size() { return useSize; }
清空顺序表
public void clear() { useSize=0; }
常见ArrayList的遍历
1、for循环+下标
2、foreach
3、使用迭代器
System.out.println("=========for=========");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("==========foreach========");
for (String x: list) {
System.out.println(x);
}
System.out.println("==========迭代器========");
Iterator<String> it=list.listIterator();
while(it.hasNext()){
System.out.println(it.next() + "");
}
杨辉三角
1. 划分阶段
按照行数进行阶段划分。
2. 定义状态
定义状态 dp[i][j] 为:杨辉三角第 i 行、第 j 列位置上的值。
3. 状态转移方程
根据观察,很容易得出状态转移方程为:dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j],此时 i > 0,j > 0。
4. 初始条件
每一行第一列都为 1,即 dp[i][0] = 1。
每一行最后一列都为 1,即 dp[i][i] = 1。
5. 最终结果
根据题意和状态定义,我们将每行结果存入答案数组中,将其返回。
public class YanghuiTriangle {
public List<List<Integer>> generate(int numRows){
List<List<Integer>> ret=new ArrayList<>();
List<Integer> list=new ArrayList<>();
list.add(1);
ret.add(list);
for (int i = 1; i < numRows; i++) {
List<Integer> curRow=new ArrayList<>();
curRow.add(1);
List<Integer> prevRow=ret.get(i-1);
for (int j = 1; j < i; j++) {
int num=prevRow.get(j)+prevRow.get(j-1);
curRow.add(num);
}
curRow.add(1);
ret.add(curRow);
}
return ret;
}
public static void main(String[] args) {
YanghuiTriangle yanghuiTriangle=new YanghuiTriangle();
List<List<Integer>> list=yanghuiTriangle.generate(5);
System.out.println(list);
}
}
链表(不带环单向链表)
链式结构在逻辑上是连续的,但在物理存储上不一定是连续的,其逻辑顺序是通过链表中的引用链接次序实现的。
打印链表
public void display(){ Node cur=this.head; while (cur!=null){ System.out.print(cur.val+" "); cur=cur.next; } }
头插法添加元素
public void addFirst(int data){ Node node=new Node(data); node.next=head; head=node; }
尾插法添加元素
public void addLast(int data){ Node node=new Node(data); if(head==null){ head=node; }else{ Node cur=head; while (cur.next!=null){ cur=cur.next; } cur.next=node; } }
任意位置插入元素
public void addIndex(int index,int data){ checkIndex(index); if (index==0){ addFirst(data); } if (index==size()){ addLast(data); } Node node=new Node(data); Node cur=findIndexSubOfOne(index); node.next=cur.next; cur.next=node; }
查找是否包含关键字key是否在单链表中
public boolean contains(int key){ Node cur=this.head; while (cur!=null){ if (cur.val==key){ return true; } cur=cur.next; } return false; }
删除第一次出现关键字为key的节点
public void remove(int key){ if (head.val==key){ head=head.next; return; } Node cur=searchPrevOfKey(key); if (cur==null) return; cur.next=cur.next.next; }
删除所有值为key的节点
public void removeAllKey(int key){ if (head==null){ return; } Node cur=head.next; Node prev=head; while (cur!=null){ if (cur.val==key){ prev.next=cur.next; cur=cur.next; }else { prev=cur; cur=cur.next; } } if (head.val==key){ head=head.next; } }
链表的长度
public int size(){ Node cur=this.head; int count=0; while (cur!=null){ cur=cur.next; count++; } return count; }
清空链表
public void clear(){ Node cur=head; while (cur!=null){ Node curNext=cur.next; cur.next=null; cur=curNext; } head=null; }
LinkedList双向链表
打印链表
public void display(){ ListNode cur=head; while (cur!=null){ System.out.println(cur.val+" "); cur=cur.next; } System.out.println(); }
头插法
public void addFirst(int data){ ListNode node=new ListNode(data); if (head==null){ head=node; last=node; }else { node.next=head; head.prev=node; head=node; } }
尾插法
public void addLast(int data){ ListNode node=new ListNode(data); if (head==null){ head=node; last=node; }else { node.prev=last; last.next=node; last=last.next; } }
任意位置插入数据
public void addIndex(int index,int data){ //检查合法性 if (index<0 || index>size()){ throw new IndexNotLegalException(); } //插入 ListNode node=new ListNode(data); ListNode cur=findIndex(index); node.next=cur; node.prev=cur.prev; cur.prev.next=node; cur.prev=node; }
删除第一次出现关键字为key的节点
public void remove(int key){ ListNode cur=head; while (cur!=null){ if (cur.val==key){ if (cur==head){ head=head.next; if (head!=null){ head.prev=null; } }else{ cur.prev.next=cur.next; if (cur.next!=null){ cur.next.prev=cur.prev; }else { last=cur.prev; } } } cur=cur.next; } }
查找关键字key是否在链表中
public boolean contains(int key){ ListNode cur=head; while (cur!=null){ if (cur.val==key){ return true; } cur=cur.next; } return false; }
删除所有值为key的节点
public void removeAllKey(int key){ ListNode cur=head; while (cur!=null){ if (cur.val==key){ if (cur==head){ head=head.next; if (head!=null){ head.prev=null; } }else{ cur.prev.next=cur.next; if (cur.next!=null){ cur.next.prev=cur.prev; }else { last=cur.prev; } } } cur=cur.next; } }
查找链表的长度
public int size(){ int count=0; ListNode cur=head; while (cur!=null){ count++; cur=cur.next; } return count; }
清空链表
public void clear(){ ListNode cur=head; while (cur!=null){ ListNode curNext=cur.next; cur.next=null; cur.prev=null; cur=curNext; } head=null; last=null; }
常见LinkedList的遍历
for (Integer x:linkedList) {
System.out.println(x+" ");
}
System.out.println("=====================");
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.get(i));
}
System.out.println("=====================");
Iterator<Integer> it=linkedList.listIterator();
while (it.hasNext()){
System.out.println(it.next());
}
ArrayList和LinkedList的区别
不同点 | ArrayList | LinkedList |
存储空间上 | 物理上一定连续 | 逻辑上连续,但物理上不一定连续 |
随机访问 | 支持O(1) | 不支持O(N) |
头插 | 需要搬移元素,效率低 | 需要修改引用的指向,时间复杂度为O(1) |
插入 | 空间不够使需要扩容 | 没有容量的概念 |
应用场景 | 元素高效存储+频繁访问 | 任意位置插入和删除频繁 |