一、程序员了解数据结构和算法的好处:
1.对算法的理解的越多,就越能减少时间复杂度
例如:像2、4、8、16、32、64、128、256,如何判断一个数是2的幂次方?
思考:传统的做法是不是拿这个数不断的对2取模,看最后余数是否为0?
会算法就快很多:
2转为二进制是:0010
2的前一个数1的二进制:0001
4--->0100
3--->0011
8--->1000
7--->0111
...
得出 n & (n-1)=0 则n符合条件(二进制的&运算,在对应的二进制位上不同会为0)
//测试
public static void main(String[] args) {
System.out.println(1024 & 1023);
}
//结果
0
Process finished with exit code 0
2.对算法理解越多,就越能减少空间复杂度,节省服务器资源
例如: 统计中国16亿人口的年龄,并按从小到大排列,服务器cpu 1核 内存512M。
思考:如果初始化一个16亿的数组,再把这个超大的数组按一定的算法排序,服务器早蹦了。
用算法的思维:人的年龄一般在0-200岁之间,我们初始化一个200的数组,数组的角标代表年龄,数组的value代表在这个年龄内有多少人,简化代码如下
public static void main(String[] args) {
int[] peopleArr = new int[200];
//模拟统计各年龄段的人口
Random random = new Random();
for (int i = 0; i < peopleArr.length; i++) {
peopleArr[i] = random.nextInt(100) * 100;
}
//人口按年龄从小到大输出
System.out.println(Arrays.toString(peopleArr));
for (int i = 0; i < peopleArr.length; i++) {
System.out.println("人口是"+i+"岁的:");
for (int j = 0; j < peopleArr[i]; j++) {
System.out.print(i+" ");
}
System.out.println();
}
}
3、对数据结构理解的越多,就越能应付不同的业务场景。
例如:在不使用Redis的情况下,如何实现VIP用户的优先排队。
其实,JDK自带了队列的数据结构,使用优先队列的类就能解决此问题:
//value属性是排序的权重,value越大,task对象排在越前面
class Task implements Comparable<Task>{
private int value =1;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
@Override
public int compareTo(Task o) {
return this.value>o.value?-1:1;
}
@Override
public String toString() {
return "Task{" +
"value=" + value +
'}';
}
}
//运行
public static void main(String[] args) {
PriorityBlockingQueue<Task> priorityBlockingQueue = new PriorityBlockingQueue<>();
Task task1 = new Task();
task1.setValue(1);
Task task2 = new Task();
task2.setValue(2);
priorityBlockingQueue.add(task1);
priorityBlockingQueue.add(task1);
priorityBlockingQueue.add(task2);
priorityBlockingQueue.add(task1);
Iterator<Task> iterator = priorityBlockingQueue.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
//结果如下
Task{
value=2}
Task{
value=1}
Task{
value=1}
Task{
value=1}
Process finished with exit code 0
二、常用的数据结构简析:
1.List
//底层数组,有下标,适合做查询多的容器
List<Integer> arrayList = new ArrayList<Integer>();
//底层链表,有指针,适合做增删多的容器
List<Integer> linkedList = new LinkedList<Integer>();
//线程安全,但效率慢
Vector<Integer> vector =new Vector<Integer>();
2.set
相比于list,有去重的功能
//乱序去重,与插入的顺序不同
Set<Integer> hashSet = new HashSet<Integer>