目录
更多内容可以到专栏查看:https://blog.csdn.net/sunshine543123/category_10899368.html
时间复杂度
O(logn) 对数阶例子
int count=1;
while(count<n){
count=count*2;
}
计算最坏情况下的时间复杂度,成为最坏时间复杂度,一般在没有特殊情况说明,都是指最坏时间复杂度。
树
树的存储结构
特殊的二叉树
斜树:只有左子树或只有右子树
满二叉树:所有分支节点都有左子树和右子树,并且所有叶子结点都在同一层上
完全二叉树:编号为i的节点与同样深度编号为i的满二叉树的节点在同一位置(满二叉树一定是完全二叉树,完全二叉树不一定是满二叉树),完全二叉树深度:|log₂n|+1(利用结点数和层数的关系推导)
二叉搜索树(BST):每个节点的值大于其任意左侧子节点的值,小于其任意右节点的值。
二叉树的遍历
深度优先遍历
沿着树的深度遍历结点,尽可能深的搜索树的分支。如果当前的节点所在的边都被搜索过,就回溯到当前节点所在的那条边的起始节点。一直重复直到进行到发现源节点所有可达的节点为止。
广度优先遍历
从根节点开始,沿着树的宽度遍历树的节点(从上到下,从左到右),直到所有节点都被遍历完为止。
二叉树的中序遍历和后序遍历满足栈的压入(中序)弹出(后序)关系;
单链表和双链表(LinkedList)的区别
单链表是在元素的节点结构中只能包含一个后继结点指针。
双链表则是包含前驱和后继两个指针的。
单向链表适用于节点的增加删除,双向链表适用于需要双向查找节点值的情况。
单向链表的优缺点:
1、优点:存储空间小,增加删除节点简单。
2、缺点:只能从头到尾遍历。只能找到后继节点,无法找到前驱节点。
双向链表的优缺点:
1、优点:可以双向遍历,既能找到后继节点,也能找到前驱节点。从任一节点都可以访问到其他所有节点。
2、缺点:存储空间大,增加删除节点较复杂。
链表(LinkedList)跟数组(ArrayList)的区别
数组静态分配内存,链表动态分配内存;
数组在内存中连续,链表不连续;
数组利用下标定位,时间复杂度为O(1),链表定位元素时间复杂度O(n);
数组插入或删除元素的时间复杂度O(n),链表的时间复杂度O(1)。
数组的优点:
随机访问性强(通过下标进行快速定位)
查找速度快
数组的缺点:
插入和删除效率低(插入和删除需要移动数据)
内存空间要求高,必须有足够的连续内存空间。
数组大小固定,不能动态拓展
链表的优点:
插入删除速度快(因为有next指针指向其下一个节点,通过改变指针的指向可以方便的增加删除元素)
内存利用率高,不会浪费内存(可以使用内存中细小的不连续空间(大于node节点的大小),并且在需要空间的时候才创建空间)
大小没有固定,拓展很灵活。
链表的缺点:
不能随机查找,必须从第一个开始遍历,查找效率低
ArrayList底层,LinkedList底层,依次删除List中的所有元素应该怎么删除?
ArrayList底层是数组,LinkedList底层是双链表;
使用for循环或者iterator遍历
List<Integer> li = new LinkedList<Integer>() ;
for(int i=0;i<50;i++){
li.add(i) ;
}
System.out.println(li);
Iterator<Integer> it=li.iterator();
while(it.hasNext()){
it.next();
it.remove();
}
ArrayList扩容如何实现
ArrayList是采取延迟分配对象数组大小空间的,当第一次添加元素时才会分配10个对象空间,当添加第11个元素的时候,会扩容1.5倍,当添加到16个元素的时候扩容为15*1.5=22,以此类推。
ArrayList每次扩容都是通过Arrays.copyof(elementData,newCapacity)来实现的(elementData数组元素,newCapacity新数组的大小)
怎样判断链表有无环,怎样不借助额外空间,找到链表中间节点
设置两个指针,一个慢指针(low=low.next),一个快指针(fast=fast.next.next)
在不使用额外节点存储空间的情况下,实现单链表逆序
使用循环
Node pre=new Node();
Node next;
while (head!=null){
next=head.next;
head.next=pre;
pre=head;
head=next;
}
while (pre!=null){
System.out.println(pre.var+",");
pre=pre.next;
}
递归(链表的最后一个节点最为翻转链表的头结点)
public static Node digui(Node head){
if (head==null||head.next==null){
return head;
}
Node newHead=digui(head.next);
head.next.next=head;
head.next=null;
return newHead;
}