标签: 算法

来推荐几本对职业生涯影响较大的技术书籍

开发过程中,有时候会觉得当时要是没有读过那本书,现在肯定想不到要这样做。由此可以推定,因为曾经没有读过某一本书,会导致想不到要怎样做。所以不如大家都相互推荐一下自己读过的好书,拓宽自己的知识领域。

我先推荐几本对我影响比较大的书:

《算法》基本功,理解常用的组件的原理,比如 redis 。 面试也很有用

《 Head First 设计模式(中文版)》业务开发利器。可以写出更优雅的代码

《 MySQL 技术内幕》充分理解 mysql,每次阅读都有新收获

《 Go 语言设计与实现》 深入了解 golang 。 面试也很有用

《架构整洁之道》 如何避免代码不断膨胀导致项目不可维护,非常有效

85 条回复    2021-08-16 15:57:38 +08:00

mazhimazh
    1

mazhimazh   1 天前   ❤️ 73

对我影响比较大的书《深入解析 Java 编译器:源码剖析与实例详解》《深入剖析 Java 虚拟机:源码剖析与实例详解》,为什么对我影响比较大呢?因为是我写的
youjianchuiyan
    2

youjianchuiyan   1 天前

《 unix 网络编程》
musi
    3

musi   1 天前

来推荐几本爱民老师的书
《程序原本》
《我的架构思想》
letianqiu
    4

letianqiu   1 天前

@mazhimazh 《深入剖析 Java 虚拟机:源码剖析与实例详解》预计什么时候上市?
SearchDream
    5

SearchDream   1 天前 via iPhone

TCP/IP 详解
xylxAdai
    6

xylxAdai   1 天前   ❤️ 6

《深入理解计算机系统》,我觉得每个学习计算机的都应该看一下。
HENQIGUAI
    7

HENQIGUAI   1 天前

《程序员之禅》《禅与摩托车维修艺术》《黑客与画家》
milkleeeeee
    8

milkleeeeee   1 天前

我来个不那么高大上的……大学的时候买了本《 JavaScript 权威指南(第六版)》自学,从此开始了前端职业生涯。
mazhimazh
    9

mazhimazh   1 天前

@letianqiu 这个月底吧,估计
bug403
    10

bug403   1 天前

没那末大影响,一本小说 《疯狂的程序员》*影 讲外 @挂

agagega
    11

agagega   1 天前 via iPhone

《疯狂的程序员》
《 C++简明教程》
《 C++沉思录》
《编码》
《程序员修炼之道》
《 UNIX 编程艺术》

CrazyRundong
    12

CrazyRundong   1 天前 via iPhone

应该是大二时看的《 MATLAB 在数学建模中的应用》,觉醒了内心的程序员之魂 (bushi),随后开启了数学建模-推荐系统-xgboost-传统 cv-人工智障的升级打怪之路
btnokami
    13

btnokami   1 天前 via iPhone   ❤️ 2

Design Data Intensive Application,真的神书
codyfeng
    14

codyfeng   1 天前 via Android

Effective C++
More Effective C++
shiny
    15

shiny   1 天前

UNIX 环境高级编程:服务器环境不再神秘
重来:开启了对工作方法的思考,启蒙
禅与摩托车维修艺术:始于技术,超脱技术细节,思考哲学问题
Hallelu
    16

Hallelu   1 天前

@mazhimazh 哈哈哈哈哈哈 有被装到
letianqiu
    17

letianqiu   23 小时 44 分钟前

@mazhimazh 到时候会支持一下。
Pagliacii
    18

Pagliacii   23 小时 41 分钟前   ❤️ 1

SICP
ruchee
    19

ruchee   22 小时 12 分钟前

《精通正则表达式(第三版)》:读一遍此书,写正则手到擒来,再也不用到处复制粘贴
xiaket
    20

xiaket   22 小时 7 分钟前

Pro Django
wandehul
    21

wandehul   21 小时 45 分钟前   ❤️ 1

<<知音>><<故事会>>难道不配拥有姓名吗
qping
    22

qping   21 小时 42 分钟前

@milkleeeeee #8 作为一个后端,看了 javascript 设计模式 ,觉得大有收益
Cbdy
    23

