日撸 Java 三百行(11天,顺序表(一))

日撸 Java 三百行(11天,顺序表(一))

注意:这里是JAVA自学与了解的同步笔记与记录,如有问题欢迎指正说明


一、关于顺序表的那些二三事

顺表是数据结构的开篇之作,也是很多计算机学习初识计算机相关算法与逻辑体系的开篇。最为数据结构中最简单最基础的部分,其在编程领域占据的重要程度也是不言而喻。

简单介绍下这位熟人吧:(部分语言参考互联网)
顺序表从属于线性表这一个大类 。线性表,全名为线性存储结构,使用线性表存储数据的方式可以这样理解,即“把所有数据用一根线儿串起来,再存储到物理空间中”。

在这里插入图片描述
而在物理空间中的不同存储方式派生出顺序表与链表两个分集,其中顺序表的特点在于逻辑上相连的空间在物理地址上也是绝对相连的,这种绝对相连的过程构成了线性表的顺序存储,从而简称“顺序表”。

具体来说顺序表,其用一组地址连续的存储单元依次存储线性表中的各个元素,使得线性表在逻辑结构上相邻的元素存储在连续的物理存储单元中:

即:通过数据元素物理存储的连续性来反应元素之间逻辑上的相邻关系。又因为地址空间的定长特点,可以实现随机存取。

一般来说,所有的编程语言模拟顺序表的方法都是通过数组,因为数组的存储与逻辑结构与顺序表几乎完全一致。


二、补充:面向对象的JAVA

为什么要重谈“java的类”?

数据结构包括了数据本身以及定义在这个数据上的一组操作,这个与抽象数据类型(Abstract Data Type 简称ADT)的说法类似,而定义数据结构的过程也确实可以看在逻辑上定义抽象数据类型的过程。

经过早期面向过程编程的试错后,后续诞生的面向对象的编程语言才彻底意义上实现了抽象数据类型的构造——即通过封装数据对象。至此,真正实现了编程层面的类的设计与逻辑层面的数据抽象类型设计的一致性。

这里之所以重谈Java的类,是因为我们后续的所有数据结构都是ADT的一种体现,因此都会用类封装的方式呈现,所有对于数据结构的操作,也将用局部于类的方法实现。(当然,最开始几天提到的类的一些使用方法在下面就不再重述了)

1.关键字final

final关键字可以用来修饰引用、方法和类。具体使用我会在接下来的代码说明中辅助解释,这里就简单看下作用(方便后来忘记时可以查看),再或者可以参考链接这个网站来看相关案例。

–>a.用来修饰一个引用时,要注意

  1. 引用为基本数据类型,则该引用为常量,该值无法修改
  2. 引用数据类型,比如对象、数组,则该对象、数组本身可以修改,但指向该对象或数组的地址的引用不能修改
  3. 如果引用时类的成员变量,则必须当场赋值,否则编译会报错

–>b.用来修饰一个方法时,要注意

  1. 当使用final修饰方法时,这个方法将成为最终方法,无法被子类重写。但是,该方法仍然可以被继承。

–>c.用来修饰一个类时,要注意

  1. 当用final修改类时,该类成为最终类,无法被继承。简称为“断子绝孙类”。

2.Java中方法重载(Overloading)

重载是类中非常优良的特性,其增强了同一个方法应用于不同场合的适应性,扩充了函数带入变量的丰富度。具体使用办法是为想扩充使用场景的函数方法再写个函数,这个新函数名字相同,而参数不同,甚至返回类型也可以相同也可以不同。·(所以,每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。)
在类中,我们往往会对构造函数进行重载。

3.Java中方法重写(Override)

重写是类的另一个特点,一般来说,是继承方案中的常客,其可以继承父亲的方法并且重写其核心,从而专门针对本类发挥出独特作用。
所以,重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
重写与重载是不同的,无论是他们完成的功能来说来说,还是使用的方法来说。用文化类比,前者像是一种前人的传统在今天的新说法,而后者更像是传统本身可以的多种说法。
下面这张图的描述简直不要太准确:
在这里插入图片描述
当然诸多规则不是今天的重点,具体使用细则可见这个网站。当然关于重写与重载的区别也可参考这个网站,过多内容就不再赘述了。


三.代码实现

在完成了知识准备后,我们就可以用代码来完成今天的任务了

1.顺序表的属性

	/**
	 * The maximal length of the list. It is a constant.
	 */
	public static final int MAX_LENGTH = 10;

	/**
	 * The actual length not exceeding MAX_LENGTH. Attention: length is not only the
	 * member variable of Sequential list, but also the member variable of Array. In
	 * fact, a name can be the member variable of different classes.
	 */
	int length;

	/**
	 * The data stored in an array.
	 */
	int[] data;

这些内容是对于顺序表数据结构需要使用的属性,本代码构建的是静态创建的顺序表,因此在最开始就需要限定顺序表的分配长度而无法在后期再更改(MAX_LENGTH)。所以使用了final int这个关键字,综上,final限制基本的系统数据类型后,此类型无法被更改,如同常量一样(就像C++的const,另外这种常量声明的名称标识都必须是大写表示,这虽然不是编译器强制的,但是是我们统一的习惯)

2.顺序表的方法

