常用的数据结构和算法,Java/Android中的数据结构和算法

本文总结了IT公司面试中常考的数据结构与算法,包括快速排序、二分查找、链表操作、基础函数实现、哈希表、AVL树、B树、红黑树等,以及它们在实际工作中的应用,如C++ STL、Linux进程调度、Nginx定时器管理等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

---- 常用的数据结构和算法

 - 与30 家公司过招,得到了这章面试心法- https://blog.youkuaiyun.com/csdnnews/article/details/86851461
IT 公司一般都会考察数据结构和算法能力,其中以百度与爱奇艺等为代表,面试官一般是先简单地了解你之前的工作经历和项目经验,然后就直接出算法和数据结构的题目,具体涉及到以下内容:
 快速排序。考察的地方包括算法步骤、平均算法复杂度、最好和最坏的情形,有人说校招要把算法写出来,我这里是社招,所以一般描述一下算法过程即可。
 二分查找法。一般面试官会要求面试者把算法写出来,或者先结合一个具体场景来提问,需要你联想到要使用该算法,比如求一个数的平方根,接着要你把它具体实现。
 链表。常见的面试题有要求你写出从一个链表中删除一个节点的算法、单链表倒转、两个链表找相交的部分等,一般需要完全无误地写出来。
 实现一些基础的函数。例如 strcpy、memcpy、memmov 与 atoi 这些函数,面试官会要求你用自己的理解和思路去实现。同样,这些一般也需要完全无误地写出来,并且要保证高效,比如你的实现中有动态分配堆内存,那么这道题目就算答错。

  链表和实现基础函数的关键点一般在于考察你的代码风格、对边界条件的处理,比如判断指针是否为空,千万不要故意不考虑这种情形,即使你知道也不行,只要你不写,一般面试官就认为你的思路不周详,容错率低;再比如,单链表的倒转,最后的返回值肯定是倒转后的链表头结点,这样才能引用一个链表,这些都是面试官想考虑的重点。
 哈希表。对哈希表的细节要求很高,比如哈希表的冲突检测、哈希函数常用实现、算法复杂度;比如百度二面就让我写一个哈希表插入元素算法,元素类型是任意类型。
 AVL 树与 B 树。考察概念与细节,比如会问 MySQL 数据库索引的实现原理,基本上就等于在问你 B 树。 
 红黑树。这个基本上是必问的数据结构,包括红黑树的概念、平均算法复杂度、最好最坏情况下的算法复杂度、左右旋转与颜色变换。面试官常见的套路有:你熟悉 C++ 的 stl 吗?你说熟悉,ok,stl 的 map 用过吧?用过,ok,那 map 是如何实现的?红黑树,ok,那什么是红黑树?这样提问,红黑树就开始了。Java 的也类似。

>  数据结构:线性表,堆栈,队列,串,数组,树和二叉树(红黑树是平衡二叉树吗?)

> 算法
- 算法:递归算法,二分查找算法

- 排序算法
简单排序:冒泡排序、选择排序、插入排序
高级排序:快速排序、归并排序、希尔排序
相关算法知识:划分、递归、二分查找

1.插入排序:直接插入排序,希尔排序
2.选择排序:直接选择排序,堆排序
3.交换排序:冒泡排序,快速排序
4.归并排序
5.基数排序

https://github.com/desaco1989/DesignPattern_Algorithm_EncryptDecrypt/tree/master/src/com/desaco/Algorithm/CommonlyUsedAlgorithm

-- 算法的时间复杂度和控件复杂度

https://i-blog.csdnimg.cn/blog_migrate/568df7f2a4f705356dfa0bd25c28f8bc.png

> 二叉树
- 满二叉树和完全二叉树的区别:
 完全二叉树:设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,
第 h 层所有的结点都连续集中在最左边;
 满二叉树:深度为k且有2^k-1个结点的二叉树称为满二叉树。
 在满叉树的基础上,我在最底层从右往左删去若干节点,得到的都是完全二叉树。

https://i-blog.csdnimg.cn/blog_migrate/738039a1480380c0359c46f514f81d19.png

- 平衡二叉树
 平衡二叉树:树的左右子树的高度差不超过1的数,空树也是平衡二叉树的一种。
 平衡二叉树,又称AVL树。它或者是一棵空树,或者是具有下列性质的二叉树:它的左子树和右子树都是平衡二叉树,且左子树和右子树的高度之差之差的绝对值不超过1.。
 常用算法有:红黑树、AVL树、Treap等。

 平衡二叉树的调整方法:平衡二叉树是在构造二叉排序树的过程中,每当插入一个新结点时,首先检查是否因插入新结点而破坏了二叉排序树的平衡性,若是,则找出其中的最小不平衡子树,在保持二叉排序树特性的前提下,调整最小不平衡子树中各结点之间的链接关系,进行相应的旋转,使之成为新的平衡子树。

 哈夫曼树:带权路径长度达到最小的二叉树,也叫做最优二叉树。
 不关心树的结构,只要求带权值的路径达到最小值,哈夫曼树可能是完全二叉树也可能是满二叉树。
