Java数据结构和算法 - OverView
Q: 为什么要学习数据结构与算法?
A: 如果说Java语言是自动档轿车,C语言就是手动档吉普。数据结构呢?是变速箱的工作原理。你完全可以不知道变速箱怎样工作,就把自动档的车子从1档开到4档,而且未必就比懂得的人慢。写程序这件事,和开车一样,经验可以起到很大作用,但如果你不知道底层是怎么工作的,就永远只能开车,既不会修车,也不能造车。如果你对这两件事都不感兴趣也就罢了,数据结构懂得用就好。但若你此生在编程领域还有点更高的追求,数据结构是绕不开的课题。
Java 替你做了太多事情,那么多动不动还支持范型的容器类,加上垃圾收集,会让你觉得编程很容易。但你有没有想过,那些容器类是怎么来的,以及它存在的意义是什么?最粗浅的,比如 ArrayList 这个类,你想过它的存在是多么大的福利吗——一个可以随机访问、自动增加容量的数组,这种东西 C 是没有的,要自己实现。但是,具体怎么实现呢?如果你对这种问题感兴趣,那数据结构是一定要看的。甚至,面向对象编程范式本身,就是个数据结构问题:怎么才能把数据和操作数据的方法封装到一起,来造出 class / prototype 这种东西?
A: 此外,很重要的一点是,数据结构也是通向各种实用算法的基石,所以学习数据结构都是提升内力的事情。
链接:https://www.zhihu.com/question/20012022/answer/13688683
A: 这里是关于罗升阳的访谈,专访罗升阳:老罗的Android之旅
Q: 不同数据结构的优缺点?
| 数据结构 | 优点 | 缺点 |
|---|---|---|
| 数组(Array) | 快速访问,如果知道下标,就可以非常快地存取 | 查找慢, 插入或删除慢, 大小固定 |
| 有序数组(OrderedArray) | 比无序的数组查找快 | 插入或删除慢,大小固定 |
| 栈(Stack) | 提供后进先出方式的存取 | 存取其他项很慢 |
| 队列(Queue) | 提供先进先出方式的存取 | 存取其他项很慢 |
| 链表(LinkedList) | 插入快,删除快 | 查找慢 |
| 二叉树(BinaryTree) | 查找、插入、删除都快(如果树保持平衡) | 删除算法复杂 |
| 红-黑树(RBTree) | 查找、插入、删除都快。树总是平衡的 | 算法复杂 |
| 2-3-4树(2-3-4Tree) | 查找、插入、删除都快。树总是平衡的。类似的树对磁盘存储有用 | 算法复杂 |
| 哈希表(HashTable) | 如果关键字已知则存取极快。插入快 | 删除慢,如果不知道关键字则存取很慢,对存储空间使用不充分 |
| 堆(Heap) | 插入、删除快,对最大数据项的存取很快 | 对其他数据项存取慢 |
| 图(Graph) | 对现实世界建模 | 有些算法慢且复杂 |
Q: 算法的概述?
A: 许多算法直接适用于上面的数据结构,都需要知道如何:
1) 插入一个新的数据项
2) 删除某一特定的数据项
3) 寻找某一个特定的数据项
4) 如何迭代地访问各个数据项
5) 排序
Q: 为什么面向对象编程比面向过程编程要好一些?
A: 面向过程编程,如C、Pascal或早期版本的Basic在处理大型的复杂问题时有些力不从心,为什么会这样呢?有两类问题:一是程序与现实世界缺乏相应关系;二是程序内部的结构出现了问题。
A: 对现实世界建模的无能为力
使用过程语言对现实世界问题进行抽象及概念化十分困难:方法执行任务,而数据存储信息,但是现实世界中的事物是对两者同时进行操作的。
例如,炉子上的自动调温器例子,如果用过程语言来写这个程序,可能会以两个函数turnOn()和turnOff()即炉开和炉闭来完成,但是还会有两个全局变量currentTemp和desiredTemp,即现在的温度和希望的温度。
然而这些函数和变量并没有形成任何编程对象,在程序中不会出现任何可以称之为自动调温器的单元,这个单元的唯一概念仅存在程序员的脑海中。
对于大型的程序,有可能包括上百个类似调温器的实体,面向过程语言对这种情况将会使程序变得极为混乱,错误频繁出现,有时甚至不可能实现方案,因此需要一种可以更好地将程序中的事物与现实中的事物相匹配的语言。
A: 粗糙的组织结构
解决程序的内部组织是一个更微妙而且事关重大的问题。面向对象被划分为一个一个的函数,这种基于函数组织形式的一个巨大问题是它仅仅考虑了函数,而没有重视数据。当不得不面对数据时,它没有过多的选择。简而言之,数据可以是一个特定的函数的局部变量,也可以使所有函数都可以存取的全局变量,就是无法规定一个变量只允许某些函数存取而不允许另一些函数存取。
如果一个变量要想被多个函数存取到,就必须为全局变量,但是全局变量会在不经意间被程序的任何一个函数存取,这就导致了频繁的程序错误。
Q: 什么是软件工程?
A: 软件工程研究是许多程序员参与的大型复杂的计算机程序的创建方法。它强调是程序的整体设计和如何依照最终用户需求而进行设计的问题。
A: 软件工程关系一个软件项目的整个生命周期,包括分析、设计、验证、编码、测试、生产和维护各个阶段。
Q: C++和Java的几处不同?
A: 这里只列出可以帮助C++程序员看懂示例的Java特性
A: 没有指针
Java和C++的最大区别在于Java没有指针,其实,Java只是摆脱了显示表露的指针,指针依旧是以存储地址的形式隐藏在程序的深处,有时甚至可以说在Java中,所有的东西都是指针。
1) 引用(reference)
Java对基本数据类型的处理与对象的处理不同
int nVar; // an int variable called nVar
BankAccount bankAccount; // reference to a BankAccount object
在第一行语句中,一个被称为nVar的存储地址保存了一个数值127,然而,bankAccount这个存储地址并没有保存BankAccount对象的数据,这个名称bankAccount是对象的引用,它并不是对象本身。
实际上,如果bankAccount没有被预先赋值的话,它就不会称为引用。在赋值为某个对象之前,它保存了一个被称为null的特殊对象的引用。同样,nVar在它被赋值之前也不会保存数值。如果尝试使用一个被赋值的变量,编译器会报错。
在C++中
BankAccount bankAccount;
实际上在栈里创建了一个对象,它留出了所有这个对象的数据的空间。而在Java中,这条语句只创建了一个放置某一对象的存储地址的空间。可以将Java引用认为是普通变量语法中的指针。
2) 赋值
Java中的赋值操作符与C++中的不一样。
在C++中,这条语句:
bankAccount2 = bankAccount1;
将一个名为bankAccount1的对象的所有数据都拷贝到另一个名为bankAccount2的对象中。然而在Java中,这条语句的赋值语是向bankAccount2拷贝了bankAccount1指向的存储地址,现在bankAccount1和bankAccount2实际指的是同一个对象,它们都是这个对象的引用。
如果对赋值操作符理解不深的话,上面的语句会让人感到困惑。
如果想对一个对象中复制数据到另一个对象中,必须保证在一开始就有两个不同的对象,然后分别拷贝每个字段,等号是不起复制的作用的。
3) new操作符
在Java中任何创建对象的工作必须使用new。但是new在Java中返回一个引用,而不像C++中返回一个指针。下面是创建对象的一个方法:
BankAccount bankAccount = null;
bankAccount = new BankAccount();
取消指针意味着一个更安全的系统。程序员不可能找到bankAccount的真实地址,也就不可能意外地破坏它。
用new向堆申请空间后,如何去释放那些不再使用的空间?在C++中,可以使用delete。在Java中,则根本不需要对释放空间担心。Java每隔一段时间就会查看每一块由new开辟的内存,看指向它的有效引用是否依旧存在,如果这个引用不存在,系统会自动将这块空间归入空闲内存区。这个过程被称为垃圾回收。
几乎所有的程序员在使用C++过程中都会有忘记删除存储空间的经历,这会导致“内存泄漏”(memory leak)从而消耗系统资源,使程序处于不稳定的状态,甚至会导致系统崩溃。内存泄漏在Java中不可能出现(或至少几乎没有)。
4) 参数
在C++中,指针经常被用来在函数间传递对象,从而避免拷贝一个大对象的系统开销。在Java中,对象经常以引用的形式传递,这种方法同样地避免了对象的拷贝:
void f1() {
BankAccount bankAccount = new BankAccount(270.00);
f2(bankAccount);
}
void f2(BankAccount ba) {}
上面的代码中引用bankAccount和ba都指向同一个对象,而在C++中,ba则是从bankAccount拷贝而来的另一个对象。
然而,简单的基本数据类型总是通过它的值来传递。
5) 相等与同一
在Java中,对基本数据类型,可以通过相等操作符(==)来判断两个变量是否含有相同的值:
int a = 12;
int b = a;
if (a == b) {
System.out.println("they are equal");
}
这同C/C++语法。
但是在Java中,由于关系操作符使用引用,所以它们在涉及到对象的判断时有些不同。 当使用相等操作符(==)判断类时,实际上判断的是类的引用是否一致,即它们是否指向的是同一个对象:
BankAccount ba1 = new BankAccount(250.00);
BankAccount ba2 = ba1;
if (ba1 == ba2) {
System.out.println("they are identical");
}
在C++中,这个操作符会判断两个对象是否含有相同的数据。如果在Java中要判断两个对象是否含有相同的数据,则使用Object类的equals()方法:
BankAccount ba1 = new BankAccount(250.00);
BankAccount ba2 = new BankAccount(250.00);
if (ba1 == ba2) {
System.out.println("they are equal");
}
A: 重载操作符
Java中没有重载操作符,在C++中可以重新定义+、*、=及大多数其他操作符,以便使它们在特定的类中达到不同的效果。在Java中,任何类似的重新定义都是不可能的,而可以使用命名的方法,如add()或其他名字。
A: 基本数据类型
Java八种基本数据类型 
参考
- 《Java数据结构和算法》Robert Lafore 著,第1章 - 综述
Java数据结构和算法 - OverView的更多相关文章
- Java数据结构和算法
首先,本人自学java,但是只学习了java的基础知识,所以想接下来学习一下数据结构和算法,但是找了很多教材,大部分写的好的都是用c语言实现的,虽然知道数据结构和算法,跟什么语言实现的没有关系,但是我 ...
- 【Java数据结构学习笔记之二】Java数据结构与算法之栈(Stack)实现
本篇是java数据结构与算法的第2篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型 栈是 ...
- Java数据结构和算法(六)——前缀、中缀、后缀表达式
前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆序,匹配关键字符等等,那它还有别的什么功能吗 ...
- Java数据结构和算法(十四)——堆
在Java数据结构和算法(五)——队列中我们介绍了优先级队列,优先级队列是一种抽象数据类型(ADT),它提供了删除最大(或最小)关键字值的数据项的方法,插入数据项的方法,优先级队列可以用有序数组来实现 ...
- Java数据结构和算法(九)——高级排序
春晚好看吗?不存在的!!! 在Java数据结构和算法(三)——冒泡.选择.插入排序算法中我们介绍了三种简单的排序算法,它们的时间复杂度大O表示法都是O(N2),如果数据量少,我们还能忍受,但是数据量大 ...
- java数据结构与算法之栈(Stack)设计与实现
本篇是java数据结构与算法的第4篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型 栈是一种用于 ...
- Java数据结构和算法 - 堆
堆的介绍 Q: 什么是堆? A: 这里的“堆”是指一种特殊的二叉树,不要和Java.C/C++等编程语言里的“堆”混淆,后者指的是程序员用new能得到的计算机内存的可用部分 A: 堆是有如下特点的二叉 ...
- Java数据结构和算法 - 二叉树
前言 数据结构可划分为线性结构.树型结构和图型结构三大类.前面几篇讨论了数组.栈和队列.链表都是线性结构.树型结构中每个结点只允许有一个直接前驱结点,但允许有一个以上直接后驱结点.树型结构有树和二叉树 ...
- Java数据结构和算法 - 高级排序
希尔排序 Q: 什么是希尔排序? A: 希尔排序因计算机科学家Donald L.Shell而得名,他在1959年发现了希尔排序算法. A: 希尔排序基于插入排序,但是增加了一个新的特性,大大地提高了插 ...
随机推荐
- is not eligible for getting processed by all BeanPostProcessors
BeanPostProcessor是控制Bean初始化开始和初始化结束的接口.换句话说实现BeanPostProcessor的bean会在其他bean初始化之前完成,BeanPostProcessor ...
- ETCD相关介绍--整体概念及原理方面
etcd作为一个受到ZooKeeper与doozer启发而催生的项目,除了拥有与之类似的功能外,更专注于以下四点. 简单:基于HTTP+JSON的API让你用curl就可以轻松使用. 安全:可选SSL ...
- 关于CSS定位属性 position 的使用
CSS中一般通过浮动和定位来对标签进行位置操作.下面我们来讨论一下定位的用法和需要注意的地方. 1.首先,说一下position的几个属性值 (1)none属性值,这个是定义不进行定位,默认为不定位, ...
- Dubbo中SPI扩展机制解析
dubbo的SPI机制类似与Java的SPI,Java的SPI会一次性的实例化所有扩展点的实现,有点显得浪费资源. dubbo的扩展机制可以方便的获取某一个想要的扩展实现,每个实现都有自己的name, ...
- 【cogs 775】山海经 ——Segment Tree
题目链接: TP 题解: 我数据结构真心是弱啊= =. 线段树好厉害啊,一直不会区间最大连续和,今天刚学习了一下233. 维护前缀最大和后缀最大,越界最大(?),再维护一个区间最大,瞎搞 ...
- LuoguP4234_最小差值生成树_LCT
LuoguP4234_最小差值生成树_LCT 题意: 给出一个无向图,求最大的边权减最小的边权最小的一棵生成树. 分析: 可以把边权从大到小排序,然后类似魔法森林那样插入. 如果两点不连通,直接连上, ...
- BZOJ_2435_[Noi2011]道路修建_dfs
BZOJ_2435_[Noi2011]道路修建_dfs 题意: http://www.lydsy.com/JudgeOnline/problem.php?id=2435 分析: dfs搞定. 我怕爆栈 ...
- 正则表达式(Regular expressions)使用笔记
Regular expressions are a powerful language for matching text patterns. This page gives a basic intr ...
- FPGA学习笔记(七)——FSM(Finite State Machine,有限状态机)设计
FPGA设计中,最重要的设计思想就是状态机的设计思想!状态机的本质就是对具有逻辑顺序和时序规律的事件的一种描述方法,它有三个要素:状态.输入.输出:状态也叫做状态变量(比如可以用电机的不同转速作为状态 ...
- Unity 用ml-agents机器学习造个游戏AI吧(2)(入门DEMO)
前言: 上一篇博文已经介绍了Unity ml-agents的环境配置(https://www.cnblogs.com/KillerAery/p/10629963.html)了. 个人建议先敲demo再 ...