特别说明,此类的名称叫做SequentialList()

	public SequentialList() {
		length = 0;
		data = new int[MAX_LENGTH];
	}// Of the first constructor

	/**
	 *********************
	 * Construct a sequential list using an array.
	 * 
	 * @param paraArray The given array. Its length should not exceed MAX_LENGTH.
	 *                  For simplicity now we do not check it.
	 *********************
	 */
	public SequentialList(int[] paraArray) {
		data = new int[MAX_LENGTH];
		length = paraArray.length;

		// Copy data.
		for (int i = 0; i < paraArray.length; i++) {
			data[i] = paraArray[i];
		} // Of for i
	}// Of the second constructor

	/**
	 *********************
	 * Overrides the method claimed in Object, the superclass of any class.
	 *********************
	 */
	public String toString() {
		String resultString = "";

		if (length == 0) {
			return "empty";
		} // Of if

		for (int i = 0; i < length - 1; i++) {
			resultString += data[i] + ",";
		} // Of for i

		resultString += data[length - 1];

		return resultString;
	}// Of toString

	/**
	 *********************
	 * Reset to emppty
	 *********************
	 */
	public void reset() {
		length = 0;
	}// Of reset

这里对于构造函数使用了重载,public SequentialList()创建了个无参构造函数,public SequentialList(int[] paraArray)构造了输入数组作为参数的构造函数。前者适合于一般情况下我们初始化顺序表的操作,后者能非常快捷完成数据的复制操作。

此外,这里还重写了Object的toString()方法(Java中所有类都是Object类的儿子),因为这个方法与print()方法挂钩,重写了这个方法后,我们创建的对象就能通过print操作打印出数据,能更加方便数据的使用以及可读性。

四.代码总览与输出测试

代码如下

package datastructure;

/**
 * Sequential list.
 * 
 * @author Xingyi Zhang 1328365276@qq.com
 */

public class SequentialList {

	/**
	 * The maximal length of the list. It is a constant.
	 */
	public static final int MAX_LENGTH = 10;

	/**
	 * The actual length not exceeding MAX_LENGTH. Attention: length is not only the
	 * member variable of Sequential list, but also the member variable of Array. In
	 * fact, a name can be the member variable of different classes.
	 */
	int length;

	/**
	 * The data stored in an array.
	 */
	int[] data;

	public SequentialList() {
		length = 0;
		data = new int[MAX_LENGTH];
	}// Of the first constructor

	/**
	 *********************
	 * Construct a sequential list using an array.
	 * 
	 * @param paraArray The given array. Its length should not exceed MAX_LENGTH.
	 *                  For simplicity now we do not check it.
	 *********************
	 */
	public SequentialList(int[] paraArray) {
		data = new int[MAX_LENGTH];
		length = paraArray.length;

		// Copy data.
		for (int i = 0; i < paraArray.length; i++) {
			data[i] = paraArray[i];
		} // Of for i
	}// Of the second constructor

	/**
	 *********************
	 * Overrides the method claimed in Object, the superclass of any class.
	 *********************
	 */
	public String toString() {
		String resultString = "";

		if (length == 0) {
			return "empty";
		} // Of if

		for (int i = 0; i < length - 1; i++) {
			resultString += data[i] + ",";
		} // Of for i

		resultString += data[length - 1];

		return resultString;
	}// Of toString

	/**
	 *********************
	 * Reset to emppty
	 *********************
	 */
	public void reset() {
		length = 0;
	}// Of reset

	public static void main(String args[]) {
		int[] tempArray = { 1, 4, 6, 7 };
		SequentialList tempFirstList = new SequentialList(tempArray);
		System.out.println("Initialized, the list is: " + tempFirstList.toString());
		System.out.println("Again, the list is: " + tempFirstList);

		tempFirstList.reset();
		System.out.println("After reset, the list is: " + tempFirstList);
	}// Of main

}// Of class SequentialList

显示如下
在这里插入图片描述
这次测试了重写后对象中的方法的输出效果,两次输出分别是直接调用对象本身的方法toString()与toString()本身重写特征下影响的println()方法中对于此对象的识别。
最后是测试空数据是否能正常输出我们自定义的重写内容。


总结

顺序表简单吗?

从理论来看,简单,因为其内核是思想很符合我们正常人的思维,无论是你在买凉菜时排队的人群,还是去成都路上堵车的高速公路,又或者是打牌时把几个同数字的放在一起准备炸了…这些都是顺序表的思维,也都体现了顺序表的处理方法。

但是从实践层面来看,有人说,很多计算机的问题,本质上都可以视为字符串的处理。字符串处理是数据处理中最基础也是最麻烦也是的问题,而字符串本身上就是顺序表的字符表现。

计算机算法领域的非常重要的查找与排序问题也是属于顺序表问题,SQL数据库中也充满各种顺序表的信息展现,其中是否能选取合理的索引结构,能影响整个数据库的效率。

顺序表是困难的,因为顺序表要对仅仅局限于一对一的存储结构中,实现对于全局数据的感知。很多逻辑结构,人为感知很简单,因为人脑可以快速提取一个顺序段的信息,但是,用程序抽象却格外困难。因为,本质上,这是逻辑丰富与物理存储单一的矛盾。

而我们计算机人研究算法的过程,正是实现逻辑与存储的统一性的过程。

所以,顺序表简单吗?也许是简单的,但是,因为能蕴含计算机中大多数数据处理的内涵,以及线性表本身在诸多困难算法问题中无处不在的声影,也许来说,顺序表也是最复杂的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值