1. java怎么用链表实现
在数据结构中经常看见的一个基本概念-链表。
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
在Java中,对于链表的实现都是基于引用数据类型操作的。实现大致如下:
定义节点类Node,节点的概念很重要,一个链表是由各各节点连接在一起组成的。在节点类Node中定义节点内容及指向下一节点的引用,再增加一个添加节点的方法即可完成链表实现。
链表有很多种不同的类型:单向链表,双向链表以及循环链表。在执行效率上,相比数组而言,链表插入快查找慢,开发中得根据实际业务使用。
2. Java语言没有指针,怎样实现链表
Java语言中的对象引用实际上是一个指针(这里的指针均为概念上的意义,而非语言提供的数据类型),所以我们可以编写这样的类来实现链表中的结点。
程序代码:
classNode
{
Objectdata;
Nodenext;//指向下一个结点
}
将数据域定义成Object类是因为Object类是广义超类,任何类对象都可以给其赋值,增加了代码的通用性。为了使链表可以被访问还需要定义一个表头,表头必须包含指向第一个结点的指针和指向当前结点的指针。为了便于在链表尾部增加结点,还可以增加一指向链表尾部的指针,另外还可以用一个域来表示链表的大小,当调用者想得到链表的大小时,不必遍历整个链表。
链表的数据结构我们可以用类List来实现链表结构,用变量Head、Tail、Length、Pointer来实现表头。存储当前结点的指针时有一定的技巧,Pointer并非存储指向当前结点的指针,而是存储指向它的前趋结点的指针,当其值为null时表示当前结点是第一个结点,因为当删除当前结点后仍需保证剩下的结点构成链表,如果Pointer指向当前结点,则会给操作带来很大困难。如何得到当前结点呢?我们定义了一个方法cursor(),返回值是指向当前结点的指针。类List还定义了一些方法来实现对链表的基本操作,通过运用这些基本操作我们可以对链表进行各种操作。例如reset()方法使第一个结点成为当前结点。insert(Object d)方法在当前结点前插入一个结点,并使其成为当前结点。remove()方法删除当前结点同时返回其内容,并使其后继结点成为当前结点,如果删除的是最后一个结点,则第一个结点变为当前结点。
链表类List的源代码如下:
packagecn.javatx;importjava.io.IOException;/**
*@authorljfan
*
*/
publicclassList{
privateNodeHead=null;
privateNodeTail=null;
privateNodePointer=null;
privateintLength=0;publicvoiddeleteAll(){
Head=null;
Tail=null;
Pointer=null;
Length=0;
}publicvoidreset(){
Pointer=null;
}publicbooleanisEmpty(){
return(Length==0);
}publicbooleanisEnd(){
if(Length==0)
thrownewjava.lang.NullPointerException();
elseif(Length==1)
returntrue;
else
return(cursor()==Tail);
}publicObjectnextNode(){
if(Length==1)
thrownewjava.util.NoSuchElementException();
elseif(Length==0)
thrownewjava.lang.NullPointerException();
else{
Nodetemp=cursor();
Pointer=temp;
if(temp!=Tail)
return(temp.next.data);
else
thrownewjava.util.NoSuchElementException();
}
}publicObjectcurrentNode(){
Nodetemp=cursor();
returntemp.data;
}publicvoidinsert(Objectd){
Nodee=newNode(d);
if(Length==0){
Tail=e;
Head=e;
}else{
Nodetemp=cursor();
e.next=temp;
if(Pointer==null)
Head=e;
else
Pointer.next=e;
}
Length++;
}publicintsize(){
return(Length);
}publicObjectremove(){
Objecttemp;
if(Length==0)
thrownewjava.util.NoSuchElementException();
elseif(Length==1){
temp=Head.data;
deleteAll();
}else{
Nodecur=cursor();
temp=cur.data;
if(cur==Head)
Head=cur.next;
elseif(cur==Tail){
Pointer.next=null;
Tail=Pointer;
reset();
}else
Pointer.next=cur.next;
Length--;
}
returntemp;
}privateNodecursor(){
if(Head==null)
thrownewjava.lang.NullPointerException();
elseif(Pointer==null)
returnHead;
else
returnPointer.next;
}publicstaticvoidmain(String[]args){
Lista=newList();
for(inti=1;i<=10;i++)
a.insert(newInteger(i));
System.out.println(a.currentNode());
while(!a.isEnd())
System.out.println(a.nextNode());
a.reset();
while(!a.isEnd()){
a.remove();
}
a.remove();
a.reset();
if(a.isEmpty())
System.out.println("ThereisnoNodeinListn");
System.out.println("Youcanpressreturntoquitn");
try{
System.in.read();
}catch(IOExceptione){
}
}
}classNode{
Objectdata;
Nodenext;Node(Objectd){
data=d;
next=null;
}
}
当然,双向链表基本操作的实现略有不同。链表和双向链表的实现方法,也可以用在堆栈和队列的现实中。
3. JAVA中数组与链表有什么区别
数组与链表在计算机科学中是两种常见的数据结构,它们各自具有不同的特点和用途。
数组是一种有序的元素序列,将具有相同类型的多个元素集合在一起进行命名,这些元素在物理存储上是连续的。这意味着数组中的所有元素都具有相同的数据类型,并且可以通过索引快速访问,但数组的大小在创建时就需要确定,不能动态调整。
相比之下,链表则是一种非连续的存储结构,它由一系列结点组成,每个结点包含数据部分和指向下一个结点的指针。链表中的结点可以在运行时动态生成,因此可以灵活地添加或删除结点,而不像数组那样需要预先知道数据的大小。
链表的优势在于它能有效利用内存空间,特别是在数据大小不确定或需要频繁添加或删除数据的情况下。链表的这种特性使得它在动态数据管理方面具有独特的优势。
数组和链表之间的主要区别还体现在它们的实现方式上。数组中的元素是连续存储的,因此可以利用索引来快速访问元素。而链表则通过指针链接各结点,这种方式使得链表更适合处理动态数据。
综上所述,数组和链表在不同的应用场景中都有其独特的优势,选择哪种数据结构取决于具体的需求和场景。
4. Java链表ListNode的理解与操作技巧
深入理解Java链表——ListNode的奥秘与高效操作
链表,这位数据结构的低调明星,与数组并肩存在,但实现原理却大相径庭。Java中,ArrayList依托数组,而LinkedList则依托链表。链表的一大优势在于数据的动态添加和删除,但循环遍历效率却不如数组。它是一个由节点(Node)串联而成的线性结构,内存中的数据分布不连续,每个节点持有自己的数据和对下一个节点的引用,形成了链式连接。链表的主角——单向链表,仅有一个头节点(Head),所有的操作都是通过它进行的,无论是插入还是删除。
想象一下,就像一个看不见的线索,每个节点都持有指向下一个节点的线索,上图中,头节点就像这个链条的起点。有趣的是,添加节点的过程却从链尾开始,新节点被插入到当前尾节点之后,形成一个不断扩展的序列。每个节点都仅知道自己下一个节点的位置,这就是链表的魅力所在。
节点的构造精巧,由对象值(val或data)和指向下一个节点的引用(Node.next)构成,就像一个信息传递的接力赛,每个节点都承载着数据和传递的使命。以下是ListNode的精简版定义:
在MyList类中,链表的操作方法更是精细入微。添加节点(add)、删除指定节点(delete)、获取节点长度(size)、查找节点位置(find),以及通过下标获取节点(get),每个方法都展示了链表操作的灵活性和高效性。比如,delete方法通过遍历链表找到目标节点,然后更新节点连接,避免了数组需要移动大量元素的麻烦。
最后,别忘了链表还有个华丽转身的时刻——链表反转(reverse)。通过交换每个节点的前后节点,链表从头到尾的顺序来了个180度的大转弯,展示了链表操作的多样性和可能性。
链表,这个看似平凡的数据结构,实则蕴含着丰富的操作技巧和灵活性。通过熟练掌握ListNode,你将能在Java编程世界中游刃有余地处理各种数据操作,让代码更加高效且优雅。
5. 求用Java写的:输入N个整数,按照输入的顺序建立单链表存储,并遍历所建立的单链表,输出这些数据。
importjava.util.Scanner;
publicclassNode{
publicintvalue;
publicNodenext;
publicNode(intvalue){
this.value=value;
this.next=null;
}
publicvoidadd(Nodenode){
this.next=node;
}
publicbooleanhasNext(){
returnthis.next==null?false:true;
}
publicstaticvoidmain(String[]args){
Nodefirst=null;//记录第一个节点,在后面遍历的时候使用
Nodenode=null;//保存当前输入的节点使用
Scannerin=newScanner(System.in);//用于控制台输入,Ctrk+Z结束输入
while(in.hasNext()){
intv=in.nextInt();
Noden=newNode(v);
if(first==null){
first=n;
node=n;
}else{
node.add(n);
node=n;
}
}
if(first==null){
System.out.println("没有数字输入");
}else{
node=first;
System.out.println(node.value+"");
while(node.hasNext()){
node=node.next;
System.out.println(node.value+"");
}
}
}
}
模拟最简单的单链表,临时手打,仅供做题等参考,望采纳。