
class Node
{
Object data
Node next//指向下一个结点
}
将数据域定义成Object类是因为Object类是广义超类,任何类对象都可以给其赋值,增加了代码的通用性。为了使链表可以被访问还需要定义一个表头,表头必须包含指向第一个结点的指针和指向当前结点的指针。为了便于在链表尾部增加结点,还可以增加一指向链表尾部的指针,另外还可以用一个域来表示链表的大小,当调用者想得到链表的大小时,不必遍历整个链表。下图是这种链表的示意图:
链表的数据结构
我们可以用类List来实现链表结构,用变量Head、Tail、Length、Pointer来实现表头。存储当前结点的指针时有一定的技巧,Pointer并非存储指向当前结点的指针,而是存储指向它的前趋结点的指针,当其值为null时表示当前结点是第一个结点。那么为什么要这样做呢?这是因为当删除当前结点后仍需保证剩下的结点构成链表,如果Pointer指向当前结点,则会给 *** 作带来很大困难。那么如何得到当前结点呢,我们定义了一个方法cursor(),返回值是指向当前结点的指针。类List还定义了一些方法来实现对链表的基本 *** 作,通过运用这些基本 *** 作我们可以对链表进行各种 *** 作。例如reset()方法使第一个结点成为当前结点。insert(Object d)方法在当前结点前插入一个结点,并使其成为当前结点。remove()方法删除当前结点同时返回其内容,并使其后继结点成为当前结点,如果删除的是最后一个结点,则第一个结点变为当前结点。
链表类List的源代码如下:
import java.io.*
public class List
{
/*用变量来实现表头*/
private Node Head=null
private Node Tail=null
private Node Pointer=null
private int Length=0
public void deleteAll()
/*清空整个链表*/
{
Head=null
Tail=null
Pointer=null
Length=0
}
public void reset()
/*链表复位,使第一个结点成为当前结点*/
{
Pointer=null
}
public boolean isEmpty()
/*判断链表是否为空*/
{
return(Length==0)
}
public boolean isEnd()
/*判断当前结点是否为最后一个结点*/
{
if(Length==0)
throw new java.lang.NullPointerException()
else if(Length==1)
return true
else
return(cursor()==Tail)
}
public Object nextNode()
/*返回当前结点的下一个结点的值,并使其成为当前结点*/
{
if(Length==1)
throw new java.util.NoSuchElementException()
else if(Length==0)
throw new java.lang.NullPointerException()
else
{
Node temp=cursor()
Pointer=temp
if(temp!=Tail)
return(temp.next.data)
else
throw new java.util.NoSuchElementException()
}
}
public Object currentNode()
/*返回当前结点的值*/
{
Node temp=cursor()
return temp.data
}
public void insert(Object d)
/*在当前结点前插入一个结点,并使其成为当前结点*/
{
Node e=new Node(d)
if(Length==0)
{
Tail=e
Head=e
}
else
{
Node temp=cursor()
e.next=temp
if(Pointer==null)
Head=e
else
Pointer.next=e
}
Length++
}
public int size()
/*返回链表的大小*/
{
return (Length)
}
public Object remove()
/*将当前结点移出链表,下一个结点成为当前结点,如果移出的结点是最后一个结点,则第一个结点成为当前结点*/
{
Object temp
if(Length==0)
throw new java.util.NoSuchElementException()
else if(Length==1)
{
temp=Head.data
deleteAll()
}
else
{
Node cur=cursor()
temp=cur.data
if(cur==Head)
Head=cur.next
else if(cur==Tail)
{
Pointer.next=null
Tail=Pointer
reset()
}
else
Pointer.next=cur.next
Length--
}
return temp
}
private Node cursor()
/*返回当前结点的指针*/
{
if(Head==null)
throw new java.lang.NullPointerException()
else if(Pointer==null)
return Head
else
return Pointer.next
}
public static void main(String[] args)
/*链表的简单应用举例*/
{
List a=new List ()
for(int i=1i<=10i++)
a.insert(new Integer(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("There is no Node in List \n")
System.in.println("You can press return to quit\n")
try
{
System.in.read()
//确保用户看清程序运行结果
}
catch(IOException e)
{}
}
}
class Node
/*构成链表的结点定义*/
{
Object data
Node next
Node(Object d)
{
data=d
next=null
}
}
读者还可以根据实际需要定义新的方法来对链表进行 *** 作。双向链表可以用类似的方法实现只是结点的类增加了一个指向前趋结点的指针。
可以用这样的代码来实现:
class Node
{
Object data
Node next
Node previous
Node(Object d)
{
data=d
next=null
previous=null
}
}
当然,双向链表基本 *** 作的实现略有不同。链表和双向链表的实现方法,也可以用在堆栈和队列的实现中,这里就不再多写了,有兴趣的读者可以将List类的代码稍加改动即可。
希望对你有帮助。
java中创建链表的例子:package zx
class Link{
private Node root
class Node{
private String name
private Node Next
public Node(String name){
this.name = name
}
public String getName(){
return this.name
}
public void addNode(Node newNode){
if(this.Next==null){
this.Next = newNode
}else{
this.Next.addNode(newNode)
}
}
public void printNode(){
System.out.print(this.name + "-->")
if(this.Next!=null){
this.Next.printNode()
}
}
}
public void add(String name){
Node newNode = new Node(name)
if(this.root==null){
this.root = newNode
}else{
this.root.addNode(newNode)
}
}
public void print(){
if(this.root!=null){
this.root.printNode()
}
}
}
public class LinkDemo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Link link = new Link()
link.add("根节点")
link.add("第一节点")
link.add("第二节点")
link.add("第三节点")
link.add("第四节点")
link.print()
System.out.println("null")
}
}
public class Linktest {//反转方法 ,传入一个链表
public static LinkNode reversal(LinkNode list){
//pre用来存放前一个链表节点
LinkNode pre =list
//取出下一个链表节点 ,cru 用来存放当前链表节点
LinkNode cru = list.getNext()
//next用来存放下一个链表节点
LinkNode next
//如果当前节点不为空(这里意思是 如果传进来的list 有下一个节点就继续执行)
while(null!=cru){
//取出当前节点的下一个节点
next = cru.getNext()
//把前一个节点赋予当前节点的下一个节点(这里产生实际改变)
cru.setNext(pre)
//把当前节点变量赋予前一个节点的变量
pre=cru
//把下一个节点变量赋予当前
cru = next
}
//循环体内会循环到方法传入的LinkNode 没有前一个节点为止
//因为几次交换的原因
//因为循环结束,所以把next赋空
list.setNext(null)
//因为循环的原因,前一个节点实际是第一个节点
list=pre
//返回第一个节点
return list
}
public static void main(String[] args) {
LinkNode head = new LinkNode(0)
LinkNode tmp = null
LinkNode cur = null
for (int i = 1 i < 10 i++) {
tmp = new LinkNode(i)
if (1 == i) {
head.setNext(tmp)
} else {
cur.setNext(tmp)
}
cur = tmp
}
LinkNode h = head
while (null != h) {
System.out.print(h.getVal() + " ")
h = h.getNext()
}
head = reversal(head)
System.out.println("\n**************************")
//打印反转后的结果
while (null != head) {
System.out.print(head.getVal() + " ")
head = head.getNext()
}
}
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)