Java中单链表的实现和单链表的反转(倒置)

单链表的实现

用一组地址任意的存储单元存放线性表中的数据元素。以元素(数据元素的映象) + 指针(指示后继元素存储位置) = 结点。
以“结点的序列”表示线性表,称作线性链表(单链表)。单链表是一种顺序存取的结构,为找第 i 个数据元素,必须先找到第 i-1 个数据元素。 
链表的结点结构: 
         ┌──┬──┐   
         │data│next│   
         └──┴──┘   
   data域:存放结点值的数据域   
   next域:存放结点的直接后继的地址(位置)的指针域(链域)。

注意:①链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的。   
          ②每个结点只有一个链域的链表称为单链表(Single Linked List)。
所谓的链表就好像火车车厢一样,从火车头开始,每一节车厢之后都连着后一节车厢。

例如:创建一节车厢的节点类,其代码如下:
   class Node {
     private String data;   //保存该节点内容
     private Node next;    //保存下一个节点
     public Node() {}
     public Node(String data) {
       this.data = data;
     }
     public void setData(String data) {
       this.data = data;
     }
     public String getData() {
       return this.data;
     }
     public void setNext(Node next) {
       this.next = next;
     }
     public Node getNext() {
       return this.next;
     }
   }

实现一个单链表节点操作包括增加数据、查找数据、删除数据。删除节点,则是直接修改上一个节点的引用即可。

例如:实现链表操作,代码如下:
   class Link<T>  {

     class Node<T>  {
       private T info ;   //保存节点内容
       private Node<T> next;    //保存下一个节点
       public Node(T info) {
         this.info = info;
       }
       public T getInfo() {return this.info;}
       public Node<T> getNext() {return this.next;}
       public void setNext(Node<T> next) {this.add(next);}
       public void setNext(T info) {this.add(info);}

       public void add(Node<T> newNode) {
         if(this.next == null) {
           this.next = newNode;
         } else {
           this.next.add(newNode);   //运用递归方法来完成下一个节点处的增加
         }
       }
      
      public void add(T info) {
       Node<T> newNode = new Node<T>(info);
          this.add(newNode);
      }

       public boolean search(T info) {
         if(info.equals(this.info)) {
           return true;
         } else {                   //判断下一个节点
           if(this.next != null) {  //下一个节点存在,则继续查找
              return this.next.search(info);
           } else {
              return false;
           }
         }
       }

       public void delete(Node<T> preNode,T info) {
         if(info.equals(this.info)) {
           preNode.next = this.next; //修改上一个节点的引用
         } else {
           if(this.next != null) { 
              this.next.delete(this,info);
           }
         }
       }

       public void print() {
         System.out.print(this.info.toString()+"/t");
         if(this.next != null) {
            this.next.print();
         }
       }
     }

     private Node<T>  root;       //根节点
     
     public void addNode(T info) {  //新增
        Node<T> newNode = new Node<T>(info);
        if(this.root == null) {
           this.root = newNode;
        } else {
           this.root.add(newNode);
        }
     }

     public boolean contaits(T info) {  //查询
        return this.root.search(info);
     }

     public void deleteNode(T info) {   //删除
        if(this.contaits(info)) {
           if(this.root.info.equals(info)) { //包含该内部类的外部类中,可以通过该内部类的实例来访问内部类的私有属性和方法
              this.root = this.root.next;
           } else {
              this.root.next.delete(this.root,info);
           }
        }
     }

     public void printNode() {   //打印
        if(this.root != null) {
           this.root.print();
        }
     }

   }

此处的Node类是一个Inner Class(内部类),Link类此处属于Outer Class(外部类) ,内部类和外部类之间都可以通过其对应的实例来访问其私有的属性和方法。

一个内部类除了通过外部类访问外,也可直接在其他类中进行调用,调用的格式为:
外部类 外部类对象 =  new 外部类();
外部类.内部类 内部类对象 = 外部类对象.new 内部类();

调用该链表的主要部分:
   Link<String> myLink = new Link<String>();
   myLink.addNode("A");
   myLink.addNode("B");
   myLink.addNode("C");
   myLink.addNode("D");
   myLink.printNode();
   myLink.deleteNode("C");
   System.out.println();
   myLink.printNode();
   System.out.println();
   //内部类对象
   Link<String>.Node<String> inns = myLink.new Node<String>("abcd");
   inns.print();

单链表的反转(倒置)reverseNode
   反转(倒置):则必须在泛类 Link<T>中,再添加两个私有的Node<T>属性temp,cur,其反转实现代码为:

    class Link<T>  {

        .......(与上面的Link类中代码相同)

       private Node<T>  temp, cur; // 零时链表、当前节点

       public void reverseNode() {
             if (this != null  &&  this.root  != null) {
                   this.temp = this.root;
                   this.cur = this.root;
                   this.root = null;
                  while (this.temp.next != null) {
                           while (this.cur.next != null) {
                                   this.cur = this.cur.next;
                           }
                          this.addNode(this.cur.info);
                          this.temp.delete(this.temp, this.cur.info);
                          this.cur = this.temp;
                 }
                 if(this.temp.next == null && this.temp.info != null) {
                         this.addNode(this.temp.info);
                }
           }
      }

   }

调用实现链表反转的主要代码:

   Link<String> myLink = new Link<String>();
   myLink.addNode("A");
   myLink.addNode("B");
   myLink.addNode("C");
   myLink.addNode("D");
   myLink.printNode();
   System.out.println();
   myLink.reverseNode();
   // 反转后
   myLink.printNode();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值