《数据结构Java版》线性表之单链表的建立及操作
数据结构与算法——单链表的实现及原理

数据结构与算法——单链表的实现及原理1. 单链表的原理 链表是线性表的链式存储⽅式,逻辑上相邻的数据在计算机内的存储位置不必须相邻,那么怎么表⽰逻辑上的相邻关系呢?可以给每个元素附加⼀个指针域,指向下⼀个元素的存储位置。
如图所⽰: 从图中可以看出,每个结点包含两个域:数据域和指针域,指针域存储下⼀个结点的地址,因此指针指向的类型也是结点类型链表的核⼼要素:Ø 每个节点由数据域和指针域组成 Ø 指针域指向下⼀个节点的内存地址。
1.1 结构体定义1 Typedef struct LinkNode2 {3 ElemType data; //节点中存放数据的类型4struct LinkNode* next; //节点中存放下⼀节点的指针5 }LinkList, LinkNode;2. 单链表初始化链表的节点均单向指向下⼀个节点,形成⼀条单向访问的数据链1//单链表的初始化2 typedef struct _LinkNode3 {4int data; //结点的数据域5struct _LinkNode* next; //结点的指针域6 }LinkNode, LinkList; //链表节点、链表78bool InitList(LinkList*& L) //构造⼀个空的单链表 L9 {10 L = new LinkNode; //⽣成新结点作为头结点,⽤头指针 L 指向头结点11if(!L)return false; //⽣成结点失败12 L->next=NULL; //头结点的指针域置空13return true;14 }3. 单链表增加元素 - 单链表前插法插⼊节点的要素就是要找到要插⼊位置的前⼀个节点,将这个节点的Next赋值给新节点,然后将新节点的地址赋值给前⼀个节点的Next便可,任意位置插⼊和前插法均是如此。
1//前插法2bool ListInsert_front(LinkList * &L, LinkNode * node) //参数1 链表指针参数2 要插⼊的节点元素3 {4if (!L || !node) return false; //如果列表或节点为空返回 false5 node->next = L->next; //将头节点指向节点1的地址赋值给要插⼊节点的指针域,使要插⼊的节点先与后部相连6 L->next = node; //将插⼊节点的地址赋值给头结点的指针域,使要插⼊节点与头结点相连78return true;9 }4. 单链表增加元素 - 单链表尾插法1//尾插法2bool ListInsert_back(LinkList*& L, LinkNode* node)3 {4 LinkNode* last = NULL; //创建空指针,5if (!L || !node) return false; //如果列表或节点为空返回 false67 last = L;8while (last->next) last = last->next; //使⽤ last 找到最后⼀个节点910 node->next = NULL; //要插⼊节点由于在尾部,指针域置为 NULL11 last->next = node; //将要插⼊节点的地址赋值给之前的尾部节点的指针域,将要插⼊节点放置到尾部12return true;13 }5. 单链表增加元素 - 单链表任意位置插⼊插⼊节点的要素就是要找到要插⼊位置的前⼀个节点,将这个节点的Next赋值给新节点,然后将新节点的地址赋值给前⼀个节点的Next便可,任意位置插⼊和前插法均是如此。
数据结构-单链表基本操作实现(含全部代码)

数据结构-单链表基本操作实现(含全部代码)今天是单链表的实现,主要实现函数如下:InitList(LinkList &L) 参数:单链表L 功能:初始化时间复杂度 O(1)ListLength(LinkList L) 参数:单链表L 功能:获得单链表长度时间复杂度O(n)ListInsert(LinkList &L,int i,ElemType e) 参数:单链表L,位置i,元素e 功能:位置i后插时间复杂度O(n)[加⼊了查找]若已知指针p指向的后插 O(1)ListDelete(LinkList &L,int i) 参数:单链表L,位置i 功能:删除位置i元素时间复杂度O(n)[加⼊了查找]若已知p指针指向的删除最好是O(1),因为可以与后继结点交换数据域,然后删除后继结点。
最坏是O(n),即从头查找p之前的结点,然后删除p所指结点LocateElem(LinkList L,ElemType e) 参数:单链表L,元素e 功能:查找第⼀个等于e的元素,返回指针时间复杂度O(n)代码:/*Project: single linkeed list (数据结构单链表)Date: 2018/09/14Author: Frank YuInitList(LinkList &L) 参数:单链表L 功能:初始化时间复杂度 O(1)ListLength(LinkList L) 参数:单链表L 功能:获得单链表长度时间复杂度O(n)ListInsert(LinkList &L,int i,ElemType e) 参数:单链表L,位置i,元素e 功能:位置i后插时间复杂度O(n)[加⼊了查找]若已知指针p指向的后插 O(1)ListDelete(LinkList &L,int i) 参数:单链表L,位置i 功能:删除位置i元素时间复杂度O(n)[加⼊了查找]若已知p指针指向的删除最好是O(1),因为可以与后继结点交换数据域,然后删除后继结点。
单链表数据结构

插入
if (p != NULL && j == i-1) { // 找到第i个结点
s = (LinkList) malloc ( sizeof (LNode)); // 生成新结点
s->data = e;
// 数据域赋值
s->next = p->next; //新结点指针指向后一结点
p->next = s; return OK;
6、销毁
4.6 销毁操作
while(L) { p = L->next; free(L); L=p;
// p指向第一结点(头节点为“哑结点”) // 释放首结点 // L指向p
}
// 销毁完成后,L为空(NULL)
算法的时间复杂度为:O(ListLength(L))
判空 求表长
4.7 其它操作
if(L->next==NULL) return TRUE; // 空
5、清空
4.5 清空操作
while (L->next) { p = L->next; L->next = p->next; free(p);
// p指向当前结点 // 头结点指向当前结点的后结点 // 释放当前结点内存
}
// 清空完成后,仍保留头结点L
算法的时间复杂度为:O(ListLength(L))
点。
5.1.2 逆序建立单链表
①建立一个带头结点的空单链表;
②输入数据元素ai,建立新结点p, 并把p插入在头结点之后成为第一个 结点。
③重复执行②步,直到完成单链表的 建立。
a1
a2 a1
创建出来的链表 点顺序与插入操作
顺序相反。
JAVA数据结构——单链表的操作

单链表的操作方法一:package ch02;(1)建立结点类Node.javapublic class Node {public Object data;//存放结点数据值public 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;}}(2)建立链表及操作LinkList.javapackage ch02;import java.util.Scanner;public class LinkList implements IList{public Node head;//单链表的头指针//构造函数初始化头结点public LinkList(){head=new Node();}//构造函数构造长度为n的单链表public LinkList(int n,boolean Order) throws Exception{ this();if(Order)create1(n); //头插法顺序建立单链表elsecreate2(n); //尾插法逆序建立单链表}//头插法顺序建立单链表public void create1(int n) throws Exception{Scanner sc=new Scanner(System.in);System.out.println("请输入结点的数据(头插法):”);for(int i=0;i<n;i++){insert(0,sc.next());}}//尾插法逆序建立单链表public void create2(int n) throws Exception{Scanner sc=new Scanner(System.in);System. out.println("请输入结点的数据(尾插法):");for(int i=0;i<n;i++){insert(length(),sc.next());}}//将链表置空public void clear(){head.data=null;head.next=null;}//判断链表是否为空public boolean isEmpty(){return head.next==null;}//返回链表长度public int length(){Node p=head.next;int length=0;while(p!=null){p=p.next;length++;//返回P不空长度length加1}return length;}//读取并返回第i个位置的数据元素public Object get(int i) throws Exception {Node p=head.next;int j;//从首结点开始向后查找,直到9指向第i个结点或者p为nullfor(j=0;j<i&&p!=null;j++){ p=p.next;}if(j>i||p==null)//i不合法时抛出异常throw new Exception("第"+i+”个数据元素不存在”);return p.data;}//插入乂作为第i个元素public void insert(int i, Object x) throws Exception{ Node p=head;int j=-1;//寻找第i个结点的前驱i-1while(p!=null&&j<i-1){p=p.next;j++;}if(j>i-l||p==null)//i不合法时抛出异常throw new Exception("插入位置不合法”);Node s=new Node(x);s.next=p.next;p.next=s;}//删除第i个元素public void remove(int i) throws Exception{ Node p=head;int j=-1;while(p!=null&&j<i-1){//寻找第i-1 个节点p=p.next;j++;}if(j>i-1||p.next==null)throw new Exception("删除位置不合法”);p.next=p.next.next;}//返回元素x首次出现的位序号public int indexOf(Object x) {Node p=head.next;int j=0;while(p!=null&&!p.data.equals(x)){p=p.next;j++;if(p!=null)return j;elsereturn -1;}public void display(){Node p=head.next;while(p!=null){if(p.next==null)System.out.print(p.data);elseSystem.out.print(p.data+"f );p=p.next;}}}(3)建立测试类Test.javappublic class test {public static void main(String[] args) throws Exception { // TODO Auto-generated method stubScanner sc=new Scanner(System.in);boolean or;int xz,xx;System.out.println("请选择插入的方法:0、头插法,1、尾插法");xz=sc.nextInt();if(xz!=0)or=true;elseor=false;System. out.println("请插入的结点的个数:”);xx=sc.nextInt();LinkList L=new LinkList(xx,or);System.out.println("建立的链表为:");L.display();System.out.println();System.out.println("链表的长度:"+L.length());System. out.println(”请输入查找的结点的数据:”);Object x=sc.next();int position=L.indexOf(x);System.out.println("结点的数据为:"+x+"的位置为:"+position); System. out.println("请输入删除的结点的位置:”);int sr=sc.nextInt();L.remove(sr);L.display();System.out.println();System.out.println("链表的长度:"+L.length()); }品P rob I em & J a vs d oc / Declaration Q Error Log 里Con sole-M、、■=:termin8ted> test [3] [Java Application] C U &ert\Ad im i n i st rat o r\Ap p Data\L o cs I请选择插入.的方法:0、头插法,lv星插法请插入的特点的个数:请愉入结点的颓据(尾插法):A B C E D F建立的旌表为;A+B T C+E T D+F链表的长度:6请输入查找的结点的数据:结点的数据为:E的位置为:3请输入删除的结点的位置,R+B T E+DW道表的长度:S方法二(引入get和set方法)Package sy;import java.util.Scanner;//单链表的结点类public 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) {//构造值为data 和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;}}//实现链表的基本操作类public 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个结点的数据域的值。
数据结构——链表的创建、插入、删除

/ 令 S指 向结点的存储 内容为 x / 半 * ① s >e t p > e t 一nx=一nx : 令新创设的结点 的指针指于 P 相邻 后方 的结点 /
② P >e ts 一nx= : p之 后 ,指 于 相 邻 后 方 的结 点 /
这样一来。便实 现了于单链表中数据的后插放置 。 ①②行顺序我们 不能去忽略, 因为常常这里就是很容产生 错误的地方 , 以说 , 可 这两句顺序错误 , 插入操作便不 能实现 , 因为 a 5的地址被存储在 a 4结点的指针域中 , 不是 明确 的, 如 果我们选择②先运行 ,则 a 5的地 址将 由于 x结点的地址数据 的抹去 , 不能够指 向 a 5以及其最 后的结点了。因为这个原因 , 我们不仅仅需要知道涉及结点 的指针为 明确或者 隐含 , 并且要 谨记将隐含结点先于别的结点执行 。
一
麝 一
相关代码
:
图5
l 4~ o
计算机光盘软件 与应用
2 1 第 8期 0 2年
C m u e DS fw r n p lc t o s o p t rC o t a ea dA p i a i n 工 程 技 术
① s (t u t d o e卓 a lc (i e f s r c = sr c n d )m l o s z o (t u t
一
、
图 3
2 后 插 法 .
后插法没有前插法这么复杂 ,我们想象 ,于书 p指 向的结 点的最后放进新创设 的结 点 x ,如图 4 。 相关语 句: sr c n d p 水声 明指针 P宰 t u t L o e书 :/ / 令术 p的地址为 a : 4 s (t u t L o e木 m lo (i e f sr c n d ) :木 = s r c n d ) a lc s z o (t u t L o e ) / 令 S指于新创设 的结点 木 /
数据结构课程设计 单链表的建立

一、实验目的:1、通过单链表来理解链表的逻辑结构和存储结构,熟练掌握线性表的存储方式和一些基本的操作,如:线性表的建立、求表长操作、取元素操作、按值查找操作、插入及删除操作等。
2、将理论知识与实践相结合,提高自己的实际动手能力。
3、通过实践来及时发现自己的缺点与不足,以便为接下来更加有效的学习做铺垫。
二、实验内容:1、采用头插法或尾插法(此次课程设计我们以头插法为例)建立一个单链表。
2、对建立好的单链表进行一些基本的操作,如:a.单链表的类型定义。
b.求表长操作。
c.取元素操作。
d.按值查找操作。
e.显示元素操作。
f.插入操作。
g.删除操作。
h.显示元素操作。
三、基本要求:1.软件要求:Windows 2003、Microsoft Visual C++ 6.0、Microsoft Ward 2003等。
2.硬件要求:电脑、优盘及其它辅助设备。
四、算法设计思想:用一组任意的存储单元来存放线性表中的数据元素,这组存储单元既可以是连续的,也可以是不连续的,甚至可以是零散分布在内存中的任意位置上。
为了表示线性表中的数据元素之间的前后关系,每个数据元素在存储器中的结点除了存储其基本信息外(结点的数据域),还需附加存储其前驱和后继的位置(结点的指针域)。
这样线性表L=(a1,a2,…,an)在存储器上的n个结点就通过各自结点的指针域链接成一个“链子”,即链表。
如果只附加存储其后继的位置(后继指针)就为单链表。
五、算法流程图六、算法源代码#include <iostream.h>#include<stdlib.h>#include <stdio.h>typedef int Status;#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define OVERFLOW -2#define NULL 0/*单链表的类型定义*/typedef struct LNode{int data;struct LNode *next;}LNode, *LinkList;/*头插法建立单链表*/LNode *createList(int n){LNode *p;int i;LinkList L;L=(LinkList)malloc(sizeof(LNode));L->next=NULL;for(i=1;i<=n;i++){p=(LNode*)malloc(sizeof(LNode));cout <<"输入值";cin>>p->data;p->next=L->next;L->next=p;}return L;}/*求表长操作*/int listLength(LinkList L){LNode *p=L;int j=0;while(p->next){p=p->next;j++;}return j;}/*取元素操作*/void getElem(LNode *L,int i){int e;LNode *p=L;int j=0;while(j<i && p->next){p=p->next;j++;}if(j==i){e=p->data;printf("取得元素为:%d\n",e);}else printf("无此元素\n");}/*按值查找*/int locateElem(LinkList L,int e){LNode *p=L->next;while(p->data!=e&&p!=NULL)p=p->next;if(p->data==e)return OK;else return ERROR;}/*单链表的插入*/int listInsert(LinkList L,int i,int e){LNode *p=L,*q;int j=0;while(j<i-1&&p->next){p=p->next;j++;}if(j==i-1){q=(LNode*)malloc(sizeof(LNode));if(!q) return OVERFLOW;q->data=e;q->next=p->next;p->next=q;return OK;}else return ERROR;}/*单链表的删除*/int listDelete(LNode* L,int i){LNode *p=L,*q;int j=0;while(j<i-1&&p->next){p=p->next;j++;}if(j==i-1&&p->next){q=p->next;p->next=q->next;free(q);return OK;}else return ERROR;}/*显示元素操作*/void display(LNode *L){LNode *p=L->next;while(p){ printf("%d",p->data);p=p->next; }}/*主函数*/void main (){cout<<"* * * * * * * * * * * * *"<<endl;cout<<" * 1:单链表的建立* "<<endl;cout<<"* * * * 2:求表长* * * * * *"<<endl;cout<<" * 3:取元素* * * "<<endl;cout<<"* * * * 4:按值查找* * * * *"<<endl;cout<<" * 5:插入* * * "<<endl;cout<<"* * * * 6:删除* * * * * *"<<endl;cout<<" * 7:显示* * * "<<endl;cout<<"* * * * 0:退出* * * * * *"<<endl;cout<<"* * * * * * * * * * * * *"<<endl;LNode *L;int n,flag=1,i;int h,m;while(flag){cout <<"请选择:";cin>>i;switch(i){ case 0: flag=0;break;case 1: cout<<"输入单链表长度:",cin>>n, L=createList(n);break;case 2: cout<<"求得表长为: "<<listLength(L)<<endl;break;case 3: cout <<"取第几个元素:",cin>>h, getElem(L,h);break;case 4: cout<<"输入要查找的值: ",cin>>m,cout<<locateElem(L,m);break;case 5: cout<<"插入位置和插入值分别为:",cin>>i>>m,cout<<listInsert(L,i,m)<<endl;break;case 6: cout<<"输入要删除的元素的位置:",cin>>i,cou t<<listDelete(L,i)<<endl;break;case 7: display(L);break;default: cout<<"输入错误,请重新输入!";}}}七、算法运行结果1、显示整个链表的功能选择:2、设置单链表的长度:3、求出并返回链表的长度:4、在链表中取出某个位置的元素并返回其值:5、给定一个值,查看链表中是否存在这个元素,若存在就返回TURE(即:返回数字1),反之,返回ERROR(即:返回数字0):6、显示链表中的元素:7、在链表的某个位置插入元素:8、删除链表中的某个元素:9、退出对链表的操作:10、链表所有功能效果图:八、收获及体会通过这次课程设计,我们小组成员对单链表的基本操作都更加熟悉了、对线性存储的认识也更加深刻了。
第2章线性表(2)-数据结构教程(Java语言描述)-李春葆-清华大学出版社

public void Setsize(int nlen)
//设置线性表的长度
{ int len=size();
if (nlen<0 || nlen>len)
throw new IllegalArgumentException("设置长度:n不在有效范围内");
s
s.next=head.next;
ai
head.next=s;
head
…
∧
9/85
public void CreateListF(E[] a) { LinkNode<E> s;
for (int i=0;i<a.length;i++) { s=new LinkNode<E>(a[i]);
s.next=head.next; head.next=s; } }
12/85
3. 线性表基本运算在单链表中的实现
查找序号为i(0≤i≤n-1,n为单链表中数据结点个数)的结点
private LinkNode<E> geti(int i) { LinkNode<E> p=head;
int j=-1; while (j<i) { j++;
p=p.next; } return p; }
//尾插法:由数组a整体建立单链表
//t始终指向尾结点,开始时指向头结点 //循环建立数据结点s //新建存放a[i]元素的结点s //将s结点插入t结点之后
//将尾结点的next置为null
a=('a','b','c','d'),调用CreateListR
数据结构课件单链表

删除链表中的节点需要遍历至指定位置,时间复杂度为 O(n)。
查找节点
在链表中查找一个节点需要遍历整个链表,时间复杂度为 O(n)。
空间复杂度
空间占用
单链表的空间占用主要取决于链表中的 节点数,因此空间复杂度为O(n)。
VS
内存分配
每个节点需要分配内存空间存储数据和指 针,因此内存分配的空间复杂度也为O(n) 。
需要根据数据元素顺 序进行遍历的场景, 如排序算法等。
需要频繁插入、删除 操作的场景,如动态 规划、图算法等。
02
单链表的实现
创建单链表
定义节点结构体
首先需要定义一个节点结构体,包含 数据域和指针域两个部分,数据域用 于存储数据,指针域用于指向下一个 节点。
初始化头节点
创建一个头节点,并将其指针域指向 NULL,表示单链表的起始位置。
05
单链表常见问题与解决方 案
循环链表
总结词
循环链表是一种特殊类型的单链表,其中尾节点的指针指向头节点,形成一个闭环。
详细描述
在循环链表中,由于尾节点的指针指向头节点,因此遍历链表时需要特别注意,以避免无限循环。常见的解决方 法是在遍历时记录已经访问过的节点,避免重复访问。
链表中的重复元素
总结词
链表中可能存在重复元素的问题,这会影响数据处理的正确性。
详细描述
为了解决这个问题,可以在插入节点时检查新元素是否已存在于链表中。如果存在,则不进行插入操 作。另外,也可以使用哈希表等数据结构来快速查找重复元素。
链表的排序
总结词
对链表进行排序是常见的需求,但链表的排 序算法通常比数组的排序算法复杂。
合并单链表
总结词
将两个已排序的单链表合并为一个新的已排序的单链表。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《数据结构Java》线性表之单链表的建立及操作package sjjg3;//单链表结点类,T指定结点的元素类型public class Node<T> {public T data;//数据域,存储数据元素public Node<T> next;//地址域,引用后继结点public Node(T data,Node<T> next) {//构造结点,data指定数据元素,next指定后继结点this.data=data;//T对象引用赋值this.next=next;//Node<T>对象引用赋值}public Node() {this(null, null);}public String toString() {//返回结点数据域的描述字符串return this.data.toString();}}package sjjg3;//单链表类,实现ADT List<T>声明方法,T表示数据元素的数据类型public class SinglyList<T> extends Object{public Node<T> head;//头指针,指向单链表的头结点//(1)构造方法public SinglyList() {//构造空单链表this.head=new Node<T>();//创建头结点,data和next值均为null }public SinglyList(T[] values) {//构造单链表,由values数组提供元素this();//创建空单链表,只有头结点Node<T> rear=this.head;//rear指向单链表最后一个结点for(int i=0;i<values.length;i++) {//若values。
length==0,构造空链表rear.next=new Node<T>(values[i],null);//尾插入,创建结点链入rear结点之后rear=rear.next;//rear指向新的链尾结点}}public boolean isEmpty() {//判断单链表是否空,O(1)return this.head.next==null;}//(2)存取public T get(int i) {//返回第i个元素,0<=i<表长度。
若i越界,则返回null。
O(n)Node<T> p=this.head.next;for(int j=0;p!=null && j<i;j++)//遍历单链表,寻找第i个结点(p指向)p=p.next;return(i>=0 && p!=null)?p.data:null;//若p指向第i个结点,返回其元素值}public void set(int i,T x) {//设置第i个元素为x,0<=i<表长度,x!=null。
}public int size() {//返回单链表长度,O(n)。
Node<T> p=head;int count=0;while(p!=null) {count++;p=p.next;}return count;}//返回单链表所有元素的描述字符串,形式“(,)”。
覆盖Object类的toString()方法,O(n)public String toString() {String str=this.getClass().getName()+"(";//返回类名for(Node<T> p=this.head.next;p!=null;p=p.next) {//p遍历单链表str+=p.data.toString();if(p.next!=null)str+=",";//不是最后一个结点时,加分隔符}return str+")";//空表返回()}//(3)插入//插入x作为第i个元素,x!=null,返回插入结点//对序号i采取容错措施,若i<0,则插入x在最前;若i>n,则插入x在最后。
O(n) public Node<T> insert(int i,T x){if(x==null)throw new NullPointerException("x==null");//抛出空对象异常Node<T> front=this.head;//front指向头结点for(int j=0;front.next!=null && j<i;j++)//寻找第i-1个或最后一个结点(front指向)front=front.next;front.next=new Node<T>(x,front.next);//在front之后插入值为x的结点return front.next;//返回插入结点}public Node<T> insert(T x){//在单链表最后添加x对象,O(n)//调用insert(i,x),用整数最大值指定插入在最后,遍历一次,i必须容错return insert(Integer.MAX_VALUE,x);}//(4)删除public T remove(int i) {//删除第i个元素,0<=i<n,返回被删除元素;若i越界;则返回null。
O(n)Node<T> front=this.head;//front指向头结点for(int j=0;front.next!=null && j<i;j++)//遍历寻找第i-1结点(front指向)front=front.next;if(i>=0 && front.next!=null) {//若front的后继结点存在,则删除之T old=front.next.data;//获得待删除结点引用的对象front.next=front.next.next;//删除front的后继,包括头删除,中间/尾删除//由Java虚拟机稍后释放结点占用的存储单元return old;}return null;//若i<0或i>表长}public void clear() {//删除单链表所有元素this.head.next=null;//Java自动收回所有结点占用的存储空间}//(5)查找public Node<T> search(T key){//查找返回首个与key相等元素结点,查找不成功返回nullfor(Node<T> p=head.next;p!=null;p=p.next)if(key.equals(p.data))return p;return null;}public boolean contains(T key){//判断是否包含关键字为key元素Node<T> p = null;return this.search(key)!=p;}}package sjjg3;public class SinglyTest {public static void main(String[] args) {Node<Integer> i;String values[] = {"A","B","C","D","E","F"};SinglyList<String> list = new SinglyList<String>(values);Integer values1[] = { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9 };SinglyList<Integer> list1 = new SinglyList<Integer>(values1);Integer values2[] = { 100, 11, 22, 33, 44, 55, 66, 77, 88, 99 };SinglyList<Integer> list2 = new SinglyList<Integer>(values2);System.out.println("更改前的顺序表:");System.out.println(list.toString());System.out.println(list1.toString());System.out.println(list2.toString());list.insert(3,"K");System.out.print("插入后的顺序表:");System.out.println(list.toString());list1.remove(4);System.out.print("删除后的顺序表:");System.out.println(list1.toString());i=list2.search(100);System.out.print("查找结果:");if(i!=null)System.out.print(true);elseSystem.out.print(false);}}。