Cbdy   21 小时 42 分钟前 via Android

Unix 编程艺术
Issacx
    24

Issacx   21 小时 37 分钟前

我加一本《 Thinking in Java 》,从这里我开始理解面向对象编程。
enGrave93
    25

enGrave93   21 小时 34 分钟前 via Android

《 Java 并发编程之美》,《 Android 开发艺术探索》,《算法(第 4 版)》
feather12315
    26

feather12315   17 小时 55 分钟前 via Android

@ruchee #19 读完了也忘光了。

程序员的自我修养、Linux 高级环境编程、Linux Inside 、Intel 微处理器 /计算机组成原理、龙书。

feather12315
    27

feather12315   17 小时 54 分钟前 via Android

@ruchee #19 强推 regex101.com ,有了这个才是手到擒来
csfreshman
    28

csfreshman   17 小时 52 分钟前

UNIX 高级环境编程 和 SICP,大三 大四啃了一年,以为自己看懂了,工作后常伴左右温故知新
morty0
    29

morty0   17 小时 42 分钟前

designing data-intensive applications
MeatIndustry
    30

MeatIndustry   17 小时 20 分钟前 via iPhone

收集一波大家的神书…
Arthurccc
    31

Arthurccc   17 小时 1 分钟前

好贴。希望大家踊跃。
WangTx1996
    32

WangTx1996   17 小时 0 分钟前 via iPhone

SICP 和 CSAPP
chevalier
    33

chevalier   16 小时 38 分钟前

《黑客与画家》
《构建高性能 Web 站点》郭欣
《 C Primer Plus 》 Stephen Prata
《 Go 预言学习笔记》雨痕
katsusan
    34

katsusan   16 小时 33 分钟前

CSAPP+APUE+DDIA
aguesuka
    35

aguesuka   16 小时 22 分钟前

“The HoTT Bokk”
levelworm
    36

levelworm   15 小时 15 分钟前 via Android

@mazhimazh 大佬能不能说一说学习和工作的经历?感觉很多人虽然有很久的工作经验,但是技术上并没有多少提高。
NetCobra
    37

NetCobra   12 小时 12 分钟前   ❤️ 1

《人月神话》
《代码整洁之道》
chenyu0532
    38

chenyu0532   9 小时 32 分钟前

算法 head first 设计模式 + 若干本设计模式的书 代码整洁之道。
可能我的业务比较简单吧,我越来越觉得设计模式*重要,算法知道怎么回事就行了,在面试中比较有用 。
whywaoxaks
    39

whywaoxaks   9 小时 24 分钟前

小时候家里书架上的 谭浩强的《 basic 语言》。。
没这本书,估计不会对编程感兴趣。。
acerlawson
    40

acerlawson   9 小时 22 分钟前 via iPhone

CSAPP+OSTEP+CA:AQA
tonzeng
    41

tonzeng   9 小时 0 分钟前

《从删库到跑路》.jpg
xin053
    42

xin053   8 小时 42 分钟前

《软件调试》
BrainOnline
    43

BrainOnline   8 小时 42 分钟前

《陈景润传》
BrainOnline
    44

BrainOnline   8 小时 40 分钟前

#43 小学时候读的这本书,然后开启自己对数学的兴趣,否则之前是偏文科一些。
ffLoveJava
    45

ffLoveJava   8 小时 37 分钟前

先 Mark 一下 过会我在=商场
Rebely
    46

Rebely   8 小时 34 分钟前

流畅的 python
mazhimazh
    47

mazhimazh   8 小时 34 分钟前

@levelworm 我工作也其实接近 10 年了吧,前 6 年都是做计算广告的,本来打算把计算广告的业务走通,后来觉得个人的性格不适合做业务,适合做技术,所以职业规划就变为了走技术,精通一个点了,下定决心研究虚拟机,为了让学习有产出就写了 2 本书,现在也做虚拟机相关工作,所以说只要决定了,就要好好准备,等机会来了就能抓住上车了
yunyuyuan
    48

yunyuyuan   8 小时 33 分钟前

《如何讨取富婆欢心》
zjj19950716
    49

zjj19950716   8 小时 29 分钟前

代码大全
coldmonkeybit
    50

coldmonkeybit   8 小时 27 分钟前

