双向链表任意遍历打印实现

实现双向链表的任意遍历打印,涉及到双向链表和递归调用。本这段代码一共实现了5中遍历打印的方法,其中有一种是传入根节点,一种是不需要传入结点,另外3种都是任一个结点的参数。其中printRan3()方法独立实现打印,是这段代码的亮点,printRan2()方法有助于你理解递归调用。printRan4()方法是石军同学实现的,我只是在这里展示。
看懂这段代码,将很大程度上提高你看懂递归调用的能力。

package linkdemo;

public class LinkDemo {

public static void main(String args[]){
LinkDemo demo=new LinkDemo();
LinkNode foot=demo.creatLink();
System.out.println("调用printAll()方法打印");
demo.printAll(foot);
System.out.println("调用printRan1()方法打印");
demo.printRan1();
System.out.println("调用printRan2()方法打印");
demo.printRan2(foot.getNext());
System.out.println("调用printRan3()方法打印");
demo.printRan3(foot.getNext());

foot.delete(); //删除链表中的根节点
foot.insert(new LinkNode("插入的结点"));
System.out.println("调用printRan4()方法打印");
demo.printRan4(foot.getNext());
}

//创建一个新的链表,返回根节点
public LinkNode creatLink(){
LinkNode no1=new LinkNode("节点1");
LinkNode no2=new LinkNode("节点2");
LinkNode no3=new LinkNode("节点3");
LinkNode no4=new LinkNode("节点4");
LinkNode no5=new LinkNode("节点5");

//手动设置节点在链表中的关系
no1.setNext(no2);
no2.setPre(no1);
no2.setNext(no3);
no3.setPre(no2);
no3.setNext(no4);
no4.setPre(no3);
no4.setNext(no5);
no5.setPre(no4);
LinkNode.setFoot(no1); //设置no1为根节点

return no1;
}

//传入链表的根节点,输出所有的节点的值的方法
public void printAll(LinkNode foot){
if(foot!=null){
System.out.println("节点的值是:"+foot.getData());
foot=foot.getNext();
printAll(foot);
}
}

//无需传入任何一个链表中的节点,打印出所有的节点的方法一(使用根节点foot类属性)
public void printRan1(){
printAll(LinkNode.getFoot());
}

//传入链表中任何一个节点,遍历输出所有链表中所有节点的方法二(未使用根节点foot类属性)
public void printRan2(LinkNode ran){
boolean b1=true;
boolean b2=true;
int count1=0;

printRan(ran,b1,b2,count1);

}

private void printRan(LinkNode ran,boolean b1,boolean b2,int count1){
//打印ran之后的所有节点
if(b1&&(ran.getNext()!=null)){
ran=ran.getNext();
if(ran.getNext()!=null){
System.out.println("节点的值是:"+ran.getData());
count1++;
printRan(ran,b1,b2,count1);
}

if(ran.getNext()!=null){
b1=false;
b2=false;
}
}

//打印ran节点,并将ran回复到原始出入的ran值
if(b1){
System.out.println("节点的值是:"+ran.getData());

if(count1!=0){
for(int i=0;i<count1+1;i++){
ran=ran.getPre();
}
System.out.println("节点的值是:"+ran.getData());
}
b1=false;
}

//打印ran节点之前的所有节点
if(b2){
ran=ran.getPre();
if(ran!=null){
System.out.println("节点的值是:"+ran.getData());
printRan(ran,b1,b2,count1);
}
if(ran!=null){
b2=false;
}
System.out.println("****************一组打印完了*******************");
}
}

//单个方法实现任一节点的遍历打印:方法三
//(不需要调用另外的方法,单个参数,不需要使用LinkNode类中的foot属性)
public void printRan3(LinkNode ran){
if(ran.getPre()==null){
while(ran!=null){
System.out.println(ran.getData());
ran=ran.getNext();
}
return;
}
if(ran!=null){
ran=ran.getPre();
printRan3(ran);
}
}

//传入任意结点,遍历打印所有结点的方法四
//(不需要使用LinkNode中foot属性,要调用printRan1()方法)
// ——石军同学实现的,没有征得你同意就在这边贴出来了,希望原谅
public void printRan4(LinkNode ran){
if(ran.getPre()!=null){
ran=ran.getPre();
printRan4(ran);
}else{
printAll(ran);
}
}

};




package linkdemo;
//链表的节点类
public class LinkNode {

private LinkNode next; //下一个节点
private LinkNode pre; //前一个节点
private String data; //链表的值
private static LinkNode foot; //类属性,链表的根节点属性

public LinkNode(String data){
this.data=data;
}
public static LinkNode getFoot(){
return foot;
}



public LinkNode getNext() {
return next;
}


public void setNext(LinkNode next) {
this.next = next;
}


public LinkNode getPre() {
return pre;
}


public void setPre(LinkNode pre) {
this.pre = pre;
}


public String getData() {
return data;
}


public static void setFoot(LinkNode foot) {
LinkNode.foot = foot;
}


//在一个节点后面插入新的节点的方法
public void insert(LinkNode newNode){
LinkNode no=this.next;

this.next=newNode;
newNode.pre=this;
no.pre=newNode;
newNode.next=no;
}

//删除调用该方法的节点
public void delete(){
if(this.pre==null){ //如果是首节点
this.data=this.next.data;
this.next.next.pre=this;
this.next=this.next.next;
}else{
this.pre.next=this.next;
this.next.pre=this.pre;
}
}


};





[img]http://dl.iteye.com/upload/attachment/292920/3dfcd048-a1d4-308c-9dc9-b6561fd9ab0e.png[/img]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值