单向链表的Java实现

如果需要快速访问数据,很少或不插入和删除元素,就应该用数组,相反,如果需要经常插入和删除的就需要用链表了。

实例一
设计一个节点类,以String为数据的保存内容,手工把各节点串联起来,然后从根节点开始输出整条链表数据。

class Node{
     private String data;
     private Note next;    //表示保存下一个节点
     public Node(String data){     //通过构造函数设置节点内容
          this.data=data;
     }
     public void setNext(Node next){      //设置下一个节点
          this.next=next;     
     }
     public Node getNext(){      //取得下一个节点
          return this.next;
     }
     public String getData(){       //取得本节点内容
          return this.data; 
     }
}

public class LinkDemo01{
     public static void main(String args[]){
          Node root=new Node("火车头");
          Node n1=new Node("车厢-A");
          Node n2=new Node("车厢-B");
          Node n3=new Node("车厢-C");
          root.setNext(n1);    //手工去处理各个节点的关系
          n1.setNext(n2);
          n2.setNext(n3);
          printNode(root);    //从头开始输出
     }
     public static void printNode(Node node){       //通过递归的方法将单链表输出
          System.out.print(node.getData()+"\t");
          if(node.getNext()!=null){
               printNode(node.getNext());
          }
     }
}

实例二
这里把对节点的操作封装起来,包括:增加节点、查找节点、删除节点。把节点类作为链表类的内部类。

class Link { // 链表的完成类
     class Node { // 保存每一个节点,此处为了方便直接定义成内部类
           private String data ;
           private Node next ;

           public Node(String data) {
               this.data = data;
          }

           public void add(Node newNode) { // 将节点加入到合适的位置
               if (this .next == null) { // 如果下一个节点为空,则把新节点设置在next的位置上
                    this.next = newNode;
              } else { // 如果不为空,则需要向下继续找next
                    this.next .add(newNode);
              }
          }

           public void print() {
              System. out.print(this .data + "\t" );
               if (this .next != null) { // 还有下一个元素,需要继续输出
                    this.next .print(); // 下一个节点继续调用print
              }
          }

           public boolean search(String data) { // 内部搜索的方法
               if (data.equals(this.data)) { // 判断输入的数据是否和当前节点的数据一致
                    return true ;
              } else { // 向下继续判断
                    if (this .next != null) { // 下一个节点如果存在,则继续查找
                         return this .next .search(data); // 返回下一个的查询结果
                   } else {
                         return false ; // 如果所有的节点都查询完之后,没有内容相等,则返回false
                   }
              }
          }

           public void delete(Node previous, String data) {
               if (data.equals(this.data)) { // 找到了匹配的节点
                   previous. next = this.next ; // 空出当前的节点
              } else {
                    if (this .next != null) { // 还是存在下一个节点
                         this.next .delete(this, data); // 继续查找
                   }
              }
          }
     }

     private Node root; // 链表中必然存在一个根节点

     public void addNode(String data) { // 增加节点
          Node newNode = new Node(data); 
           if (this .root == null) { 
               this.root = newNode; // 将第一个节点设置成根节点
          } else { // 不是根节点,放到最后一个节点之后
               this.root .add(newNode); // 通过Node自动安排此节点放的位置
          }
     }

     public void printNode() { // 输出全部的链表内容
           if (this .root != null) { // 如果根元素不为空
               this.root .print(); // 调用Node类中的输出操作
          }
     }

     public boolean contains(String name) { // 判断元素是否存在
           return this .root .search(name); // 调用Node类中的查找方法
     }

     public void deleteNode(String data) { // 删除节点
           if (this .contains(data)) { // 判断节点是否存在
               // 一定要判断此元素现在是不是根元素相等的
               if (this .root .data .equals(data)) { // 内容是根节点
                    this.root = this.root .next ; // 修改根节点,将第一个节点设置成根节点
              } else {
                    this.root .next .delete(root , data); // 把下一个节点的前节点和数据一起传入进去
              }
          }
     }
}

public class LinkDemo02 {
     public static void main(String args[]) {
          Link l = new Link();
          l.addNode( "A"); // 增加节点
          l.addNode( "B");
          l.addNode( "C");
          l.addNode( "D");
          l.addNode( "E");
          System. out.println("======= 删除之前 ========" );
          l.printNode();
          l.deleteNode( "C"); // 删除节点
          l.deleteNode( "D");
          l.deleteNode( "A");
          System. out.println("\n====== 删除之后 =========");
          l.printNode();
          System. out.println("\n查询节点:" + l.contains("B"));
     }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,302评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,232评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,337评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,977评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,920评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,194评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,638评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,319评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,455评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,379评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,426评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,106评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,696评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,786评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,996评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,467评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,043评论 2 341

推荐阅读更多精彩内容