应该是《操作系统导论》,我非科班
necodba
    51

necodba   8 小时 26 分钟前

金鳞岂是池中物…
wangxn
    52

wangxn   8 小时 25 分钟前 via Android

深入浅出 MFC
深入 C++ 对象模型
前者入门,后者深入。都是侯捷写的或者翻译的书。
raptor
    53

raptor   8 小时 25 分钟前

Modern C++ Design: 看了半本决定放弃用了十来年的 C++,因为觉得这样的 C++不是我想要的,不是我玩它,是它玩我,后来改用 Python 十几年,表示还是这个好。

其它影响比较大的就是《人月神话》《人件》《软件需求》这类。

Longerrrr
    54

Longerrrr   8 小时 24 分钟前

编码
searene
    55

searene   8 小时 24 分钟前

Designing Data-Intensive Applications
nspih
    56

nspih   8 小时 13 分钟前

脊椎康复指南
mazhimazh
    57

mazhimazh   8 小时 9 分钟前

《如何与产品经理友好相处》
xhldtc
    58

xhldtc   7 小时 58 分钟前

对人生影响较大的书籍:《英雄志》
gaodq
    59

gaodq   7 小时 47 分钟前

《数据密集型应用系统设计》
https://book.douban.com/subject/30329536/
shanghai1943
    60

shanghai1943   7 小时 46 分钟前

《代码整洁之道》 《黑客与画家》《 程序员的修炼之道:从小工到专家 》《 Eeffective java 》
abc635073826
    61

abc635073826   7 小时 38 分钟前

《如何活到 80 岁》《如何活到 90 岁》《如何比别人活的长》
weiwenhao
    62

weiwenhao   7 小时 30 分钟前

《代码整洁之道》《计算机程序的构造与解释》《球状闪电》《凡人修仙传》
chigeyaowaner
    63

chigeyaowaner   7 小时 28 分钟前

《 程序员的修炼之道:从小工到专家 》+1,这本改变了我很多,每次搬家还要带着走。第二版比*版的内容做了一些扩充,*版有些内容在第二版里做了删减。无论是曳光弹还是简单设计等等,都很受用,也很经典,现在还会推荐给我的学弟学妹们。
不想看书的还可以看视频,有些内容讲的还是很不错的: https://www.zentao.net/redirect-index-19380.html,唯一的不足就是视频输出频率快,经常需要按暂停。个人还是希望书籍看完再看一些视频或者一些点评。

还有一本《代码整洁之道》,讲了很多关于代码整洁的重要性和实践,还给出了一些工具,只要遵循这些规则,就能编写出干净的代码,从而有效提升代码质量。这本书也是及其推荐的一本。

viator42
    64

viator42   7 小时 25 分钟前

「吃掉那只青蛙 : 拒*穷忙,把时间留给*重要的事」
4771314
    65

4771314   7 小时 23 分钟前   ❤️ 1

《颈椎病康复指南》
RudyS
    66

RudyS   7 小时 21 分钟前

Ayn Rand: 《源泉》《理想》《阿特拉斯耸耸肩》
silently9527
    67

silently9527   7 小时 12 分钟前

《程序员健康指南》《 MySQL 是怎样运行的 : 从根儿上理解 MySQL 》《算法第四版》
silently9527
    68

silently9527   7 小时 8 分钟前   ❤️ 1

《全国富婆通讯录》
meshell
    69

meshell   7 小时 8 分钟前

代码大全
0xZhangKe
    70

0xZhangKe   6 小时 50 分钟前

重构 /改善既有代码设计
Loserzhu
    71

Loserzhu   6 小时 38 分钟前

csapp
yutonliu
    72

yutonliu   6 小时 37 分钟前

前列腺养生保健
lovedebug
    73

lovedebug   6 小时 37 分钟前

技术科普书籍 《信息简史》
yingo
    74

yingo   6 小时 21 分钟前

apue,这本书直接看出快感来了..
Brentwans
    75

Brentwans   6 小时 11 分钟前

《谭浩强 c 语言程序设计》无出其右
TUNGH
    76

TUNGH   6 小时 6 分钟前

@mazhimazh 递茶
huZhao
    77

huZhao   5 小时 45 分钟前   ❤️ 1