https://i-blog.csdnimg.cn/blog_migrate/389720f190b659f1ca6b032f41ea44ca.png

  平衡二叉树,平衡二叉搜索树(Self-balancing binary search tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。平衡二叉树的常用实现方法有红黑树、AVL、替罪羊树、Treap、伸展树等。 最小二叉平衡树的节点总数的公式如下 F(n)=F(n-1)+F(n-2)+1 这个类似于一个递归的数列,可以参考Fibonacci(斐波那契)数列,1是根节点,F(n-1)是左子树的节点数量,F(n-2)是右子树的节点数量。

  红黑树是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组。它是在1972年由Rudolf Bayer发明的,他称之为"对称二叉B树",它现代的名字是在 Leo J. Guibas 和 Robert Sedgewick 于1978年写的一篇论文中获得的。它是复杂的,但它的操作有着良好的最坏情况运行时间,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n是树中元素的数目。
  AVL是最先发明的自平衡二叉查找树算法。在AVL中任何节点的两个儿子子树的高度最大差别为一,所以它也被称为高度平衡树,n个结点的AVL树最大深度约1.44log2n。查找、插入和删除在平均和最坏情况下都是O(log n)。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。
  Treap是一棵二叉排序树,它的左子树和右子树分别是一个Treap,和一般的二叉排序树不同的是,Treap纪录一个额外的数据,就是优先级。Treap在以关键码构成二叉排序树的同时,还满足堆的性质(在这里我们假设节点的优先级大于该节点的孩子的优先级)。但是这里要注意的是Treap和二叉堆有一点不同,就是二叉堆必须是完全二叉树,而Treap并不一定是。
  伸展树(Splay Tree)是一种二叉排序树,它能在O(log n)内完成插入、查找和删除操作。它由Daniel Sleator和Robert Tarjan创造。它的优势在于不需要记录用于平衡树的冗余信息。在伸展树上的一般操作都基于伸展操作。
  SBT,Size Balanced Tree(简称SBT)是一自平衡二叉查找树,是在计算机科学中用到的一种数据结构。它是由中国广东中山纪念中学的陈启峰发明的。陈启峰于2006年底完成论文《Size Balanced Tree》,并在2007年的全国青少年信息学奥林匹克竞赛冬令营中发表。由于SBT的拼写很容易找到中文谐音,它常被中国的信息学竞赛选手和ACM/ICPC选手们戏称为“傻B树”、“Super BT”等。相比红黑树、AVL树等自平衡二叉查找树,SBT更易于实现。据陈启峰在论文中称,SBT是“目前为止速度最快的高级二叉搜索树”。SBT能在O(log n)的时间内完成所有二叉搜索树(BST)的相关操作,而与普通二叉搜索树相比,SBT仅仅加入了简洁的核心操作Maintain。由于SBT赖以保持平衡的是size域而不是其他“无用”的域,它可以很方便地实现动态顺序统计中的select和rank操作。

> 红黑树
 红黑树(Red Black Tree) 是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现
关联数组。
平衡二叉树是大堆或小堆吗?平衡二叉树/红黑树就是为了将查找的时间复杂度保证在O(logN)范围内。

红黑树与平衡二叉树:
  平衡二叉树AVL树适合用于插入与删除次数比较少,但查找多的情况。由于维护这种高度平衡所付出的代价比从中获
得的效率收益还大,故而实际的应用不多,更多的地方是用追求局部而不是非常严格整体平衡的红黑树。当然,如果
应用场景中对插入删除不频繁,只是对查找要求较高,那么AVL还是较优于红黑树。

  红黑树:一种二叉查找树,但在每个节点增加一个存储位表示节点的颜色,可以是红或黑(非红即黑)。通过对任
何一条从根到叶子的路径上各个节点着色的方式的限制,红黑树确保没有一条路径会比其它路径长出两倍,因此,红
黑树是一种弱平衡二叉树(由于是弱平衡,可以看到,在相同的节点情况下,AVL树的高度低于红黑树),相对于要求
严格的AVL树来说,它的旋转次数少,所以对于搜索,插入,删除操作较多的情况下,我们就用红黑树。
 
- 红黑树应用:
 1,广泛用于C ++的STL中,地图和集都是用红黑树实现的; 
 2,着名的Linux的的进程调度完全公平调度程序,用红黑树管理进程控制块,进程的虚拟内存区域都存储在一颗红黑
树上,每个虚拟地址区域都对应红黑树的一个节点,左指针指向相邻的地址虚拟存储区域,右指针指向相邻的高地址
虚拟地址空间; 
 3,IO多路复用的epoll的的的实现采用红黑树组织管理的的的sockfd,以支持快速的增删改查; 
 4,Nginx的的的中用红黑树管理定时器,因为红黑树是有序的,可以很快的得到距离当前最小的定时器; 
 5,Java的的的中TreeMap中的中的实现;

- 红黑树性质:
性质1. 节点是红色或黑色。
性质2. 根节点是黑色。
性质3 每个叶节点(NIL节点,空节点)是黑色的。
性质4 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
性质5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
https://i-blog.csdnimg.cn/blog_migrate/aaea296b193460e901e63657266b425a.png

---- Java/Android中的数据结构和算法

Android客户端面试基础(五)-数据结构与算法- http://blog.youkuaiyun.com/johnWcheung/article/details/72843223

 数据结构:是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成。
 算   法:是特定问题求解步骤的描述,算法是独立存在的一种解决问题的方法和思想。算法时间复杂度和空间复杂度;

> 数据结构
    基本的数据结构:数组,字符串,链表;

    二叉搜索树是一种排序的数据结构。
    队列在图的宽度优先遍历。

 ConcurrentHashMap 分段加锁;
 Android中的各种数据工具,常用集合类的继承结构如下: 注意这里的 Collection、List、Set和Map都是接口(Interface)
 Collection<--List<--Vector ,基于数组结构
 Collection<--List<--ArrayList ,基于数组结构
 Collection<--List<--LinkedList ,基于单链表实现的
 Collection<--Set<--HashSet ,基于单链表和数组结构
 Collection<--Set<--HashSet<--LinkedHashSet ,它继承于HashSet、又基于LinkedHashMap来实现的
 Collection<--Set<--SortedSet<--TreeSet ,内部实现是根据红黑树,红黑树是一种平衡有序的二叉树
 Map<--SortedMap<--TreeMap 
 Map<--HashMap (补充一个HashMap的子类LinkedHashMap:)

1.ArrayList: 元素单个,效率高,多用于查询 ,数据可以重复
2.Vector: 元素单个,线程安全,多用于查询 
3.LinkedList:元素单个,多用于插入和删除 
4.HashMap: 元素成对,元素可为空 ,HashMap的key是不能有重复的
5.HashTable: 元素成对,线程安全,元素不可为空 
6. HashSet:元素单个,元素不可重复

如果能用数组的时候(元素类型固定,数组长度固定),请尽量使用数组来代替List; 
如果没有频繁的删除插入操作,又不用考虑多线程问题,优先选择ArrayList; 
如果在多线程条件下使用,可以考虑Vector; 
如果需要频繁地删除插入,LinkedList就有了用武之地:

 1.View.isShown() 判断视图是否显示,不需要再根据 View.getVisibility() == View.VISIBLE来判断是否显示或者隐藏,但是注意;
  (1)View.getVisibility() == View.VISIBLE 只是对View自身的可见性进行判断;
  (2)View.isShown() 只有它及其所有的祖先都为visible时,才返回true。
 2.TextUtils.isEmpty(CharSequence)方法,用于判断字符串是否为null或"",以后再也不要写 if(str != null && !str.equals(""));
 3.TextWatcher **接口,用来监听文本输入框内容的改变;
 4.TextView.setError(); 这个一般用于EditText中,验证用户输入,然后给予提示,这样就不需要使用Toast或者Dialog来提示了。
 5.onBackPressed(); 调用此句,相当于点了一次返回按钮。
 6.runOnUiThread可以直接运行到主线程中,一般在子线程中使用;
 7.ConcurrentHashMap相较于HashMap,它是线程同步的,而且不是简单的加锁而已,而是采用了分段加锁的技术segment(类似HashTable)来进行加锁,性能比单纯的全局加锁提升10几倍。
 8.SparseArray替代HashMap,SparseArray比HashMap更省内存,它对数据采取了压缩的方式来表示稀疏数组的数据,从而节约内存空间,SparseArray只能存储key为int类型的数据,同时,SparseArray在存储和读取数据时候,使用的是二分查找法;
 9.ArrayMap 和 SimpleArrayMap 替代HashMap,其中,ArrayMap 是 Map的子类,而SimpleArrayMap 不是。

> 算法
 查找:二分查找;
 排序:归并排序,快速排序;
 算法实现:递归和循环;

Android面试算法排序—7大基础算法(详细分析)- http://blog.youkuaiyun.com/csdn_aiyang/article/details/73108606
android 常用的算法- http://blog.youkuaiyun.com/lespace/article/details/52145598
  算法的学习对于培养一个人的逻辑思维能力是有极大帮助的,它可以培养 我们养成思考分析问题,解决问题的能力。
  一个算法的优劣可以用空间复杂性和时间复杂度来衡量。算法可以使用自然语言、伪代码、流程图等多种不同的方法来描述。计算机系统中的操作系统、语言编译系统、数据库管理系统以及各种各样的计算机应用系统中的软件,都必须使用具体的算法来实现。算法设计与分析是计算机科学与技术的一个核心问题。
  a.关于查找的算法很多种:基本查找、二分查找、二叉树、斐波那契等。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值