依然碎碎念

本文最后更新于:8 天前

前言

依旧是一些废话。学而不思则罔,古人说的话是对的,学习的时候也需要思考啊,照猫画虎画形易,画骨难啊。而你如果了解了画骨,画猫亦画虎,
轻而易举。

我常说,多知道一个方法,解决的时候就多一种方案,可是如果过于追求极致,盲目的要多知道一个方法,会不会也是孔乙己里面经典的 ”你知道字有几种写法吗“。哪怕你知道几十种方法,实际中只需要用一个稳定的方法就行了。在武术界这种是不是被称为花架子。哼哼哈嘿了半天,然后自己把自己给绊倒了。反过来想,没有一种方法是通吃的,不同的场景有不同的需求,还是需要知道多一点,世事须有度啊。这个度在哪里,在你心里。

碎碎念正文

关于算法

概念需要懂,知道程序的复杂度,程序的算法复杂度是按步数以及随数据增长步数增长的曲线来表示的,表示符号为大写的O,至于复杂的有O(n),O(logn),O(n^2)等等。这是高中数学吧貌似。程序员的数学能力很重要。

比如经典的排序问题,给几个个整数排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

public class TestSort {
public static void main(String[] args) {
int[] arr = new int[] {34,546,767,2};
// 一般下意识的就是通过遍历一个一个进行排序 (升序)
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
// 升序降序主要是这个比较符
if (arr[i] < arr[j]) {
// 交换位置
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
for (int j : arr) {
System.out.println(j);
}
}
}

分析上面的复杂度4个数需要多少步,这个不用分析,就是16步。4的平方,上面的”算法”貌似不能称作为算法😂😂😂复杂度就是O(n^2)。如果是十位数就是100步,如果是上万个数,那程序运行所需要的时间是相当可观的🙂🙂🙂🙂

暴力循环排序了解完了,我们在了解优雅的排序,优雅代表着高效。Java中用的最多的是快速排序和归并排序,我印象中是基本类型用快速排序,引用类型用归并排序,这两个算法牛逼啊,就类似以前的那种牛逼哄哄的功法一样,比如斗破苍穹萧炎用的焰分噬浪尺, 串戏了啊,我要表达的是什么嘞,就是这种东西我们只需要去学就行了,重要的在于领悟,功法就在那了,能理解几分,那就要看自身的机缘了,有玄幻内味了。至于创造出这种算法的大佬,我们只需要仰视就行了。感兴趣可以自行百度,

归并排序算法是目前为止我们拥有的最重要的算法之一。它是一种基于比较的排序算法,使用分治法解决那些原本复杂度为O(N^2)的问题。归并排序是由数学家John von Neumann于1945年发明的

霍尔 (Sir Charles Antony Richard Hoare) 是一位英国计算机科学家,他也是著名的快速排序算法的发明者。

快速排序演示代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

/**
* 快速排序
* @param a 待排序数组
* @param l 左边界 数组的起点就填0
* @param r 右边界 数组的有边界 a.length -1
*/
public static void quickSort(int[] a, int l, int r) {

if (l < r) {
int i, j, x;

i = l;
j = r;
x = a[i];
while (i < j) {
while (i < j && a[j] > x)
j--; // 从右向左找第一个小于x的数
if (i < j)
a[i++] = a[j];
while (i < j && a[i] < x)
i++; // 从左向右找第一个大于x的数
if (i < j)
a[j--] = a[i];
}
a[i] = x;
quickSort(a, l, i - 1); /* 递归调用 */
quickSort(a, i + 1, r); /* 递归调用 */
}
}

归并排序(迭代版)演示代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

// 归并排序(Java-迭代版)
public static void merge_sort(int[] arr) {
int len = arr.length;
int[] result = new int[len];
int block, start;

// 原版代码的迭代次数少了一次,没有考虑到奇数列数组的情况
for(block = 1; block < len*2; block *= 2) {
for(start = 0; start <len; start += 2 * block) {
int low = start;
int mid = (start + block) < len ? (start + block) : len;
int high = (start + 2 * block) < len ? (start + 2 * block) : len;
//两个块的起始下标及结束下标
int start1 = low, end1 = mid;
int start2 = mid, end2 = high;
//开始对两个block进行归并排序
while (start1 < end1 && start2 < end2) {
result[low++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++];
}
while(start1 < end1) {
result[low++] = arr[start1++];
}
while(start2 < end2) {
result[low++] = arr[start2++];
}
}
int[] temp = arr;
arr = result;
result = temp;
}
result = arr;
}

归并排序(递归版)演示代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 归并排序(Java-递归版)
static void merge_sort_recursive(int[] arr, int[] result, int start, int end) {
if (start >= end)
return;
int len = end - start, mid = (len >> 1) + start;
int start1 = start, end1 = mid;
int start2 = mid + 1, end2 = end;
merge_sort_recursive(arr, result, start1, end1);
merge_sort_recursive(arr, result, start2, end2);
int k = start;
while (start1 <= end1 && start2 <= end2)
result[k++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++];
while (start1 <= end1)
result[k++] = arr[start1++];
while (start2 <= end2)
result[k++] = arr[start2++];
for (k = start; k <= end; k++)
arr[k] = result[k];
}

public static void merge_sort(int[] arr) {
int len = arr.length;
int[] result = new int[len];
merge_sort_recursive(arr, result, 0, len - 1);
}

关于数据结构

数据结构这里其实没有什么多说的,大家要知道一些常用的数据结构就行了,这个东西怎么说呢,正常的开发中程序员可能都不需要接触底层的数据结构这块,且各大语言类库里面本身存在封装好的集合类,Java里面的list,set,map这些工业级别的集合,经过了足够的时间沉淀,出错??不可能的。实现list接口的集合类有常用的ArrayList,LinkedList,还有一些线程安全的类我就记不太清了,Java的多线程实际开发中用的不过,维护成本过高。加上大多是编写网络应用,中间件的技术的成熟,有很多种方法提升性能。回到集合,这两个集合的类的名字就很贴切了,一个底层是Array,一个是LinKed。然后就有各自的特性。set的实现类HashSet,有用到Has表h这种数据结构,Hash表也是Map集合的灵魂啊。

数组

就是数组

数组(Array)是有序的元素序列。若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按有序的形式组织起来的一种形式。这些有序排列的同类数据元素的集合称为数组。

数组是用于储存多个相同类型数据的集合。

这个不需要演示了吧。应该不需要演示

链表

就是链表

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。

使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数据的存取往往要在不同的排列顺序中转换。链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。链表有很多种不同的类型:单向链表,双向链表以及循环链表。链表可以在多种编程语言中实现。

哈希表

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表

栈和队列

使用栈结构存储数据,讲究“先进后出”,即最先进栈的数据,最后出栈;

使用队列存储数据,讲究 “先进先出”,即最先进队列的数据,也最先出队列;

关于计算机网络

留个坑待填,大学里面不是计算机专业,我没学过😑😑😑😑😑😑😑

封面原图

王者台词千千万,好听李信占一半

李信:能提起沉重剑刃的手,握不住飞舞飘落的花

李信:这里是为我所统帅的战场,这里是,让我忘却野心的战场

凯:以绝望挥剑,着逝者为凯

苏烈:沙漠中的花,意味着无限希望

诗语江南 西施


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!