《颈椎病的预防》,《一本书读懂颈椎病》,《痔疮》,《近视眼》,《减肥》,《如何比别人活的长》
tonghuashuai
    78

tonghuashuai   5 小时 25 分钟前

《 Redis 设计与实现》 – 当时在通勤的地铁上花了几天看完的,现在想想这本书真的是简单易懂读起来没有压力但又干货满满的一本小书
chairuosen
    79

chairuosen   5 小时 3 分钟前

代码大全
zhoudaiyu
    80

zhoudaiyu   4 小时 21 分钟前   ❤️ 1

运维向:
1 、Kubernetes in Action (顾名思义,讲 K8S 的,深入浅出,没有生硬的感觉,我的 K8S 入门书。马上出第二版了)
2 、Systems Performance – Enterprise and the Cloud (讲了一些 Linux 下的性能调优的,还有一些监控工具的,很不错)
3 、Fluent Python ( Python 进阶了,当初刚做运维学了几个月 Python 我就飘了,然后看了这本书仿佛觉得我学了假的 Python,第二本的英文版已经可以在 Safari 上看了)
4 、Wireshark 网络分析就这么简单(运维不懂网络有点说不过去了,这本书直接从例子入手讲一些网络的知识,推荐)
Phariel
    81

Phariel   4 小时 14 分钟前

我*近在看这本
编码:隐匿在计算机软硬件背后的语言

对于信息通讯产业人士比较有帮助

Klingon
    82

Klingon   4 小时 9 分钟前

严肃诚恳的推荐《荀子·劝学》
wzxlovesy
    83

wzxlovesy   3 小时 32 分钟前 via Android

OSTEP
naruco
    84

naruco   2 小时 14 分钟前

在没有扎实基础的前提下,于引擎搜索各类奇技淫巧都是在浪费时间;
我就是个例子,表面上解决了很多问题,实际狗屁不通。
《荀子·劝学》 +1
看了几句,甚好!
fkdtz
    85

fkdtz   1 小时 49 分钟前

《编码 : 隐匿在计算机软硬件背后的语言》

写了 N 年代码之后偶然看到这本书,让我认识到原来之前一直都在计算机的门外徘徊,这本书让我摸到了计算机的大门 。

这本书让人从信息的本质去思考:写这么多代码,归根结底是在干嘛?

Android面试题算法篇

Android面试题算法篇,由本人整理汇总,后续将继续推出系列篇,如果喜欢请持续关注和推荐,更多精彩内容

红黑树特点

1.root节点和叶子节点是黑色
2.红色节点后必须为黑色节点
3.从root到叶子每条路径的黑节点数量相同
实现阶乘

//采用递归法
public static long factorial(long number) {
if (number <= 1)
return 1;
else
return number * factorial(number – 1);
}
//采用循环连乘法
public static int fact(int num){
int temp=1;
int factorial=1;
while(num>=temp){
factorial=factorial*temp;
temp++;
}
return factorial;
}
二分查找

//递归法
int binarySearch(int array[], int low, int high, int target) {
if (low > high) return -1;
int mid = low + (high – low) / 2;
if (array[mid] > target)
return binarysearch(array, low, mid – 1, target);
if (array[mid] < target)
return binarysearch(array, mid + 1, high, target);
return mid;
}
//循环法
int binarySearch2(int a[], int key) {
int low = 0;
int high = a.length – 1;
while (low <= high) {
int mid = low + (high – low) / 2;
if (a[mid] > key)
high = mid – 1;
else if (a[mid] < key)
low = mid + 1;
else
return mid;
}
return -1;
}
二分查找中值的计算
这是一个经典的话题,如何计算二分查找中的中值?大家一般给出了两种计算方法:
算法一: mid = (low + high) / 2
算法二: mid = low + (high – low)/2
乍看起来,算法一简洁,算法二提取之后,跟算法一没有什么区别。但是实际上,区别是存在的。算法一的做法,在*端情况下,(low+high)存在着溢出的风险,进而得到错误的mid结果,导致程序错误。而算法二能够保证计算出来的mid,一定大于low,小于high,不存在溢出的问题。

