复习一下简单单项链表的实现。
在动手写链表之前,需要思考链表是如何组成的,一般来说,一个简单的单项链表主要是由节点构成,由于链表的特性,头节点是一个十分重要的成员,所以,链表必须的成员是节点Node,头指针headNode;链表的基础功能是增删改查,所以应有关于增删改查的四个方法;链表应该提供打印链表的功能,故应该有这个方法:
public class Links{
class Node{}
private Node headNode = null ;
public void addNodeToLink(){}
public void delNodeFromLink(){}
public void sltNodeFromLink(){}
public void fixNodeFromLink(){}
public void printLink(){}
}
为了丰富链表的操作,我们可以追加一下几个属性,链表长度length,备用指针节点pointNode;方法中应该提供获取链表总长的方法,初始化备用节点的方法:
public class Links{
class Node{}
private Node headNode = null ;
private Node pointNode = headNode ;
private int length = 0 ;
public void addNodeToLink(){}
public void delNodeFromLink(){}
public void sltNodeFromLink(){}
public void fixNodeFromLink(){}
public void printLink(){}
public int getLinkLength(){
return this.length ;
}
public void resetPointNode(){
this.pointNode = null ;
}
}
接下来思考Node类的成员。
Node是节点,那么必须有指向下一节点的引用next;Node中要有数据data,以及关于数据的getter和setter方法:
public class Links{
class Node{
private String data = null ;
private Node next = null ;
public Node(String data){
this.setData(data) ;
}
public void setData(String data){
this.data = data ;
}
public String getData(){
return this.data ;
}
}
private Node headNode = null ;
private Node pointNode = headNode ;
private int length = 0 ;
public void addNodeToLink(){}
public void delNodeFromLink(){}
public void sltNodeFromLink(){}
public void fixNodeFromLink(){}
public void printLink(){}
public int getLinkLength(){
return this.length ;
}
public void resetPointNode(){
this.pointNode = null ;
}
}
成员基本定义好了以后,开始逐一实现方法。
- 增加
链表增加节点之前一定要确定是否是头结点,如果头结点为空就将头结点设置为我们新建的节点。节点的添加使用尾插法,即新的节点链接在链表的尾部,判断的逻辑为:如果当前节点为空,则把新建的节点设置为此节点,如果该节点不为空,则检查该节点的next引用。此过程是一个递归的过程,如果该过程在链表的方法里实现会很麻烦,所以可以在Node类中定义方法,让节点自行判断,代码如下:
public class Links{
class Node{
private String data = null ;
private Node next = null ;
public Node(String data){
this.setData(data) ;
}
public void setData(String data){
this.data = data ;
}
public String getData(){
return this.data ;
}
public void linkNext(Node node){ //链表增加指定的节点
if(this.next == null){ //如果当前节点的下一个节点为null,就将传入的节点设置为next
this.next = node ;
}else{ //如果当前节点的下一个节点不为空,则让next节点递归调用此方法
this.next.linkNext(node) ;
}
}
}
private Node headNode = null ;
private Node pointNode = headNode ;
private int length = 0 ;
public void addNodeToLink(String data){ //向链表中添加一个节点
Node node = new Node(data) ;
if(this.headNode == null){ //如果头结点为空,则将该节点设置为头节点
this.headNode = node ;
}else{
this.headNode.linkNext(node) ; //如果头结点不会为,则调用节点类中的方法处理
}
this.length ++ ; //链表长度+1
}
public void delNodeFromLink(){}
public void sltNodeFromLink(){}
public void fixNodeFromLink(){}
public void printLink(){}
public int getLinkLength(){
return this.length ;
}
public void resetPointNode(){
this.pointNode = null ;
}
}
至此,增加功能设计完毕。
- 查找
由于删除和修改的本质是先查找再操作,所以先实现查找功能。
查找的本质也是递归调用,运用Node方法中的getter方法和传进去的数据进行比较,如果一样则说明存在,如果不一样则调用该节点的next引用,当next引用为空的时候仍然没有一样的,说明不存在该节点,逻辑上还是很好实现的,需要注意的是,凡事递归最好都在Node中定义,因为这样比较好实现:
public class Links{
class Node{
private String data = null ;
private Node next = null ;
public Node(String data){
this.setData(data) ;
}
public void setData(String data){
this.data = data ;
}
public String getData(){
return this.data ;
}
public void linkNext(Node node){ //链表增加指定的节点
if(this.next == null){ //如果当前节点的下一个节点为null,就将传入的节点设置为next
this.next = node ;
}else{ //如果当前节点的下一个节点不为空,则让next节点递归调用此方法
this.next.linkNext(node) ;
}
}
public boolean selectNode(String data){ //根据给定的data查找是否存在该节点
if(this.getData().equals(data)){
return true ; //存在,返回true
}else{
if(this.next != null){ //如果当前节点的下一个节点不为空,返回下一个节点的调用结果
return this.next.selectNode(data) ;
}else{
return false ; //当前节点的下一个节点为空,说明不存在该节点,返回false
}
}
}
}
private Node headNode = null ;
private Node pointNode = headNode ;
private int length = 0 ;
public void addNodeToLink(String data){ //向链表中添加一个节点
Node node = new Node(data) ;
if(this.headNode == null){ //如果头结点为空,则将该节点设置为头节点
this.headNode = node ;
}else{
this.headNode.linkNext(node) ; //如果头结点不会为,则调用节点类中的方法处理
}
this.length ++ ; //链表长度+1
}
public void delNodeFromLink(){}
public void sltNodeFromLink(String data){ //查找一个节点
boolean hasNode = true ;
if(this.headNode.selectNode(data) == hasNode){
System.out.println("存在节点【" + data + "】") ;
}else{
System.out.println("不存在节点【" + data + "】") ;
}
}
public void fixNodeFromLink(){}
public void printLink(){}
public int getLinkLength(){
return this.length ;
}
public void resetPointNode(){
this.pointNode = null ;
}
}
- 修改
修改和查找的思路基本一样,找到节点之后用setter方法设置即可,不赘述:
public class Links{
class Node{
private String data = null ;
private Node next = null ;
public Node(String data){
this.setData(data) ;
}
public void setData(String data){
this.data = data ;
}
public String getData(){
return this.data ;
}
public void linkNext(Node node){ //链表增加指定的节点
if(this.next == null){ //如果当前节点的下一个节点为null,就将传入的节点设置为next
this.next = node ;
}else{ //如果当前节点的下一个节点不为空,则让next节点递归调用此方法
this.next.linkNext(node) ;
}
}
public boolean selectNode(String data){ //根据给定的data查找是否存在该节点
if(this.getData().equals(data)){
return true ; //存在,返回true
}else{
if(this.next != null){ //如果当前节点的下一个节点不为空,返回下一个节点的调用结果
return this.next.selectNode(data) ;
}else{
return false ; //当前节点的下一个节点为空,说明不存在该节点,返回false
}
}
}
public void fixNode(String oldData,String newData){ //修改节点
if(this.getData().equals(oldData)){
this.setData(newData) ;
}else{
if(this.next != null){
this.next.fixNode(oldData, newData) ;
}
}
}
}
private Node headNode = null ;
private Node pointNode = headNode ;
private int length = 0 ;
public void addNodeToLink(String data){ //向链表中添加一个节点
Node node = new Node(data) ;
if(this.headNode == null){ //如果头结点为空,则将该节点设置为头节点
this.headNode = node ;
}else{
this.headNode.linkNext(node) ; //如果头结点不会为,则调用节点类中的方法处理
}
this.length ++ ; //链表长度+1
}
public void delNodeFromLink(){}
public void sltNodeFromLink(String data){ //查找一个节点
boolean hasNode = true ;
if(this.headNode.selectNode(data) == hasNode){
System.out.println("存在节点【" + data + "】") ;
}else{
System.out.println("不存在节点【" + data + "】") ;
}
}
public void fixNodeFromLink(String oldData,String newData){ //修改节点数据
boolean hasNode = true ;
if(this.headNode.selectNode(oldData) == hasNode){
this.headNode.fixNode(oldData, newData) ;
}else{
System.out.println("链表中没有【"+ oldData +"】节点,无法完成修改");
}
}
public void printLink(){}
public int getLinkLength(){
return this.length ;
}
public void resetPointNode(){
this.pointNode = null ;
}
}
- 删除
删除比修改要稍复杂,删除的本质,是将要删除的节点的上一个节点的next引用改成该节点的next引用,即:
last.next = this.next
因为头结点没有last节点,所以要分开处理:如果是头结点,则把头结点更改为头结点的next节点即可,如果不是头结点,则要把last节点一并传入。如果是递归操作的话,第二个节点调用的方法只要把头结点传入即可完成递归:
public class Links{
class Node{
private String data = null ;
private Node next = null ;
public Node(String data){
this.setData(data) ;
}
public void setData(String data){
this.data = data ;
}
public String getData(){
return this.data ;
}
public void linkNext(Node node){ //链表增加指定的节点
if(this.next == null){ //如果当前节点的下一个节点为null,就将传入的节点设置为next
this.next = node ;
}else{ //如果当前节点的下一个节点不为空,则让next节点递归调用此方法
this.next.linkNext(node) ;
}
}
public boolean selectNode(String data){ //根据给定的data查找是否存在该节点
if(this.getData().equals(data)){
return true ; //存在,返回true
}else{
if(this.next != null){ //如果当前节点的下一个节点不为空,返回下一个节点的调用结果
return this.next.selectNode(data) ;
}else{
return false ; //当前节点的下一个节点为空,说明不存在该节点,返回false
}
}
}
public void fixNode(String oldData,String newData){ //修改节点
if(this.getData().equals(oldData)){
this.setData(newData) ;
}else{
if(this.next != null){
this.next.fixNode(oldData, newData) ;
}
}
}
public void delectNode(Node lastNode,String data){ //删除节点
if(this.getData().equals(data)){
lastNode.next = this.next ;
}else{
if(this.next != null){
this.next.delectNode(this, data) ;
}
//在外部方法中已经进行了节点是否存在的验证,所以不用考虑this.next = null的情况
}
}
}
private Node headNode = null ;
private Node pointNode = headNode ;
private int length = 0 ;
public void addNodeToLink(String data){ //向链表中添加一个节点
Node node = new Node(data) ;
if(this.headNode == null){ //如果头结点为空,则将该节点设置为头节点
this.headNode = node ;
}else{
this.headNode.linkNext(node) ; //如果头结点不会为,则调用节点类中的方法处理
}
this.length ++ ; //链表长度+1
}
public void delNodeFromLink(String data){ //删除一个节点
boolean hasNode = true ;
if(this.headNode.selectNode(data) == hasNode){
if(this.headNode.getData().equals(data)){
this.headNode = this.headNode.next ;
this.length -- ;
}else{
this.headNode.next.delectNode(this.headNode,data) ;
this.length -- ;
}
}else{
System.out.println("链表中没有【"+ data +"】节点,无法完成删除");
}
}
public void sltNodeFromLink(String data){ //查找一个节点
boolean hasNode = true ;
if(this.headNode.selectNode(data) == hasNode){
System.out.println("存在节点【" + data + "】") ;
}else{
System.out.println("不存在节点【" + data + "】") ;
}
}
public void fixNodeFromLink(String oldData,String newData){ //修改节点数据
boolean hasNode = true ;
if(this.headNode.selectNode(oldData) == hasNode){
this.headNode.fixNode(oldData, newData) ;
}else{
System.out.println("链表中没有【"+ oldData +"】节点,无法完成修改");
}
}
public void printLink(){}
public int getLinkLength(){
return this.length ;
}
public void resetPointNode(){
this.pointNode = null ;
}
}
- 打印
最后将打印功能加入:
public void printLink(){ //打印链表
this.pointNode = this.headNode ;
System.out.print("输出链表:");
for(int i=0 ;i < this.length ;i ++){
if(this.pointNode.next == null){
System.out.println(this.pointNode.getData());
}else{
System.out.print(this.pointNode.getData() + "->");
}
this.pointNode = this.pointNode.next ;
}
this.resetPointNode() ;
}
完整代码如下:
public class Links{
class Node{ //内部类来实现
private String data = null ; //节点数据
private Node next = null ;
public Node(String data){
this.setData(data) ;
}
public void setData(String data){
this.data = data ;
}
public String getData(){
return this.data ;
}
public void linkNext(Node node){ //链表增加指定的节点
if(this.next == null){ //如果当前节点的下一个节点为null,就将传入的节点设置为next
this.next = node ;
}else{ //如果当前节点的下一个节点不为空,则让next节点递归调用此方法
this.next.linkNext(node) ;
}
}
public boolean selectNode(String data){ //根据给定的data查找是否存在该节点
if(this.getData().equals(data)){
return true ; //存在,返回true
}else{
if(this.next != null){ //如果当前节点的下一个节点不为空,返回下一个节点的调用结果
return this.next.selectNode(data) ;
}else{
return false ; //当前节点的下一个节点为空,说明不存在该节点,返回false
}
}
}
public void fixNode(String oldData,String newData){ //修改节点
if(this.getData().equals(oldData)){
this.setData(newData) ;
}else{
if(this.next != null){
this.next.fixNode(oldData, newData) ;
}
}
}
public void delectNode(Node lastNode,String data){ //删除节点
if(this.getData().equals(data)){
lastNode.next = this.next ;
}else{
if(this.next != null){
this.next.delectNode(this, data) ;
}
//在外部方法中已经进行了节点是否存在的验证,所以不用考虑this.next = null的情况
}
}
}
private int length = 0 ; //记录链表长度
private Node headNode = null ; //头结点
private Node pointNode = null ; //备用指针
public void resetPointNode(){ //备用指针节点初始化
this.pointNode = null ;
}
/* 增加 */
public void addNodeToLink(String data){ //向链表中添加一个节点
Node node = new Node(data) ;
if(this.headNode == null){ //如果头结点为空,则将该节点设置为头节点
this.headNode = node ;
}else{
this.headNode.linkNext(node) ; //如果头结点不会为,则调用节点类中的方法处理
}
this.length ++ ; //链表长度+1
}
/* 删除 */
public void delNodeFromLink(String data){ //删除一个节点
boolean hasNode = true ;
if(this.headNode.selectNode(data) == hasNode){
if(this.headNode.getData().equals(data)){
this.headNode = this.headNode.next ;
this.length -- ;
}else{
this.headNode.next.delectNode(this.headNode,data) ;
this.length -- ;
}
}else{
System.out.println("链表中没有【"+ data +"】节点,无法完成删除");
}
}
/* 查找 */
public void sltNodeFromLink(String data){ //查找一个节点
boolean hasNode = true ;
if(this.headNode.selectNode(data) == hasNode){
System.out.println("存在节点【" + data + "】") ;
}else{
System.out.println("不存在节点【" + data + "】") ;
}
}
/* 修改 */
public void fixNodeFromLink(String oldData,String newData){ //修改节点数据
boolean hasNode = true ;
if(this.headNode.selectNode(oldData) == hasNode){
this.headNode.fixNode(oldData, newData) ;
}else{
System.out.println("链表中没有【"+ oldData +"】节点,无法完成修改");
}
}
public int getLinkLength(){ //获取链表长度
return this.length ;
}
public void printLink(){ //打印链表
this.pointNode = this.headNode ;
System.out.print("输出链表:");
for(int i=0 ;i < this.length ;i ++){
if(this.pointNode.next == null){
System.out.println(this.pointNode.getData());
}else{
System.out.print(this.pointNode.getData() + "->");
}
this.pointNode = this.pointNode.next ;
}
this.resetPointNode() ;
}
/*
public void delNodeFromLink(int nodeNum){}
public void sltNodeFromLink(int nodeNum){}
public void fixNodeFromLink(int nodeNum){}
//*/
}
- 测试
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Links link = new Links() ;
//1 测试链表是否可以被正常创建
link.addNodeToLink("1") ;
link.addNodeToLink("2") ;
link.addNodeToLink("3") ;
System.out.println("链表的长度为:" + link.getLinkLength());
///*2 测试链表的查找功能
link.sltNodeFromLink("1") ;
link.sltNodeFromLink("2") ;
link.sltNodeFromLink("3") ;
link.sltNodeFromLink("4") ;//*/
//3 测试链表的修改功能和打印链表功能
link.printLink() ;
link.fixNodeFromLink("4","3") ;
link.fixNodeFromLink("3","4") ;
link.printLink() ;
//4 测试链表的删除功能
link.delNodeFromLink("3") ;
link.delNodeFromLink("4") ;
link.printLink() ;
}
}
输出结果:
链表的长度为:3
存在节点【1】
存在节点【2】
存在节点【3】
不存在节点【4】
输出链表:1->2->3
链表中没有【4】节点,无法完成修改
输出链表:1->2->4
链表中没有【3】节点,无法完成删除
输出链表:1->2
共同学习,写下你的评论
评论加载中...
作者其他优质文章