日撸Java三百行(day12:顺序表二)

news2024/9/22 5:42:03

目录

一、关于昨天的补充

1.final关键字

2.toString()方法

二、今日代码实现

1.顺序表的查找操作

2.顺序表的插入操作

3.顺序表的删除操作

4.数据测试

总结


一、关于昨天的补充

1.final关键字

public static final int MAX_LENGTH = 10;

在昨天的这行代码中,用到了final关键字,这里我们进行一些补充。

关键字final,中文意思“最终的”,在java中声明方法变量时,我们可以用它来进行修饰,表示该引用不能被改变,具体规则如下:

  • final修饰的类不能被继承,比如String类、System类、StringBuffer类
  • final修饰的方法不能被重写,但可以被重载
  • final修饰的变量(成员变量或局部变量)不可以被更改,相当于常量(注:命名时全大写,单词之间用下划线隔开)

2.toString()方法

在java中,Object类是所有类的根基类,相当于所有类的“老祖宗”,因此每个类都直接或间接地继承Object类。而在Object类中,定义有public String toString()方法,其返回值为String类型。

如果没有重写toString()方法,那么就会调用默认的toString()方法,如下:

public String toString() {
   return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

但在大多数情况下,默认toString()方法的输出都不是我们想要的,所以我们会根据需要对其进行重写, 得到自己想要的格式,比如在昨天的代码中,我们就对toString()方法进行了如下的重写:

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

在使用String与其他数据类型进行拼接操作时,系统会自动调用该对象类的toString()方法。

例如:在昨天的主函数代码中,System.out.println("Initialized, the list is: " + tempFirstList.toString());System.out.println("Again, the list is: " + tempFirstList);的输出格式是完全一样的,这是由于字符串类型与tempFirstList相拼接,所以系统会自动调用tempFirstList.toString()方法。

public static void main(String[] args) {
   int[] tempArray = {1,4,6,9};
   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

二、今日代码实现

昨天我们学习了顺序表的一些基本概念,今天继续深入,进一步学习顺序表的相关操作。顺序表具有查找、插入、删除的功能,在昨天代码的基础上,下面进行相关方法的创建,利用java来实现这些功能。

1.顺序表的查找操作

首先是顺序表的查找操作,即给定一个元素,查找该元素在顺序表中的位置(用数组来解释就是查找该元素在数组中的索引值)。在大部分情况下,要实现顺序表的查找功能,使用的方法都是顺序查找,即按次序(一般是从头部到尾部)遍历整个数组,并在遍历的过程中将数组元素与给定元素一一进行比较,如果相同,则返回该数组元素的索引值,如果不同,则继续进行遍历。但是在查找的过程中,不可避免地会面临以下两个问题:

  • 如果在顺序表找不到该元素怎么办?
  • 如果在顺序表有两个及以上的位置都对应该元素,那么该元素的位置是哪一个呢?

对于第一个问题,我们采取一个很常见的小技巧,就是利用非法值-1,如果在顺序表中我们没有找到该元素,那么则返回-1;而第二个问题,普遍的处理方式就是以首次出现的为准。

下面进行方法创建:

    /**
	 *********************
	 *Find the index of the given value. If it appears in multiple positions,
	 *simply return the first one.
	 *
	 * @param paraValue The given value.
	 * @return The position. -1 for not found.
	 *********************
	 */
	public int indexOf(int paraValue) {
		int tempPosition = -1;
		
		for (int i = 0; i < length; i++) {
			if (data[i] == paraValue)  {
				tempPosition = i;
				break;
			} // of if
		} // of for i
		
		return tempPosition;
	} // of indexOf

在上述代码中, 我们需要注意三个点:

  • if语句中,判断数组元素与给定元素是否相等时,用的是==,而不是赋值运算符=
  • 为了避免输出多个位置,我们规定以首次出现的为准,所以在if语句中,需要利用break来中断循环,即当数组元素与给定元素首次相等时,就立马跳出循环,输出此时数组元素对应的索引值
  • 由于定义方法时,规定了返回值类型为int型,所以最后一定不要忘记写上return语句

2.顺序表的插入操作

顺序表的插入操作一般包括在头部插入元素、在尾部插入元素以及在指定位置插入元素,显然,在指定位置插入元素的方法也可以实现“头插”、“尾插”,所以这里我们直接创建在指定位置插入元素的方法。不过,在此之前,我们需要考虑两个问题:

  • 在插入元素之前,顺序表如果已经达到最大长度了怎么办?
  • 所指定的位置非法怎么办?

为使得所创建的顺序表插入的方法能够正常运行,必须排除以上两个问题的干扰。第一个问题,直接用if语句进行一个判断即可,如下:

if (length == MAX_LENGTH) {
   System.out.println("List full.");
   return false;
} // of if

而针对第二个问题,我们首先要知道什么是“非法位置”,当指定位置小于最小索引值0时,显然非法;当指定位置大于顺序表此时(插入前)的长度length时,也是非法的,这是因为顺序表此时(插入前)的长度为length,则顺序表此时(插入前)的最大索引值为length-1,而我们最多在尾部进行插入,所以指定位置最大达到索引值length,不可能比length还大。

解决这两个问题后,就可以进行插入操作了。顺序表的插入操作其实就是将指定位置的原数组元素用给定的元素进行覆盖,然后把从指定位置开始一直到尾部的原数组元素通通往后移,为方便理解,我们用图解法来说明这个过程,如下图:

弄清楚顺序表的插入过程后,再用代码来模拟这个过程,如下:

// From tail to head. The last one is moved to a new position. Because length < MAX_LENGTH, no exceeding occurs. 
for (int i = length; i > paraPosition; i--) {
   data[i] = data[i - 1];
} // of for i
		
data[paraPosition] = paraValue;
length++;
		
return true;

首先,利用for循环从尾部到指定位置进行遍历(因为指定位置之前的元素并没有发生改变,所以只需遍历至指定位置即可),然后data[i] = data[i - 1]实现了从尾部到指定位置的原数组元素的后移,再将给定元素赋给指定位置即可完成顺序表的插入操作。

//注意是从尾部开始遍历,而不是从头部开始,因为只有从尾部开始遍历,才能实现向后覆盖

//注意最后length要增加一

完整的方法创建代码如下: 

    /**
	 *********************
	 *Insert a value to a position. If the list is already full, do nothing.
	 *
	 * @param paraPosition The given position.
	 * @param paraValue    The given value.
	 * @return Success or not.
	 *********************
	 */
	public boolean insert(int paraPosition, int paraValue) {
		if (length == MAX_LENGTH) {
			System.out.println("List full.");
			return false;
		} // of if
		
		if ((paraPosition < 0) || (paraPosition > length)) {
			System.out.println("The position " + paraPosition + " is out of the bound.");
			return false;
		} // of if
		
		// From tail to head. The last one is moved to a new position. Because length < MAX_LENGTH, no exceeding occurs. 
		for (int i = length; i > paraPosition; i--) {
			data[i] = data[i - 1];
		} // of for i
		
		data[paraPosition] = paraValue;
		length++;
		
		return true;
	} // of insert

3.顺序表的删除操作

和顺序表的插入操作一样,顺序表的删除操作也分为“头删”、“尾删”和删除指定位置的元素,这里我们同样只创建在指定位置进行删除操作的方法。因为删除操作不需要考虑顺序表是否已满(不过好像可以考虑一下顺序表长度是否为0?),所以我们直接判断指定位置是否非法即可,判断代码和顺序表插入操作中的并无二异。

判断完毕之后,进行删除操作,顺序表的删除操作其实说白了就是用后一个位置的元素去覆盖前一个位置的元素,图解如下:

与顺序表的插入操作不同,这里我们需要从指定位置开始遍历到尾部,代码模拟如下:

    /**
	 *********************
	 *Delete a value at a position.
	 *
	 * @param paraPosition The given position.
	 * @return Success or not.
	 *********************
	 */
	public boolean delete(int paraPosition) {
		if ((paraPosition < 0) || (paraPosition >= length)) {
			System.out.println("The position " + paraPosition + " is out of the bound.");
			return false;
		} // of if
		
		// From head to tail.
		for (int i = paraPosition; i < length - 1; i++) {
			data[i] = data[i + 1];
		} // of for i
		
		length--;
		
		return true;
	} // of delete

在代码中,语句data[i] = data[i + 1];就实现了向前覆盖,不过,需要注意到其中for循环的循环条件为i < length - 1,这是因为length是顺序表的长度,所以length - 1就是删除前的最大索引值,i < length - 1则说明i最大可以取到倒数第二个位置的索引值,i + 1最大可以取得最后一个位置的索引值,这样就保证了指定位置之后的所有元素都可以实现向前覆盖。

4.数据测试

创建好以上三个方法之后,我们利用一个数组进行数据测试,如下:

public static void main(String[] args) {
		int[] tempArray = {1,4,6,9};
		SequentialList tempFirstList = new SequentialList(tempArray);
		System.out.println("After initialization, the list is: " + tempFirstList.toString());
		System.out.println("Again, the list is: " + tempFirstList);
		
		int tempValue = 4;
		int tempPosition = tempFirstList.indexOf(tempValue);
		System.out.println("The position of " + tempValue + " is " + tempPosition);
		
		tempValue = 5;
	   	tempPosition = tempFirstList.indexOf(tempValue);
	   	System.out.println("The position of " + tempValue + " is " + tempPosition);

	   	tempPosition = 2;
	   	tempValue = 5;
	   	tempFirstList.insert(tempPosition, tempValue);
	   	System.out.println(
	   			"After inserting " + tempValue + " to position " + tempPosition + ", the list is: " + tempFirstList);

	   	tempPosition = 8;
	   	tempValue = 10;
	   	tempFirstList.insert(tempPosition, tempValue);
	   	System.out.println(
	   			"After inserting " + tempValue + " to position " + tempPosition + ", the list is: " + tempFirstList);

	   	tempPosition = 3;
	   	tempFirstList.delete(tempPosition);
	   	System.out.println("After deleting data at position " + tempPosition + ", the list is: " + tempFirstList);

	   	for (int i = 0; i < 8; i++) {
	   		tempFirstList.insert(i, i);
	   		System.out.println("After inserting " + i + " to position " + i + ", the list is: " + tempFirstList);
	   	} // Of for i

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

结合今天的三个方法与数据测试以及昨天的代码,得到完整的程序代码:

package datastructure.list;

/**
 *Sequential list.
 *
 *@auther Xin Lin 3101540094@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;
	
	/**
	 *********************
	 *Construct an empty sequential list.
	 *********************
	 */
	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 empty.
	 *********************
	 */
	public void reset() {
		length = 0;
	} // of reset

	/**
	 *********************
	 *Find the index of the given value. If it appears in multiple positions,
	 *simply return the first one.
	 *
	 * @param paraValue The given value.
	 * @return The position. -1 for not found.
	 *********************
	 */
	public int indexOf(int paraValue) {
		int tempPosition = -1;
		
		for (int i = 0; i < length; i++) {
			if (data[i] == paraValue)  {
				tempPosition = i;
				break;
			} // of if
		} // of for i
		
		return tempPosition;
	} // of indexOf
	
	/**
	 *********************
	 *Insert a value to a position. If the list is already full, do nothing.
	 *
	 * @param paraPosition The given position.
	 * @param paraValue    The given value.
	 * @return Success or not.
	 *********************
	 */
	public boolean insert(int paraPosition, int paraValue) {
		if (length == MAX_LENGTH) {
			System.out.println("List full.");
			return false;
		} // of if
		
		if ((paraPosition < 0) || (paraPosition > length)) {
			System.out.println("The position " + paraPosition + " is out of the bound.");
			return false;
		} // of if
		
		// From tail to head. The last one is moved to a new position. Because length < MAX_LENGTH, no exceeding occurs. 
		for (int i = length; i > paraPosition; i--) {
			data[i] = data[i - 1];
		} // of for i
		
		data[paraPosition] = paraValue;
		length++;
		
		return true;
	} // of insert
	
	/**
	 *********************
	 *Delete a value at a position.
	 *
	 * @param paraPosition The given position.
	 * @return Success or not.
	 *********************
	 */
	public boolean delete(int paraPosition) {
		if ((paraPosition < 0) || (paraPosition >= length)) {
			System.out.println("The position " + paraPosition + " is out of the bound.");
			return false;
		} // of if
		
		// From head to tail.
		for (int i = paraPosition; i < length - 1; i++) {
			data[i] = data[i + 1];
		} // of for i
		
		length--;
		
		return true;
	} // of delete

	/**
	 *********************
	 *The entrance of the program.
	 *
	 * @param args Not used now.
	 *********************
	 */
	public static void main(String[] args) {
		int[] tempArray = {1,4,6,9};
		SequentialList tempFirstList = new SequentialList(tempArray);
		System.out.println("After initialization, the list is: " + tempFirstList.toString());
		System.out.println("Again, the list is: " + tempFirstList);
		
		int tempValue = 4;
		int tempPosition = tempFirstList.indexOf(tempValue);
		System.out.println("The position of " + tempValue + " is " + tempPosition);
		
		tempValue = 5;
	   	tempPosition = tempFirstList.indexOf(tempValue);
	   	System.out.println("The position of " + tempValue + " is " + tempPosition);

	   	tempPosition = 2;
	   	tempValue = 5;
	   	tempFirstList.insert(tempPosition, tempValue);
	   	System.out.println(
	   			"After inserting " + tempValue + " to position " + tempPosition + ", the list is: " + tempFirstList);

	   	tempPosition = 8;
	   	tempValue = 10;
	   	tempFirstList.insert(tempPosition, tempValue);
	   	System.out.println(
	   			"After inserting " + tempValue + " to position " + tempPosition + ", the list is: " + tempFirstList);

	   	tempPosition = 3;
	   	tempFirstList.delete(tempPosition);
	   	System.out.println("After deleting data at position " + tempPosition + ", the list is: " + tempFirstList);

	   	for (int i = 0; i < 8; i++) {
	   		tempFirstList.insert(i, i);
	   		System.out.println("After inserting " + i + " to position " + i + ", the list is: " + tempFirstList);
	   	} // Of for i

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

运行结果:

总结

今天我们主要通过顺序表查找、插入、删除这三个操作来深入理解和学习顺序表,可以发现顺序表的查找操作较迅速,其时间复杂度为O(1),这也是顺序表的优势所在。但是顺序表的缺点也是显而易见的,由于顺序表是顺序存储结构,要求其内的元素在存储时必须紧密相连,不能出现“空白”,所以这就造成了顺序表不能随意、直接地进行插入和删除,必须通过一大段元素移动覆盖的方式间接完成,因此其时间复杂度就为O(n)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1977094.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OpenCV||超详细的灰度变换和直方图修正

一、点运算 概念&#xff1a;点运算&#xff08;也称为像素级运算或单像素操作&#xff09;是指对图像中每一个像素点进行独立、相同的操作&#xff0c;而这些操作不会考虑像素点之间的空间关系。点处理优势也称对比度拉伸、对比度增强或灰度变换等。 目的&#xff1a;点运算…

操作系统|day3.锁、I/O多路复用、中断

协程 概念 协程是微线程&#xff0c;在子程序内部执行&#xff0c;可在子程序内部中断&#xff0c;转而执行别的子程序&#xff0c;在适当的时候再返回来接着执行。 优势 协程调用跟切换比线程效率高&#xff1a;协程执行效率极高。协程不需要多线程的锁机制&#xff0c;可…

项目经验分享:用4G路由器CPE接海康NVR采用国标GB28181协议TCP被动取流一段时间后设备就掉线了

最近我们在做一个生态化养殖的项目时&#xff0c;发现一个奇怪的现象&#xff1a; 项目现场由于没有有线网络&#xff0c;所以&#xff0c;我们在现场IPC接入到海康NVR之后&#xff0c;再通过一款4G的CPE接入到天翼云的国标GB28181视频平台&#xff1b;我们采用UDP协议播放NVR…

BERT模型

BERT模型是由谷歌团队于2019年提出的 Encoder-only 的 语言模型&#xff0c;发表于NLP顶会ACL上。原文题目为&#xff1a;《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》链接 在前大模型时代&#xff0c;BERT模型可以算是一个参数量比…

杂记123

(前提已安装了Beyond Compare4)在Everything的文件-右键菜单项里没有Beyond Compare的"选择左边文件进行比较"的现象 进过调查,LZ本机是X64位的,但是安装了x86(32位)的Everything, 切换成X64位的Everything版本就好了

数据结构之《二叉树》(中)

在数据结构之《二叉树》(上)中学习了树的相关概念&#xff0c;还了解的树中的二叉树的顺序结构和链式结构&#xff0c;在本篇中我们将重点学习二叉树中的堆的相关概念与性质&#xff0c;同时试着实现堆中的相关方法&#xff0c;一起加油吧&#xff01; 1.实现顺序结构二叉树 在…

详细测评下搬瓦工香港CN2 GIA VPS

搬瓦工香港VPS分移动CMI和电信CN2 GIA两个大类&#xff0c;一个属于骨干网&#xff0c;一个属于轻负载。搬瓦工的香港CN2 GIA根据测试来看实际上是CN2 GIABGP&#xff0c;并非三网纯CN2 GIA。详细测评数据如下&#xff1a; 用FIO再给测试一下硬盘I/O&#xff0c;可以仔细看看数…

全网最适合入门的面向对象编程教程:31 Python的内置数据类型-对象Object和类型Type

全网最适合入门的面向对象编程教程&#xff1a;31 Python 的内置数据类型-对象 Object 和类型 Type 摘要&#xff1a; Python 中的对象和类型是一个非常重要的概念。在 Python 中,一切都是对象,包括数字、字符串、列表等,每个对象都有自己的类型。 原文链接&#xff1a; Fre…

WebSocket 协议介绍

前言 一.通用协议设计 参考链接 /* --------------------------------------------------------------- | 魔数 2byte | 协议版本号 1byte | 序列化算法 1byte | 报文类型 1byte | --------------------------------------------------------------- | 状态 1byte | …

前端HTML+CSS查漏补缺——仿制百度搜索首页的一些思考

在像素模仿百度搜索首页的时候&#xff0c;在实现的时候&#xff0c;遇到了一些值得记录的点。 在这个过程中&#xff0c;也顺便看了看百度的源码&#xff0c;感觉很有意思。 对了&#xff0c;QQ截屏里面获取到的颜色&#xff0c;是不大正确的&#xff0c;会有点误差。 这是我…

TypeError: ‘float’ object is not iterable 深度解析

TypeError: ‘float’ object is not iterable 深度解析与实战指南 在Python编程中&#xff0c;TypeError: float object is not iterable是一个常见的错误&#xff0c;通常发生在尝试对浮点数&#xff08;float&#xff09;进行迭代操作时。这个错误表明代码中存在类型使用不…

Study--Oracle-08-ORACLE数据备份与恢复(一)

一、ORACLE数据保护方案 1、oracle数据保护方案 2、数据库物理保护方案 oracle数据库备份可以备份到本地集群存储&#xff0c;也可以备份到云存储。 3、数据库逻辑数据保护方案 二、ORACLE数据体系 1、ORACLE 数据库的存储结构 2、oracle物理和逻辑存储结构 3、数据库进程 4…

OpenCV||超简略的Numpy小tip

一、基本类型 二、数组属性 三、数组迭代&#xff08;了解&#xff09; import numpy as np # 创建一个数组 a np.arange(6).reshape(2, 3) # 使用np.nditer遍历数组 for x in np.nditer(a): print(x) np.nditer有多个参数&#xff0c;用于控制迭代器的行为&#xff…

一层5x1神经网络绘制训练100轮后权重变化的图像

要完成这个任务&#xff0c;我们可以使用Python中的PyTorch库来建立一个简单的神经网络&#xff0c;网络结构只有一个输入层和一个输出层&#xff0c;输入层有5个节点&#xff0c;输出层有1个节点。训练过程中&#xff0c;我们将记录权重的变化&#xff0c;并在训练100轮后绘制…

显示学习5(基于树莓派Pico) -- 彩色LCD的驱动

和这篇也算是姊妹篇&#xff0c;只是一个侧重SPI协议&#xff0c;一个侧重显示驱动。 总线学习3--SPI-CSDN博客 驱动来自&#xff1a;https://github.com/boochow/MicroPython-ST7735 所以这里主要还是学习。 代码Init def __init__( self, spi, aDC, aReset, aCS) :"&…

数据结构(5.4_2)——树和森林的遍历

树的先根遍历(深度优先遍历) 若树非空&#xff0c;先访问根结点&#xff0c;再依次对每棵子树进行先根遍历 树的先根遍历序列和这棵树相应二叉树的先序序列相同。 伪代码&#xff1a; //树的先根遍历 void PreOrder(TreeNode* R) {if (R ! NULL) {visit(R);//访问根结点w…

【WRF安装第四期(Ubuntu)】搭建WRF编译所需系统-WRF和WPS模型的安装

WRF安装第四期&#xff1a;搭建WRF编译所需系统-WRF和WPS模型的安装 1 WRF的编译安装&#xff08;Building WRF&#xff09;1.1 进入Build_WRF文件夹1.2 下载WRFV4.01.3 解压WRF安装包1.4 安装WRF选择#1&#xff1a;34选择#2&#xff1a;32 1.5 检查WRF是否安装成功1.5.1 WRF安…

ai文案生成器,文案自动生成好简单

随着科技的不断进步&#xff0c;AI在各个领域中扮演着越来越重要的角色。其中&#xff0c;ai文案生成器的出现给广告和市场营销行业带来了一场革命。曾经需要耗费大量时间和精力的文案创作过程&#xff0c;如今可以通过ai文案生成器轻松自动完成。这一创新技术的出现&#xff0…

什么是药物临床试验?

药物临床试验是指在人体上进行的新药试验研究&#xff0c;旨在确定新药的疗效、安全性、药代动力学和药效学。临床试验不仅帮助确认药物是否对特定疾病或症状有效&#xff0c;还帮助识别和评估药物的副作用和风险。 药物临床试验&#xff08;Clinical Trial&#xff0c;CT&…

数据结构:带索引的双链表IDL

IDLindexed double list 如图&#xff0c;下方是一个双链表&#xff0c;上方是索引。索引储存为结构体数组&#xff0c;结构体内包括一个指针&#xff0c;和长度。 假设索引只有一个&#xff0c;这时&#xff0c;它应该指向双链表的中间&#xff0c;这样才能提高搜索效率。称…