二分查找法的缺陷
二分查找法的O(logn)让它成为十分高效的算法。不过它的缺陷却也是那么明显的。就在它的限定之上:必须有序,我们很难保证我们的数组都是有序的。当然可以在构建数组的时候进行排序,可是又落到了第二个瓶颈上:它必须是数组。
数组读取效率是O(1),可是它的插入和删除某个元素的效率却是O(n)。因而导致构建有序数组变成低效的事情。
解决这些缺陷问题更好的方法应该是使用二叉查找树了,*好自然是自平衡二叉查找树了,既能高效的(O(n log n))构建有序元素集合,又能如同二分查找法一样快速(O(log n))的搜寻目标数。

用两个栈实现队列

题目描述:
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

思路:
压入元素直接压入stack1 删除元素先查看stack2是否为空,非空则弹出;空则将stack1中元素取出,置于stack2中

代码:

public class StackQueue {

Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();

public void push(int node){
stack1.push(node);
}

public int pop(){
if(stack2.empty()){
while(!stack1.empty())
stack2.push(stack1.pop());
}
return stack2.pop();
}
递归和迭代的区别是什么,各有什么优缺点?

程序调用自身称为递归,利用变量的原值推出新值称为迭代。
递归的优点大问题转化为小问题,可以减少代码量,同时代码精简,可读性好;
缺点就是递归调用浪费了空间,而且递归太深容易造成堆栈的溢出。
迭代的好处就是代码运行效率好,因为时间只因循环次数增加而增加,而且没有额外的空间开销;
缺点就是代码不如递归简洁
判断101-200之间有多少个素数,并输出所有素数
素数又称质数。所谓素数是指除了 1 和它本身以外,不能被任何整数整除的数,例如17就是素数,因为它不能被 2~16 的任一整数整除。

思路1):因此判断一个整数m是否是素数,只需把 m 被 2 ~ m-1 之间的每一个整数去除,如果都不能被整除,那么 m 就是一个素数。

思路2):另外判断方法还可以简化。m 不必被 2 ~ m-1 之间的每一个整数去除,只需被 2 ~ 之间的每一个整数去除就可以了。如果 m 不能被 2 ~ 间任一整数整除,m 必定是素数。例如判别 17 是是否为素数,只需使 17 被 2~4 之间的每一个整数去除,由于都不能整除,可以判定 17 是素数。

原因:因为如果 m 能被 2 ~ m-1 之间任一整数整除,其二个因子必定有一个小于或等于 ,另一个大于或等于 。例如 16 能被 2、4、8 整除,16=28,2 小于 4,8 大于 4,16=44,4=√16,因此只需判定在 2~4 之间有无因子即可。

public class mainCase{
public static void main(String args[]){
int i=0;
for(i=101;i<=200;i++)
if(math.isPrime(i)==true)
System.out.println(i);
}
}
class math
{
//方法1
public static boolean isPrime(int x)
{
for (int i=2;i<=x/2;i++)
if (x%2==0)
return false;
return true;
}

//方法2
public static boolean isPrime2(int m)
{
int k=(int)sqrt((double)m);
for (int i=2;i<=k;i++)
if (m%i==0)
return false;
return true;
}
}
字符串小写字母转换成大写字母

public String toUpperCase(String str)
{
if (str != null && str.length() > 0) {
for (int i=0; i<str.length(); i++) {
char c = str.charAt(i);
c += 32;
}
}
return str;
}
进制转换:给定一个十进制数 n 和 一个整数 k, 将 十进制数 n 转换成 k进制数

public String hexConversion(int n, int k) {
StringBuffer resultNumber = new StringBuffer();
tenToK(resultNumber, n, k);
System.out.println(“n:k:result: ” + n +” “+ k + ” ” + resultNumber.toString());

return resultNumber.toString();
}

private void tenToK(StringBuffer stringBuffer, int n, int k) {
int integral = n/k;
int mode = n % k;
stringBuffer.insert(0, mode);
if (integral >= k) {
tenToK(stringBuffer, integral, k);
} else if (integral > 0) {
stringBuffer.insert(0, integral);
}
}
位运算实现加法

public int aplusb(int a, int b) {
int sum_without_carry, carry;

sum_without_carry = a^b; //没有进位的和
carry = (a&b)<<1; //进位
if(carry==0) {
return sum_without_carry;
} else {
return aplusb(sum_without_carry, carry);
}
}
二叉树排序树

