资源描述
数据结构实验指导书Java语言版
182
2020年4月19日
文档仅供参考
《数据结构》课程实验指导
《数据结构》实验教学大纲
课程代码: 开课学期:3 开课专业:信息管理与信息系统
总学时/实验学时:64/16 总学分/实验学分:3.5/0.5
一、课程简介
数据结构是计算机各专业的重要技术基础课。在计算机科学中,数据结构不但是一般程序设计的基础,而且是编译原理、操作系统、数据库系统及其它系统程序和大型应用程序开发的重要基础。数据结构课程主要讨论各种主要数据结构的特点、计算机内的表示方法、处理数据的算法以及对算法性能的分析。经过对本课程的系统学习使学生掌握各种数据结构的特点、存储表示、运算的原理和方法,学会从问题入手,分析研究计算机加工的数据结构的特性,以便为应用所涉及的数据选择适当的逻辑结构、存储机构及其相应的操作算法,并初步掌握时间和空间分析技术。另一方面,本课程的学习过程也是进行复杂程序设计的训练过程,经过对本课程算法设计和上机实践的训练,还应培养学生的数据抽象能力和程序设计的能力。
二、实验的地位、作用和目的
数据结构是一门实践性较强的基础课程,本课程实验主要是着眼于原理和应用的结合,经过实验,一方面能使学生学会把书上学到的知识用于解决实际问题,加强培养学生如何根据计算机所处理对象的特点来组织数据存储和编写性能好的操作算法的能力,为以后相关课程的学习和大型软件的开发打下扎实的基础。另一方面使书上的知识变活,起到深化理解和灵活掌握教学内容的目的。
三、实验方式与基本要求
实验方式是上机编写完成实验项目指定功能的程序,并调试、运行,最终得出正确结果。具体实验要求如下:
1. 问题分析
充分地分析和理解问题本身,弄清要求,包括功能要求、性能要求、设计要求和约束,以及基本数据特性、数据间联系等等。
2. 数据结构设计
针对要解决的问题,考虑各种可能的数据结构,而且力求从中选出最佳方案(必须连同算法实现一起考虑),确定主要的数据结构和全程变量。对引入的每种数据结构和全程变量要详细说明其功用、初值和操作的特点。
3. 算法设计
算法设计分概要和详细设计。概要设计着重解决程序的类的设计问题,这包括考虑如何把被开发的问题程序分解成若干个类,并决定类与类之间的关系。详细设计则要决定每个类内部的具体算法,包括输入、处理和输出。
4. 测试用例设计
准备典型测试数据和测试方案。测试数据要有代表性、敏感性。测试方案包括单元测试和单元集成测试。
5. 上机调试
对程序进行编译,纠正程序中可能出现的语法错误。调试前,先运行一遍程序看看究竟将会发生什么。如果情况很糟,则根据事先设计的测试方案并结合现场情况进行错误跟踪,包括打印执行路径或输出中间变量值等手段。
6. 程序性能分析
在运行结果正确的前提下再分析程序中主要算法是否具有较好的时间复杂度和空间复杂度。如果没有,则经过改变数据结构或操作方法使编写的程序性能达到最佳。
7. 实验总结
每个实验完成后要认真书写实验报告,对程序运行的结构,要认真分析,总结每次实验项目的体会与收获。
四、报告与考核
每个实验都要求学生根据上机内容写出实验报告,报告要求包括以下七个方面的内容:
1.实验目的;
2.实验内容;
3.实验要求;
4.算法设计;
5.详细程序清单;
6.程序运行结果;
7.实验心得体会。
考核方式:
每个实验项目根据以下两个方面进行考核:
1.指导教师随堂抽查学生的实验过程(包括实验预习、实验出勤、实验结果的测试),并根据抽查结果评定学生成绩,此成绩占此实验总成绩的70%;
2.学生编写课程实验报告,每位学生按照实验报告的内容和要求编写详细的实验报告上交给指导老师,由指导老师根据每位学生的完成情况评定成绩,此成绩占实验总成绩的30%。
五、设备及器材材料配置
硬件:奔腾以上PC机
软件:Netbeans 6.5以上或Eclipse、MyEclipse等编程环境
六、实验指导书及主要参考书
[1]刘小晶.数据结构实验指导书(Java语言版)
[2] Robert Lafore著,计晓云等译. Java数据结构和算法(第二版)[M]. 北京:中国电力出版社, .
[3] Sartaj Sahni著,孔芳,高伟译. 数据结构、算法与应用(Java语言描述)[M]. 北京:中国水利水电出版社, .
[4] 叶核亚. 数据结构(Java版)[M]. 北京:电子工业出版社, .
[5] 邓俊辉. 数据结构与算法(Java语言描述)[M]. 北京:机械工业出版社, .
[6] 朱战立. 数据结构- Java语言描述[M]. 北京:清华大学出版社, .
[7] 张铭.数据结构与算法. 高教出版社. .6
[8] 张铭.数据结构与算法--学习指导与习题解析. 高教出版社.
[9] 耿国华等 数据结构-C语言描述. 高教出版社. .7
[10] 刘怀亮. 数据结构(C语言描述) .冶金出版社. .2
[11] 刘怀亮. 数据结构(C语言描述)习题与实验指导导.冶金出版社. .2
[12] 蔡子经,施伯乐.数据结构教程.上海:复旦大学出版社.1994
[13] 严蔚敏,吴伟民.数据结构(C语言版).北京:清华大学出版社.1999;
[14] 严蔚敏,吴伟民.数据结构题集(C语言版).北京:清华大学出版社.1999;
[15] 徐孝凯.数据结构课程实验.北京:清华大学出版社. ;
[16] 孟佳娜,胡潇琨.算法与数据结构实验与习题.北京:机械工业出版社. .
七、实验项目与内容提要
序号
实验名称
目的要求、内容提要
(限20字)
每组人数
实验学时
实验类型
必做
选做
所在实验分室
1
顺序表的基本操作
熟悉并完成顺序表上基本操作的算法及其应用问题的编程实现。
1个班
2
验证与设计
必做
2
链表的基本操作
熟悉并完成单链表和双向链表基本操作算法的编程实现。
1个班
2
验证与设计
必做
3
栈的基本操作
熟悉并完成顺序栈和链栈基本操作算法及其应用问题的编程实现
1个班
2
验证与设计
必做
4
队列的基本操作
熟悉并完成循环顺序队列和循环链队列基本操作算法及其应用问题的编程实现。
1个班
2
验证与设计
必做
5
二叉树的操作
熟悉并完成二叉树遍历算法及其应用问题的编程实现。。
1个班
2
验证与设计
必做
6
静态查找表的查找操作
熟悉并完成静态查找表上的顺序查找、二分查找和索引查找算法的编程实现
1个班
2
验证与设计
必做
7
二叉排序树的查找操作
熟悉并完成在二叉排序树上进行查找、插入和删除操作的编程实现。
1个班
2
验证与设计
选做
8
哈希表上的查找操作
熟悉并完成哈希表的建立、查找和插入操作的编程实现
1个班
2
验证与设计
选做
9
排序操作
熟悉并完成几种主要排序操作的编程实现。
1个班
2
验证与设计
必做
10
图的遍历
熟悉并完成图的遍历、最小生成树及其应用问题的编程实现
1个班
2
验证与设计
选做
实验B01: 顺序表的操作实验
一、实验名称和性质
所属课程
数据结构
实验名称
顺序表的操作
实验学时
2
实验性质
√验证 □综合 √设计
必做/选做
√必做 □选做
二、实验目的
1.掌握线性表的顺序存储结构的表示和实现方法。
2.掌握顺序表基本操作的算法实现。
3.了解顺序表的应用。
三、实验内容
1.建立顺序表。
2.在顺序表上实现插入、删除和查找操作(验证性内容)。
3.删除有序顺序表中的重复元素(设计性内容)。
4.完成一个简单学生成绩管理系统的设计(应用性设计内容)。
四、实验的软硬件环境要求
硬件环境要求:
PC机(单机)
使用的软件名称、版本号以及模块:
Netbeans 6.5以上或Eclipse、MyEclipse等编程环境下 。
五、知识准备
前期要求熟练掌握了Java语言的编程规则、方法和顺序表的基本操作算法。
六、验证性实验
1.实验要求
编程实现如下功能:
(1)根据输入顺序表的长度n和各个数据元素值建立一个顺序表,并输出顺序表中各元素值,观察输入的内容与输出的内容是否一致。
(2)在顺序表的第i(0≤i≤n)个元素之前插入一个值为x的元素,并输出插入后的顺序表中各元素值。
(3)删除顺序表中第i(0≤i≤n-1)个元素,并输出删除后的顺序表中各元素值。
(4)在顺序表中查找值为x的数据元素初次出现的位置。如果查找成功,则返回该数据元素在顺序表中的位序号;如果查找失败,则返回-1。
2. 实验相关原理
线性表的顺序存储结构称为顺序表,线性表的顺序存储结构在线性表Java接口的实现类中描述如下:
public class SqList implements IList{
private Object[] listElem; // 线性表存储空间
private int curLen; //线性表的当前长度
……
}
【核心算法提示】
⑴ 顺序表插入操作的基本步骤:要在当前的顺序表中的第i(0≤i≤n, n为线性表的当前长度)个数据元素之前插入一个数据元素x,首先要判断插入位置i是否合法, i的合法值范围:1≤i≤n+1,若是合法位置,就再判断顺序表是否满,如果不满,则将第i个数据元素及其之后的所有数据元素都后移一个位置,此时第i个位置已经腾空,再将待插入的数据元素x插入到该位置上,最后将线性表的当前长度值增加1,否则抛出异常。
⑵ 顺序表删除操作的基本步骤:要删除当前顺序表中的第i(0≤i≤n-1)个数据元素,首先依然要判断i的合法性,i 的合法范围是0≤i≤n-1,若是合法位置,则将第i个数据元素之后的所有数据元素都前移一个位置,最后将线性表的当前长度减1,否则抛出异常。
⑶ 顺序表查找操作的基本步骤:要在当前顺序表中查找一个给定值的数据元素,则能够采用顺序查找的方法,从顺序表中第0个数据元素开始依次将数据元素值与给定值进行比较,若相等则返回该数据元素在顺序表中的位置,如果所有数据元素都与x比较但都不相等,表明值为x的数据元素在顺序表中不存在,则返回-1值。
【核心算法描述】
⑴ 在当前顺序表上的插入操作算法
void insert(int i, Object x) throws Exception {
if (curLen == listElem.length) // 判断顺序表是否已满
throw new Exception("顺序表已满"); // 抛出异常
if (i < 0 || i > curLen) // i不合法
throw new Exception("插入位置不合法");// 抛出异常
for (int j = curLen; j > i; j--)
listElem[j] = listElem[j - 1];// 插入位置及其之后的所有数据元素后移一位
listElem[i] = x; // 插入x
curLen++; // 表长加1
}
⑵ 在当前顺序表上的删除操作算法
void remove(int i) throws Exception {
if (i < 0 || i > curLen - 1) // i不合法
throw new Exception("删除位置不合法");// 抛出异常
for (int j = i; j < curLen - 1; j++)
listElem[j] = listElem[j + 1];// 被删除元素及其之后的数据元素左移一个存储位置
curLen--; // 表长减1
}
⑶ 在当前顺序表是的查找操作算法
int indexOf(Object x) {
int j = 0; // j指示顺序表中待比较的数据元素,其初始值指示顺序表中第0个数据元素
while (j < curLen && !listElem[j].equals(x)) //依次比较
j++;
if (j < curLen) // 判断j的位置是否位于顺序表中
return j; // 返回值为x的数据元素在顺序表中的位置
else
return -1; // 值为x的数据元素在顺序表中不存在
}
3.源程序代码参考
package sy;
import java.util.Scanner;
class SqList {
private Object[] listElem; // 线性表存储空间
private int curLen; // 当前长度
public int getCurLen() {
return curLen;
}
public void setCurLen(int curLen) {
this.curLen = curLen;
}
public Object[] getListElem() {
return listElem;
}
public void setListElem(Object[] listElem) {
this.listElem = listElem;
}
// 顺序表的构造函数,构造一个存储空间容量为maxSize的空线性表
public SqList(int maxSize) {
curLen = 0; // 置顺序表的当前长度为0
listElem = new Object[maxSize];// 为顺序表分配maxSize个存储单元
}
// 在线性表的第i个数据元素之前插入一个值为x的数据元素。其中i取值范围为:0≤i≤curLen。 public void insert(int i, Object x) throws Exception {
if (curLen == listElem.length) // 判断顺序表是否已满
throw new Exception("顺序表已满");// 输出异常
if (i < 0 || i > curLen) // i小于0或者大于表长
throw new Exception("插入位置不合理");// 输出异常
for (int j = curLen; j > i; j--)
listElem[j] = listElem[j - 1];// 插入位置及之后的元素后移
listElem[i] = x; // 插入x
curLen++;// 表长度增1
}
// 将线性表中第i个数据元素删除。其中i取值范围为:0≤i≤curLen- 1,如果i值不在此范围则抛出异常
public void remove(int i) throws Exception {
if (i < 0 || i > curlew - 1) // i小于1或者大于表长减1
throw new Exception("删除位置不合理");// 输出异常
for (int j = i; j < curLen - 1; j++)
listElem[j] = listElem[j + 1];// 被删除元素之后的元素左移
curLen--; // 表长度减1
}
//查找顺序表中值的x元素,若查找成功则返回元素在表中的位序(0~curLen-1),否则返回-1
public int indexOf(Object x) {
int j = 0; // j指示顺序表中待比较的数据元素,其初始值指示顺序表中第0个数据元素
while (j < curLen && !listElem[j].equals(x)) //依次比较
j++;
if (j < curLen) // 判断j的位置是否位于顺序表中
return j; // 返回值为x的数据元素在顺序表中的位置
else
return -1; // 值为x的数据元素在顺序表中不存在
}
// 输出顺序表中的数据元素
public void display() {
for (int j = 0; j < curLen; j++)
System.out.print(listElem[j] + " ");
System.out.println();// 换行
}
}
//测试类
public class SY1_SqList{
public static void main(String[] args) throws Exception{
SqList L=new SqList(20); //构造一个存储容量为0的空顺序表
Scanner sc=new Scanner(System.in);
System.out.println("请输入顺序表的长度:");
int n=sc.nextInt();
System.out.println("请输入顺序表中的各个数据元素:");
for(int i=0;i<n;i++)
L.insert(i,sc.nextInt());
System.out.println("请输入待插入的位置i(0~curLen):");
int i=sc.nextInt();
System.out.println("请输入待插入的数据值x:");
int x=sc.nextInt();
L.insert(i, x);
System.out.println("插入后的顺序表为:");
L.display();
System.out.println("请输入待删除元素的位置(0~curLen-1):");
i=sc.nextInt();
L.remove(i);
System.out.println("删除后的顺序表为:");
L.display();
System.out.println("请输入待查找的数据元素:");
x=sc.nextInt();
int order=L.indexOf(x);
if (order==-1)
System.out.println("此顺序表中不包含值为"+x+"的数据元素!");
else
System.out.println("值为"+x+"元素在顺序表中的第"+order+"个位置上");
}
}
4.运行结果参考如图1-1所示:
图1-1: 验证性实验运行结果
备注: 以下设计性和应用性实验内容学生可根据自己的掌握程度或兴趣自行选择其一或其二完成。
七、设计性实验
编程实现删除有序顺序表中的所有重复元素,即使有序顺序表中相同的元素只保留一个。
1. 实验要求
⑴ 根据输入的n个非递减的有序数据建立一个有序顺序表,并输出有序顺序表中各元素值。
⑵ 删除有序顺序表中所有的重复元素,并显示删除后的有序顺序表中各元素值。
2. 核心算法提示
要在有序顺序表中删除重复的元素,首先就要抓住有序顺序表的特性:重复的元素总是在相邻的位置上,如:12,15,15,15,35,56,56,78。则删除重复元素后所得的有序表为:12,15,35,56,78。下面给出大致的操作步骤:从第0个元素开始,依次将它与后面相邻的元素进行比较,如果相等则将前面那个相等的元素从顺序表中删除;如果不相等,则继续往下比较,如此重复,直到最后一个元素为止。
3. 核心算法描述
// 删除有序顺序表L中的所有重复元素,即使得有序顺序表中相同的元素只保留一个
public static void remove_repeat(SqList L) {
int i=0;
while(i<L.getCurLen()-1)
if (L.getListElem()[i].equals(L.getListElem()[i+1])){
//如果第i个及第i+1个相邻元素值相等
for (int j=i+1;j<L.getCurLen();j++)
//将第i+1个元素及其之后的所有元素前移一个位地置
L.getListElem()[j-1]=L.getListElem()[j];
L.setCurLen(L.getCurLen()-1); //有序顺序表的表长减1
}
else
i++;
}
八、应用性设计实验
编程实现一个简单学生成绩管理系统的设计。
实验要求
此系统的功能包括:
① 查询:按特定的条件查找学生
② 修改:按学号对某个学生的某门课程成绩进行修改
③ 插入:增加新学生的信息
④ 删除:按学号删除已退学的学生的信息。
学生成绩表的数据如下:
学号
姓名
性别
大学英语
高等数学
001
Alan
F
93
88
002
Danie
M
75
69
003
Helen
M
56
77
004
Bill
F
87
90
006
Peter
M
79
86
006
Amy
F
68
75
要求采用顺序存储结构来实现对上述成绩表的相关操作。
实验B02: 链表的操作实验
一、实验名称和性质
所属课程
数据结构
实验名称
链表的操作
实验学时
2
实验性质
√验证 □综合 √设计
必做/选做
√必做 □选做
二、实验目的
1.掌握线性表的链式存储结构的表示和实现方法。
2.掌握链表基本操作的算法实现。
三、实验内容
1.建立单链表,并在单链表上实现插入、删除和查找操作(验证性内容)。
2.建立双向链表,并在双向链表上实现插入、删除和查找操作(设计性内容)。
3.计算已知一个单链表中数据域值为一个指定值x的结点个数(应用性设计内容)。
四、实验的软硬件环境要求
硬件环境要求:
PC机(单机)
使用的软件名称、版本号以及模块:
Netbeans 6.5以上或Eclipse、MyEclipse等编程环境下。
五、知识准备
前期要求熟练掌握了Java语言的编程规则、方法和单链表和双向链表的基本操作算法。
六、验证性实验
1.实验要求
编程实现如下功能:
(1)根据输入的一系列整数,以0标志结束,用头插法建立单链表,并输出单链表中各元素值,观察输入的内容与输出的内容是否一致。
(2)在单链表的第i个元素之前插入一个值为x的元素,并输出插入后的单链表中各元素值。
(3)删除单链表中第i个元素,并输出删除后的单链表中各元素值。
(4)在单链表中查找第i个元素,如果查找成功,则显示该元素的值,否则显示该元素不存在。
2. 实验相关原理:
线性表的链式储结构是用一组任意的存储单元依次存放线性表中的元素,这组存储单元能够是连续的,也能够是不连续的。为反映出各元素在线性表中的前后逻辑关系,对每个数据元素来说,除了存储其本身数据值之外,还需增加一个或多个指针域,每个指针域的值称为指针,又称作链,它用来指示它在线性表中的前驱或后继的存储地址。这两个部分的的一起组成一个数据元素的存储映像,称为结点,若干个结点链接成链表。如果一个结点中只含一个指针的链表,则称单链表。单链表中结点类描述如下:
class Node {
private Object data; // 存放结点值
private Node next; // 后继结点的引用
// 无参数时的构造函数
public Node() {
this(null, null);
}
//带一个参数时的构造函数
public Node(Object data) {
this(data, null);
}
//带两个参数时的构造函数
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
……
}
【核心算法提示】
⑴ 链表建立操作的基本步骤:链表是一个动态的结构,它不需要予分配空间,因此建立链表的过程是一个结点“逐个插入” 的过程。先建立一个只含头结点的空单链表,然后依次生成新结点,再不断地将其插入到链表的头部或尾部,分别称其为“头插法”和“尾插法”。
⑵ 链表查找操作的基本步骤:因链表是一种"顺序存取"的结构,则要在带头结点的链表中查找到第 i个 元素,必须从头结点开始沿着后继指针依次"点数",直到点到第 i 个结点为止,如果查找成功,则用e返回第i个元素值。头结点可看成是第0个结点。
⑶ 链表插入操作的基本步骤:先确定要插入的位置,如果插入位置合法,则再生成新的结点,最后经过修改链将新结点插入到指定的位置上。
⑷ 链表删除操作的基本步骤:先确定要删除的结点位置,如果位置合法,则再经过修改链使被删结点从链表中“卸下”,最后释放被删结点的空间。
【核心算法描述】
⑴ 用头插法创立带头结点的单链表操作算法
void creat() throws Exception {///*输入一系列整数,以0标志结束,将这些整数作为//data域并用头插法建立一个带头结点的单链表
Scanner sc = new Scanner(System.in);// 构造用于输入的对象
for (int x=sc.nextInt(); x!=0; x=sc.nextInt())// 输入n个元素的值
insert(0, x);// 生成新结点,插入到表头
}
⑵ 在当前带头结点的单链表上的查找操作算法
Object get(int i) throws Exception {
Node p = head.getNext();// 初始化,p指向首结点,j为计数器
int j = 0;
while (p != null && j < i) {// 从首结点开始向后查找,直到p指向第i个结点或p为空
p = p.getNext();// 指向后继结点
++j;// 计数器的值增1
}
if (j > i || p == null) { // i小于0或者大于表长减1
throw new Exception("第" + i + "个元素不存在");// 抛出异常
}
return p.getData(); // 返回结点p的数据域的值
}
⑶ 在当前带头结点的单链表上的插入操作算法
void insert(int i, Object x) throws Exception {
Node p = head;// 初始化p为头结点,j为计数器
int j = -1;
while (p != null && j < i - 1) {// 寻找i个结点的前驱
p = p.getNext();
++j;// 计数器的值增1
}
if (j > i - 1 || p == null) // i不合法
throw new Exception("插入位置不合理");// 输出异常
Node s = new Node(x); // 生成新结点
s.setNext(p.getNext());// 插入单链表中
p.setNext(s);
}
⑷ 在当前带头结点的单链表上的删除操作算法
void remove(int i) throws Exception {
Node p = head;// 初始化p为头结点,j为计数器
int j = -1;
while (p.getNext() != null && j < i - 1) {// 寻找i个结点的前驱
p = p.getNext();
++j;// 计数器的值增1
}
if (j > i - 1 || p.getNext() == null) { // i小于0或者大于表长减1
throw new Exception("删除位置不合理");// 输出异常
}
p.setNext(p.getNext().getNext());// 删除结点
}
3.源程序代码参考
package sy;
import java.util.Scanner;
//单链表的结点类
class Node {
private Object data; // 存放结点值
private Node next; // 后继结点的引用
public Node() { // 无参数时的构造函数
this(null, null);
}
public Node(Object data) { // 构造值为data的结点
this(data, null);
}
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
//实现链表的基本操作类
class LinkList {
Node head=new Node();//生成一个带头结点的空链表
// 根据输入的一系列整数,以0标志结束,用头插法建立单链表
public void creat() throws Exception {
Scanner sc = new Scanner(System.in); // 构造用于输入的对象
for (int x=sc.nextInt(); x!=0; x=sc.nextInt()) // 输入若干个数据元素的值(以0结束)
insert(0, x);// 生成新结点,插入到表头
}
//返回带头结点的单链表中第i个结点的数据域的值。其中:0≤i≤curLen-1
public Object get(int i) throws Exception {
Node p = head.getNext();// 初始化,p指向首结点,j为计数器
int j = 0;
while (p != null && j < i) {// 从首结点开始向后查找,直到p指向第i个结点或p为空
p = p.getNext();// 指向后继结点
++j;// 计数器的值增1
}
if (j > i || p == null) { // i小于0或者大于表长减1
throw new Exception("第" + i + "个元素不存在");// 抛出异常
}
return p.getData(); // 返回结点p的数据域的值
}
//在带头结点的单链表中的第i个数据元素之前插入一个值为x的元素
public void insert(int i, Object x) throws Exception {
Node p = head;// 初始化p为头结点,j为计数器
int j = -1;
while (p != null && j < i - 1) {// 寻找i个结点的前驱
p = p.getNext();
++j;// 计数器的值增1
}
if (j > i - 1 || p == null) // i不合法
throw new Exception("插入位置不合理");// 输出异常
Node s = new Node(x); // 生成新结点
s.setNext(p.getNext());// 插入单链表中
p.setNext(s);
}
// 删除带头结点的第i个数据元素。其中i取值范围为:0≤i≤length()- 1,如果i值不在此范围则抛出异常
public void remove(int i) throws Exception {
Node p = head;// 初始化p为头结点,j为计数器
int j = -1;
while (p.getNext() != null && j < i - 1) {// 寻找i个结点的前驱
p = p.getNext();
++j;// 计数器的值增1
}
if (j > i - 1 || p.getNext() == null) { // i小于0或者大于表长减1
throw new Exception("删除位置不合理");// 输出异常
}
p.setNext(p.getNext().getNext());// 删除结点
}
// 输出线性表中的数据元素
public void display() {
Node p = head.getNext();// 取出带头结点的单链表中的首结点元素
展开阅读全文