java面试总结—数据结构

更多内容可以到专栏查看:https://blog.csdn.net/sunshine543123/category_10899368.html

时间复杂度

在这里插入图片描述
在这里插入图片描述
O(logn) 对数阶例子

int count=1while(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;
    }

猜你喜欢

转载自blog.csdn.net/sunshine543123/article/details/115087452