首先定义节点类

public class TreeNode {
Object obj;
TreeNode parent;
TreeNode lchild;
TreeNode rchild;

public TreeNode(int obj) {
this.obj = obj;
}
}
然后创建一个树类

public class Tree {

/**
* 先序遍历二叉树
* @param root
*/
public void Fprint(TreeNode root){
if(root!=null){
System.out.println(root.obj);
Fprint(root.lchild);
Fprint(root.rchild);
}
}

/**
* 中序遍历二叉树
* @param root
*/
public void Mprint(TreeNode root){
if(root!=null){
Mprint(root.lchild);
System.out.println(root.obj);

Mprint(root.rchild);
}
}

/**
* 根据一个int数组建立二叉排序树
* @param a 数组
* @return
*/
public TreeNode Build(int[] a){
if(a.length==0){
return null;
}
TreeNode root = new TreeNode(a[0]);
for(int i=1;i<a.length;i++){
TreeNode newnode = new TreeNode(a[i]);
sort(root,newnode);
}
return root;
}
/**
* 在二叉排序树中添加一个节点
* @param root 二叉树的根节点
* @param newnode 新加入的加点
* @return
*/
public void sort(TreeNode root,TreeNode newnode){
TreeNode node = root;
if((Integer)newnode.obj<=(Integer)node.obj){
if(node.lchild==null){
newnode.parent = node;
node.lchild = newnode;
}else{
sort(node.lchild,newnode);
}
}else{
if(node.rchild==null){
newnode.parent = node;
node.rchild = newnode;
}else{
sort(node.rchild,newnode);
}
}
}
}
创建二叉排序树的时候随便传入一个int型数组a[]
然后通过自顶向下的方式一个一个的将a[0]—a[n]个元素创建的节点类一个一个的拼接到树上
此后只需要再创建一个主函数类来调用便行了

public class Test {

public static void main(String[] args) {
int a[] = {100,35,3,44,212,453};
Tree t = new Tree();
TreeNode root = t.Build(a);
t.Mprint(root);
}

}
这样便可通过创建二叉排序树并且中序遍历该二叉树的方式,来将一组混乱的数据整理成一组从小到大的数据了。

冒泡排序

算法描述:对于给定的n个记录,从*个记录开始依次对相邻的两个记录进行比较,当前面的记录大于后面的记录时,交换位置,进行一轮比较和交换后,n个记录中的*大记录将位于第n位;然后对前(n-1)个记录进行第二轮比较;重复该过程直到进行比较的记录只剩下一个为止。

package sorting;

