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八种基本数据类型 

参考

  1. 《Java数据结构和算法》Robert Lafore 著,第1章 - 综述

Java数据结构和算法 - OverView的更多相关文章

  1. Java数据结构和算法

    首先,本人自学java,但是只学习了java的基础知识,所以想接下来学习一下数据结构和算法,但是找了很多教材,大部分写的好的都是用c语言实现的,虽然知道数据结构和算法,跟什么语言实现的没有关系,但是我 ...

  2. 【Java数据结构学习笔记之二】Java数据结构与算法之栈(Stack)实现

      本篇是java数据结构与算法的第2篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型   栈是 ...

  3. Java数据结构和算法(六)——前缀、中缀、后缀表达式

    前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆序,匹配关键字符等等,那它还有别的什么功能吗 ...

  4. Java数据结构和算法(十四)——堆

    在Java数据结构和算法(五)——队列中我们介绍了优先级队列,优先级队列是一种抽象数据类型(ADT),它提供了删除最大(或最小)关键字值的数据项的方法,插入数据项的方法,优先级队列可以用有序数组来实现 ...

  5. Java数据结构和算法(九)——高级排序

    春晚好看吗?不存在的!!! 在Java数据结构和算法(三)——冒泡.选择.插入排序算法中我们介绍了三种简单的排序算法,它们的时间复杂度大O表示法都是O(N2),如果数据量少,我们还能忍受,但是数据量大 ...

  6. java数据结构与算法之栈(Stack)设计与实现

    本篇是java数据结构与算法的第4篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型 栈是一种用于 ...

  7. Java数据结构和算法 - 堆

    堆的介绍 Q: 什么是堆? A: 这里的“堆”是指一种特殊的二叉树,不要和Java.C/C++等编程语言里的“堆”混淆,后者指的是程序员用new能得到的计算机内存的可用部分 A: 堆是有如下特点的二叉 ...

  8. Java数据结构和算法 - 二叉树

    前言 数据结构可划分为线性结构.树型结构和图型结构三大类.前面几篇讨论了数组.栈和队列.链表都是线性结构.树型结构中每个结点只允许有一个直接前驱结点,但允许有一个以上直接后驱结点.树型结构有树和二叉树 ...

  9. Java数据结构和算法 - 高级排序

    希尔排序 Q: 什么是希尔排序? A: 希尔排序因计算机科学家Donald L.Shell而得名,他在1959年发现了希尔排序算法. A: 希尔排序基于插入排序,但是增加了一个新的特性,大大地提高了插 ...

随机推荐

  1. BZOJ_2298_[HAOI2011]problem a_线段树

    BZOJ_2298_[HAOI2011]problem a_线段树 Description 一次考试共有n个人参加,第i个人说:“有ai个人分数比我高,bi个人分数比我低.”问最少有几个人没有说真话( ...

  2. layer的删除询问框的使用

    删除是个很需要谨慎的操作 我们需要进行确认 对了删除一般使用ajax操作 因为如果同url请求 处理 再返回 会有空白页 1.js自带的样式 <button type="button& ...

  3. struts2 上传与下载

    1.Struts.xml <action name="addfileAction" class="Action.addfileAction"> &l ...

  4. selenium IDE 使用方法整理

    1.设置起始点(确定case从哪步开始执行),快捷键:S,效果图如下: 2.设置断点(case执行到添加断点处,将自动停止),快捷键:B,效果图如下: 3.设置判断点    如:百度输入ceshi,点 ...

  5. hystrix隔离策略(4)

    hystrix提供了两种隔离策略:线程池隔离和信号量隔离.hystrix默认采用线程池隔离. 1.线程池隔离 不同服务通过使用不同线程池,彼此间将不受影响,达到隔离效果. 例如: 我们可以通过andT ...

  6. zookeeper源码 — 二、集群启动—leader选举

    上一篇介绍了zookeeper的单机启动,集群模式下启动和单机启动有相似的地方,但是也有各自的特点.集群模式的配置方式和单机模式也是不一样的,这一篇主要包含以下内容: 概念介绍:角色,服务器状态 服务 ...

  7. 阿里云Centos7.x MySql安装教程示例

    创建用户 useradd mysql; passwd mysql; 下载(比如:5.5.61) 地址 https://dev.mysql.com/downloads/mysql/5.6.html#do ...

  8. Android进阶加密-第1章-Android系统架构-读书笔记

    第 1 章 Android 系统架构 1.1 Android 系统架构 Android 系统架构分为五层,从上到下依次是应用层.应用框架层.系统运行库层.硬件抽象层和 Linux 内核层. 应用层(S ...

  9. Netty4.x整合SpringBoot2.x使用Protobuf3详解

    前言 本篇文章主要介绍的是SpringBoot整合Netty以及使用Protobuf进行数据传输的相关内容.Protobuf会介绍下用法,至于Netty在netty 之 telnet HelloWor ...

  10. asp.net core系列 51 Identity 授权(下)

    1.6 基于资源的授权 前面二篇中,熟悉了五种授权方式(对于上篇讲的策略授权,还有IAuthorizationPolicyProvider的自定义授权策略提供程序没有讲,后面再补充).本篇讲的授权方式 ...