550 likes | 786 Views
数据结构 Java 语言描述. 面向对象的方法 & 注释、条件和断言. 数据结构. 数据结构 即是描述数据的 组织形式 及 操作 的一门课程。 数据的组织形式相关研究 对相应组织形式的数据上的操作研究。. 什么是程序?. 程序( Program )就是 供计算机执行后,能完成特定功能的指令序列( Instructions sequence ) 程序 = 计算机指令序列 程序包含两方面的内容 数据对象 ( Objects )及 数据对象 之间关系 数据结构 (Data structure) 对这些对象的处理过程 算法 (Algorithm).
E N D
数据结构 Java语言描述 面向对象的方法 & 注释、条件和断言
数据结构 • 数据结构即是描述数据的组织形式及操作的一门课程。 • 数据的组织形式相关研究 • 对相应组织形式的数据上的操作研究。
什么是程序? • 程序(Program)就是供计算机执行后,能完成特定功能的指令序列(Instructions sequence) • 程序=计算机指令序列 • 程序包含两方面的内容 • 数据对象(Objects)及数据对象之间关系 • 数据结构(Data structure) • 对这些对象的处理过程 • 算法(Algorithm)
程序/数据结构/算法 • 程序 = 数据结构 + 算法 (Program = Data Structure + Algorithm) 这个公式由Niklaus Wirth首先提出。 Niklaus Wirth 是PASCAL之父和结构化程序 设计的首创者,1984图灵奖获得者。
数据 • 数据是信息的载体。它能够被计算机识别、存储和加工处理,是计算机程序加工的“原料”。 • 随着计算机应用领域的扩大,数据的范畴包括: 整数、实数、字符串、图像和声音等。
数据元素(Data Element) • 数据元素是数据的基本单位。数据元素也称元素、结点、顶点、记录等。 • 一个数据元素可以由若干个数据项(也可称为字段、域、属性)组成。 • 数据项是具有独立含义的最小标识单位。
数据的逻辑结构可描述为: Group=(D,R) 有限个数据元素的集合 这些数据元素间关系的集合
学号 姓名 成绩 9861109 张卓 100 9861107 刘忠赏 95 9861103 胡孝臣 86 数据的逻辑结构——线性结构 A , B , C , ······· ,X ,Y , Z 线性表——结点间是以线性关系联结 学 生 成 绩 表
数据的逻辑结构——树形结构 全校学生档案管理的组织方式
1 4 2 3 1 2 3 数据的逻辑结构——图形结构 节点间的连结是任意的
数据的运算通过算法(Algorithm)描述,讨论算法是数据结构课程的重要内容之一。数据的运算通过算法(Algorithm)描述,讨论算法是数据结构课程的重要内容之一。 • 算法是对特定问题求解步骤的一种描述。 • 数据结构中常见的算法有:检索、排序、插入、删除、修改等。 算法和算法分析
(1)有穷性——算法必须总是在执行有穷步之后结束。(1)有穷性——算法必须总是在执行有穷步之后结束。 • (2)确定性——算法中每一条指令必须有确切的含义。不存在二义性。 • (3)可行性——即算法描述的操作都是可以通过已经实现的基本运算执行有限次来实现的。 • (4)输入——一个算法有零个或多个输入。 • (5)输出——一个算法有一个或多个输出。 算法具有以下五个特性:
求解同一计算问题可能有许多不同的算法,如何去评价这些算法的优劣?求解同一计算问题可能有许多不同的算法,如何去评价这些算法的优劣? • 选用的算法首先应该是“正确”的。此外,主要考虑如下三点: • 执行算法所耗费的时间; • 执行算法所耗费的存储空间,其中主要考虑辅助存储空间; • 算法应易于理解,易于编码,易于调试等等。 评价算法好坏的标准
算法执行的时间等于所有语句执行时间的总和,是算法所处理的数据个数n的函数,表示为: O(f(n)), • O(f(n))称为该算法的时间复杂度。 • O(1)表示算法的时间是一个常数,不依赖于n; • O(n)表示算法的时间与n成正比,是线性关系; • O(n2) ,O(n3) ,O(2n)分别称为平方阶、立方阶和指数阶; O(log2n)为对数阶 算法的时间性能分析
定义:如果存在两个正常数c和n0,对于所有的n≧n0,有︱f(n) ︳≦c|g(n) ︳ 记作:f(n)=O(g(n)) • 定理:若A(n)=amnm+am-1nm-1 +…+a1n+a0是一个m次多项式,则: A(n)=O(nm) 算法的时间性能分析
例1、{x++;s=0;} 其时间复杂度仍为O(1),即常量阶。 • 例2、for(i=0;i<n; i++) {x++;s+=x;} 即时间复杂度为线性阶。 语句频度为: 其时间复杂度为: 语句频度为: 其时间复杂度为:
例3、for(i=0;i<n;i++) for(j=0;j<n; j++) { c[i][j]=0; for(k=0;k<n; k++) c[i][j]+=a[i][k]*b[k][j]; } 语句频度为: 其时间复杂度为:
以下六种计算算法时间的多项式是最常用的。其关系为:以下六种计算算法时间的多项式是最常用的。其关系为: O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n3) • 指数时间的关系为:O(2n)<O(n!)<O(nn) • 参见P53图4-2,图4-3 • 当n取得很大时,指数时间算法运算时间远远超过多项式时间算法。 多项式时间复杂度和指数时间复杂度
空间复杂度:算法所需存储空间的度量,记作: S(n)=O(g(n)) 其中n为问题的规模(或大小) 算法的存储空间需求
数据类型 • 类型是一组值的集合。 • 数据类型是指一个类型和定义在该类型上的操作集合。 • 数据类型定义了数据的性质、取值范围以及对数据所能进行的各种操作。 • 如: Java中整型类型int的值集是{-232,…,-2,-1,0,1,2,…,232-1},还包括对这个整数类型进行的加(+)、减(-)、乘(*)、除(/)和求模(%)操作。
学号 姓名 成绩 9861109 张卓 100 9861107 刘忠赏 95 9861103 胡孝臣 86 数据类型 • Java语言提供了一些基本数据类型。 • 利用基本数据类型,软件设计人员还可以设计出各种复杂的数据类型。
抽象数据类型(Abstract Type,简称ADT) • ADT是指抽象数据的组织和与之相关的操作。可以看作是数据的逻辑结构及其在逻辑结构上定义的操作。 • 一个ADT可描述为:ADT ADT-Name{ Data: //数据说明数据元素之间逻辑关系的描述Operation1: //操作1, Operation2: //操作2…… }
第一章:面向对象的方法 • 基本概念 • 数据抽象 • 对象 • 类 • 接口
1.3 比率类(Ratio.java) • public class Ratio • { • protected int numerator; //numerator of ratio • protected int denominator; //denominator of ratio • public Ratio(int top, int bottom) • //pre bottom != 0 • //post constructs a ratio equivalent to top::bottom • { • numerator = top; • denominator = bottom; • reduce(); • }
1.3 比率类(Ratio.java) • public int getNumerator() • { • return numerator; • } • public int getDenominator() • { • return denominator; • } • public double getValue() • { • return (double)numerator/(double)denominator; • }
1.3 比率类(Ratio.java) • public Ratio add(Ratio other) • { • return new Ratio(this.numerator*other.denominator+ • this.denominator*other.numerator, • this.denominator*other.denominator); • } • protected void reduce() • { • int divisor = gcd(numerator,denominator); • numerator /= divisor; • denominator /= divisor; • }
1.3 比率类(Ratio.java) • protected static int gcd(int a, int b) • { • if (a == 0) { • if (b == 0) return 1; • else return b; • } • if (b < a) return gcd(b,a); • return gcd(b%a,a); • } • public String toString() • { • return getNumerator()+"/"+getDenominator(); • }
1.3 Ratio(比率)类的应用 • public static void main(String[] args) • { • Ratio r = new Ratio(1,1); // r == 1.0 • r = new Ratio(1,2); // r == 0.5 • r.add(new Ratio(1,3)); // sum computed, but r still 0.5 • r = r.add(new Ratio(2,8)); // r == 0.75 • System.out.println(r.getValue()); // 0.75 printed • System.out.println(r.toString()); // calls toString() System.out.println(r); // calls toString() • } • }
1.4 银行帐户类(BankAccount.java) • public class BankAccount • { • protected String account; // the account number • protected double balance; // the balance associated with account • public BankAccount(String acc, double bal) • { • account = acc; • balance = bal; • } • public boolean equals(Object other) • { • BankAccount that = (BankAccount)other; • return this.account.equals(that.account); • }
1.4 银行帐户类(BankAccount.java) • public String getAccount() • { • return account; • } • public double getBalance() • { • return balance; • } • public void deposit(double amount) • { • balance = balance + amount; • } • public void withdraw(double amount) • { • balance = balance - amount; • }
1.4 银行帐户类的应用 • 向一个10年期,利息%5的帐户存100 $ 向一个20年期,利息%2.5的帐户存100$ 试比较采用哪一种投资最好?
1.4 银行帐户类的应用 public static void main(String[] args) { BankAccount jd = new BankAccount("Jain Dough",100.00); BankAccount js = new BankAccount("Jon Smythe",100.00); for (int years = 0; years < 10; years++) jd.deposit(jd.getBalance() * 0.05); for (int years = 0; years < 20; years++) js.deposit(js.getBalance() * 0.025);
1.4 银行帐户类的应用 System.out.println("Jain invests $100 over 10 years at 5%."); System.out.println("After 10 years " + jd.getAccount() +" has $" + jd.getBalance()); System.out.println("Jon invests $100 over 20 years at 2.5%."); System.out.println("After 20 years " + js.getAccount() +" has $" + js.getBalance()); }
1.5 一般用途类:关联(Assocoation.java) • package structure; • import java.util.Map; • public class Association implements Map.Entry • { • protected Object theKey; // the key of the key-value pair • protected Object theValue; // the value of the key-value pair • public Association(Object key, Object value) • { • Assert.pre(key != null, "Key must not be null."); • theKey = key; • theValue = value; • } • public Association(Object key) • { • this(key,null); • }
1.5 一般用途类:关联(Assocoation.java) • public boolean equals(Object other) • { • Association otherAssoc = (Association)other; • return getKey().equals(otherAssoc.getKey()); • } • public Object getValue() • { • return theValue; • } • public Object getKey() • { • return theKey; • }
1.5 一般用途类:关联(Assocoation.java) • public Object setValue(Object value) • { • Object oldValue = theValue; • theValue = value; • return oldValue; • } • public String toString() • { • StringBuffer s = new StringBuffer(); • s.append("<Association: "+getKey()+"="+getValue()+">"); • return s.toString(); • } • }
1.5 关联的应用( atinLay.java) import structure.*; • public class atinLay { • // a pig latin translator for nine words • public static void main(String args[]) • { • Association dict[] = new Association[9]; • dict[0] = new Association("a","aay"); • dict[1] = new Association("bad","adbay"); • dict[2] = new Association("had","adhay"); • dict[3] = new Association("dad","adday"); • dict[4] = new Association("day","ayday"); • dict[5] = new Association("hop","ophay"); • dict[6] = new Association("on","onay"); • dict[7] = new Association("pop","oppay"); • dict[8] = new Association("sad","adsay");
1.5 关联的应用( atinLay.java) • for (int argn = 0; argn < args.length; argn++) • { // for each argument • for (int dictn = 0; dictn < dict.length; dictn++) • { // check each dictionary entry • if (dict[dictn].getKey().equals(args[argn])) • System.out.println(dict[dictn].getValue()); • } • } • } • }
1.6 字列表( atinLay.java) • for (int argn = 0; argn < args.length; argn++) • { // for each argument • for (int dictn = 0; dictn < dict.length; dictn++) • { // check each dictionary entry • if (dict[dictn].getKey().equals(args[argn])) • System.out.println(dict[dictn].getValue()); • } • } • } • }
1.5 关联的应用( atinLay.java) • for (int argn = 0; argn < args.length; argn++) • { // for each argument • for (int dictn = 0; dictn < dict.length; dictn++) • { // check each dictionary entry • if (dict[dictn].getKey().equals(args[argn])) • System.out.println(dict[dictn].getValue()); • } • } • } • }
1.8 接口(Interface) • 描述接口而并不实现接口里面的方法 • 类中实现接口 • 增加灵活性 • Design by contract
1.8 接口(Interface) public interfaceStructure{ public int size(); public boolean isEmpty(); public void clear(); public boolean contains(Object value); public void add(); public void remove(); }
1.8 接口的实现 Public class Wordlist implements Structure { } interface Alarm { void alarm(); } abstract class Door { abstract void open(); abstract void close(); } class AlarmDoor extends Door implements Alarm { void open() { … } void close() { … } void alarm() { … } }
1.9 用户 • 程序员在将类导入到程序中时使用了类。 • 对于一些自己实现的类,自己可能是唯一的用户。 • 站在用户的角度设计并遵守你的接口。 • 程序的注释,文档 • 类的数据成员应受保护,不可从外部直接访问,需遵守接口访问规则
第二章 注释、条件、断言 • 基本概念 • 前提条件 • 后置条件 • 断言 • 版权代码
注释 • 精心设计的文字,用来描述程序中:变量的使用,机器的状态,设计者的意图和技巧等。 • 何时写注释?——应和程序代码同时编写。 • 注释出现在何处?——对代码感觉不放心的地方。 • 注释的作用——有利于理解程序代码。以便让别人或者今后自己查看原有代码。