/**
* 冒泡排序
* 平均O(n^2),*好O(n),*坏O(n^2);空间复杂度O(1);稳定;简单
* @author zeng
*
*/
public class BubbleSort {

public static void bubbleSort(int[] a){

int n = a.length;
int temp = 0;
for(int i=0;i<n;i++){
for(int j=0;j<n-i-1;j++){
if(a[j]<a[j+1]){
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
}

public static void main(String[] args){
int[] a ={49,38,65,97,76,13,27,50};
bubbleSort(a);
for(int j:a)
System.out.print(j+” “);
}
}
插入排序

算法描述:对于给定的一个数组,初始时假设*个记录自成一个有序序列,其余记录为无序序列。接着从第二个记录开始,按照记录的大小依次将当前处理的记录插入到其之前的有序序列中,直至*后一个记录插入到有序序列中为止。

package sorting;

/**
* 插入排序
* 平均O(n^2),*好O(n),*坏O(n^2);空间复杂度O(1);稳定;简单
* @author zeng
*
*/
public class InsertionSort {

public static void insertionSort(int[] a) {
int tmp;
for (int i = 1; i < a.length; i++) {
for (int j = i; j > 0; j–) {
if (a[j] < a[j – 1]) {
tmp = a[j – 1];
a[j – 1] = a[j];
a[j] = tmp;
}
}
}
}

public static void main(String[] args) {
int[] a = { 49, 38, 65, 97, 76, 13, 27, 50 };
insertionSort(a);
for (int i : a)
System.out.print(i + ” “);
}
}
选择排序

算法描述:对于给定的一组记录,经过*轮比较后得到*小的记录,然后将该记录与*个记录的位置进行交换;接着对不包括*个记录以外的其他记录进行第二轮比较,得到*小的记录并与第二个记录进行位置交换;重复该过程,直到进行比较的记录只有一个时为止。

package sorting;

/**
* 选择排序
* 平均O(n^2),*好O(n^2),*坏O(n^2);空间复杂度O(1);不稳定;简单
* @author zeng
*
*/
public class SelectionSort {

public static void selectionSort(int[] a) {
int n = a.length;
for (int i = 0; i < n; i++) {
int k = i;
// 找出*小值的小标
for (int j = i + 1; j < n; j++) {
if (a[j] < a[k]) {
k = j;
}
}
// 将*小值放到排序序列末尾
if (k > i) {
int tmp = a[i];
a[i] = a[k];
a[k] = tmp;
}
}
}

public static void main(String[] args) {
int[] b = { 49, 38, 65, 97, 76, 13, 27, 50 };
selectionSort(b);
for (int i : b)
System.out.print(i + ” “);
}
}
快速排序

算法描述:对于一组给定的记录,通过一趟排序后,将原序列分为两部分,其中前一部分的所有记录均比后一部分的所有记录小,然后再依次对前后两部分的记录进行快速排序,递归该过程,直到序列中的所有记录均有序为止。

package sorting;

/**
* 快速排序
* 平均O(nlogn),*好O(nlogn),*坏O(n^2);空间复杂度O(nlogn);不稳定;较复杂
* @author zeng
*
*/
public class QuickSort {

public static void sort(int[] a, int low, int high) {
if(low>=high)
return;
int i = low;
int j = high;
int key = a[i];
while (i < j) {
while (i < j && a[j] >= key)
j–;
a[i++] = a[j];
while (i < j && a[i] <= key)
i++;
a[j–] = a[i];
}
a[i] = key;
sort(a,low,i-1);
sort(a,i+1,high);
}

public static void quickSort(int[] a) {
sort(a, 0, a.length-1);
for(int i:a)
System.out.print(i+” “);
}

public static void main(String[] args) {
int[] a = { 49, 38, 65, 97, 76, 13, 27, 50 };
quickSort(a);
}
}
归并排序

算法描述:对于给定的一组记录,首先将每两个相邻的长度为1的子序列进行归并,得到 n/2(向上取整)个长度为2或1的有序子序列,再将其两两归并,反复执行此过程,直到得到一个有序序列。

package sorting;

/**
* 归并排序
* 平均O(nlogn),*好O(nlogn),*坏O(nlogn);空间复杂度O(n);稳定;较复杂
* @author zeng
*
*/
public class MergeSort {

public static void merge(int[] a, int start, int mid,
int end) {
int[] tmp = new int[a.length];
System.out.println(“merge ” + start + “~” + end);
int i = start, j = mid + 1, k = start;
while (i != mid + 1 && j != end + 1) {
if (a[i] < a[j])
tmp[k++] = a[i++];
else
tmp[k++] = a[j++];
}
while (i != mid + 1)
tmp[k++] = a[i++];
while (j != end + 1)
tmp[k++] = a[j++];
for (i = start; i <= end; i++)
a[i] = tmp[i];
for (int p : a)
System.out.print(p + ” “);
System.out.println();
}

static void mergeSort(int[] a, int start, int end) {
if (start < end) {
int mid = (start + end) / 2;
mergeSort(a, start, mid);// 左边有序
mergeSort(a, mid + 1, end);// 右边有序
merge(a, start, mid, end);
}
}

public static void main(String[] args) {
int[] b = { 49, 38, 65, 97, 76, 13, 27, 50 };
mergeSort(b, 0, b.length – 1);
}
}
希尔排序

算法描述:先将待排序序列的数组元素分成多个子序列,使得每个子序列的元素个数相对较少,然后对各个子序列分别进行直接插入排序,待整个待排序序列“基本有序”后,再对所有元素进行一次直接插入排序。

package sorting;

/**
* 希尔排序
* 平均O(nlogn),*坏O(nlogn);空间复杂度O(1);不稳定;较复杂
* @author zeng
*
*/
public class ShellSort {

public static void shellSort(int[] a) {
int n = a.length;
int d = n / 2;
while (d > 0) {
for (int i = d; i < n; i++) {
int j = i – d;
while (j >= 0 && a[j] > a[j + d]) {
int tmp = a[j];
a[j] = a[j + d];
a[j + d] = tmp;
j = j – d;
}
}
d = d / 2;
}
}

public static void main(String[] args) {
int[] b = { 49, 38, 65, 97, 76, 13, 27, 50 };
shellSort(b);
for (int i : b)
System.out.print(i + ” “);
}
}
基数排序

算法思想:依次按个位、十位…来排序,每一个pos都有分配过程和收集过程,array[i][0]记录第i行数据的个数。

package sorting;

/**
* 基数排序
* 平均O(d(n+r)),*好O(d(n+r)),*坏O(d(n+r));空间复杂度O(n+r);稳定;较复杂
* d为位数,r为分配后链表的个数
* @author zeng
*
*/
public class RadixSort {

//pos=1表示个位,pos=2表示十位
public static int getNumInPos(int num, int pos) {
int tmp = 1;
for (int i = 0; i < pos – 1; i++) {
tmp *= 10;
}
return (num / tmp) % 10;
}

//求得*大位数d
public static int getMaxWeishu(int[] a) {
int max = a[0];
for (int i = 0; i < a.length; i++) {
if (a[i] > max)
max = a[i];
}
int tmp = 1, d = 1;
while (true) {
tmp *= 10;
if (max / tmp != 0) {
d++;
} else
break;
}
return d;
}

public static void radixSort(int[] a, int d) {

int[][] array = new int[10][a.length + 1];
for (int i = 0; i < 10; i++) {
array[i][0] = 0;// array[i][0]记录第i行数据的个数
}
for (int pos = 1; pos <= d; pos++) {
for (int i = 0; i < a.length; i++) {// 分配过程
int row = getNumInPos(a[i], pos);
int col = ++array[row][0];
array[row][col] = a[i];
}
for (int row = 0, i = 0; row < 10; row++) {// 收集过程
for (int col = 1; col <= array[row][0]; col++) {
a[i++] = array[row][col];
}
array[row][0] = 0;// 复位,下一个pos时还需使用
}
}
}

public static void main(String[] args) {
int[] a = { 49, 38, 65, 197, 76, 213, 27, 50 };
radixSort(a, getMaxWeishu(a));
for (int i : a)
System.out.print(i + ” “);
}
}

堆排序

算法描述:对于给定的n个记录,初始时把这些记录看作一棵顺序存储的二叉树,然后将其调整为一个大顶堆,然后将堆的*后一个元素与堆顶元素进行交换后,堆的*后一个元素即为*大记录;接着将前(n-1)个元素重新调整为一个大顶堆,再将堆顶元素与当前堆的*后一个元素进行交换后得到次大的记录,重复该过程直到调整的堆中只剩下一个元素时为止。

package sorting;

/**
* 堆排序
* 平均O(nlogn),*好O(nlogn),*坏O(nlogn);空间复杂度O(1);不稳定;较复杂
* @author zeng
*
*/
public class HeapSort {

public static void heapSort(int[] a) {
int i;
int len = a.length;
// 构建堆
for (i = len / 2 – 1; i >= 0; i–)
heapAdjust(a, i, len – 1);
//交换堆顶元素与*后一个元素的位置
for (i = len – 1; i > 0; i–) {
int tmp = a[0];
a[0] = a[i];
a[i] = tmp;
heapAdjust(a, 0, i – 1);
}
}

public static void heapAdjust(int[] a, int pos, int len) {
int child = 2 * pos + 1;
int tmp = a[pos];
while (child <= len) {
if (child < len && a[child] < a[child + 1])
child++;
if (a[child] > tmp) {
a[pos] = a[child];
pos = child;
child = 2 * pos + 1;
} else
break;
}
a[pos] = tmp;
}

public static void main(String[] args) {
int[] a = { 49, 38, 65, 97, 76, 13, 27, 50 };
heapSort(a);
for (int i : a)
System.out.print(i + ” “);
}
}

 

本文完~

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速