实现双向链表的任意遍历打印,涉及到双向链表和递归调用。本这段代码一共实现了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;
}
}
};
- 大小: 14 KB
分享到:
相关推荐
3.适用于大部分场景:双向链表在许多场景中都非常有用,比如需要频繁地在链表的任意位置插入和删除节点,或者需要在双向遍历的情况下快速访问前一个节点。 然而,与单向链表相比,双向链表在空间上需要更多的内存,...
双向链表 定义 :每个节点有两个指针域,分别知道直接前驱和直接后继节点 , 特点是可以重任意节点出发,从两个方向遍历链表 数据结构 typedef struct node { int data; struct node *font ; struct node *next; ...
双向链表结构体 创建结点 初始化链表 释放链表 获取链表长度 获取头结点 获取尾结点 遍历链表 插入头结点 插入尾结点 任意位置插入结点 删除头结点 删除尾结点 删除任意位置结点 获取任意位置结点 查找链表中指定的...
lru缓存leetcode 学习和探索编程 C、C++、Python 探索领域: 1 数组 二分搜索、在滑动窗口中查找...,将二叉树转换为双向链表,打印树边界、连接同级兄弟、序列化/反序列化二叉树、连接所有兄弟、带父指针的中序后继 BS
7.9 动态双向链表的应用 7.10 判断完全二叉树 7.11 动画模拟创建二叉树 7.12 打印符号三角形 7.13 递归函数的非递归求解 7.14 任意长度整数加法 第8章 数值计算问题 8.1 递推化梯形法求解定积分 8.2 求解低阶定积分...
它是使用双向链表实现的。 还提供了两个简单的程序来演示和使用ADT。 它们都接受任意数量的txt文件作为输入: Sortwords:此程序从给定的txt文件中提取单词,然后按排序顺序将它们打印到控制台。 反向单词:该...
根据指针的指向,链表能形成不同的结构,例如单链表,双向链表, 循环链表等。 链表的优点: 1. 链表是很常⽤的⼀种数据结构,不需要初始化容量,可以任意加减元素; 2. 添加或者删除元素时只需要改变前后两个元素...
范例1-52 双向链表元素值的查询 129 ∷相关函数:GetElemP函数 1.3.22 稀疏矩阵的建立 136 范例1-53 稀疏矩阵的建立 136 ∷相关函数:Create函数 1.3.23 稀疏矩阵的删除 138 范例1-54 稀疏矩阵的删除 138 ∷...
范例1-52 双向链表元素值的查询 129 ∷相关函数:GetElemP函数 1.3.22 稀疏矩阵的建立 136 范例1-53 稀疏矩阵的建立 136 ∷相关函数:Create函数 1.3.23 稀疏矩阵的删除 138 范例1-54 稀疏矩阵的删除 138 ∷...
范例1-52 双向链表元素值的查询 129 ∷相关函数:GetElemP函数 1.3.22 稀疏矩阵的建立 136 范例1-53 稀疏矩阵的建立 136 ∷相关函数:Create函数 1.3.23 稀疏矩阵的删除 138 范例1-54 稀疏矩阵的删除 138 ∷...
实例088 创建双向链表 114 实例089 创建循环链表 117 实例090 双链表逆置 118 实例091 双链表逆序输出 120 实例092 约瑟夫环 122 实例093 创建顺序表并插入元素 123 实例094 向链表中插入结点 125 ...
(3)从文件读入30个学生成绩(0-100之间),建立一个双向循环链表并输出,调整链表顺序,使所有的及格成绩排在不及格成绩之前,并输出。 2、二叉树的应用 任务 :编程实现二叉树的建立,层次遍历,(递归和非递归...
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 要求不能创建任何新的结点,只调整指针的指向。 10 / \ 6 14 / \ / \ 4 8 12 16 转换成双向链表 4=6=8=10=12=14=16。 n个数字(0,1,...
2、实现1所要求的代码后,运行设计好的代码,将以下的几组整数序列建成搜索二叉树,并记录下它们的前序遍历序列和后序遍历序列: a. 1、3、5、7、9; b. 1、13、35、13、27; c. 50、25、78、13、44、...
实例049 使用任意组件拖动窗体 58 实例050 动态创建窗体和释放窗体 59 实例051 修改提示字体及颜色 60 1.14 其他技术 61 实例052 窗口融合技术 61 实例053 给MDI窗体加背景 62 实例054 如何关闭MDI类型...
实例132 双向链表的实现 168 实例133 堆栈的实现 173 实例134 队列的实现 175 实例135 树的实现 177 6.2 常见算法的实际应用 180 实例136 计算1+22+33+44+…+nn的值 180 实例137 计算10!的值 181 实例138 求最大公...