zoukankan      html  css  js  c++  java
  • 模拟实现单链表

    单链表及其结点:

    链表是一系列存储元素的单元通过指针串接起来实现的,这些单元称为结点,每个单元有两个域:

    • 值域:用于存储数据元素
    • 指针域:指向下一个具有相同结构的结点

    因为只有一个指针结点,称为单链表

    特点:

    •            尾结点的特征是其next引用为空
    •            链表中每个结点的next引用都相当于一个指针,指向另一个结点。借助next可完成链表首结点移动到尾结点。
    •            单链表中通常用head引用来指向链表的首结点,由head引用可以完成对整个链表中所有结点的访问。
    •            单链表只能通过前驱结点找到后续结点,而无法从后续结点找到前驱结点。

    与数组相似,单链表中的结点也具有一个线性次序,即如果节点p的next引用指向结点S,则p就是S的直接前驱,反之是直接后继。

    单链表的查询、添加、删除操作分析:

    查询操作:在单链表中查找是否包含某个数据元素e,只能从链表的首结点开始,通过每个结点的next引用来依次访问链表中的每个结点,完成相应的查找操作。

    1 起始条件:p=head;

    2 结束条件:找到e.equals(p.getData())==true

                        未找到:p==null

    3 p指向下一个结点:p=p.getNext();

    缺点:逐个比较,频繁移动指针,导致效率低下

    如果查询第i个元素的值,同样无法直接定位,只能从首结点开始逐个移动到第i个结点,效率同样低下。

    添加操作

    在单链表中元素的插入,是通过在链表中插入数据元素所属的结点来完成的。

    对于链表的不同位置,插入的过程会有细微的差别。中间,末尾的添加过程是一样的,关键是首部添加,会有不同。

    首部添加会改变整个单链表的起始终点。

    1 指明新结点的后继

    2 指明新结点的前驱

    添加结点不需要移动元素,只需要修改元素的指针,效率高。

    删除操作:改变指针,使该结点的前驱指向下个结点

    在用单链表实现线性表的时候,为了使程序更加简洁,我们通常在单链表的最前面添加一个头结点。

    头结点值域为空,next指向线性表中0号元素所在结点,值域为null。可以对空表、非空表首元结点进行统一处理,简化代码,很常用。

    代码实现:

    1 新建Node类,内有data和next属性,分别代表值域和指针域;

    package com.lt.datastructure.linetable;
    /**
     * 单链表结点
     */
    public class Node {
        Object data;//存储
        Node next;
        public Node() 
        {
         }
        
        public Node(Object data) 
        {    
             this.data = data;
         }
        
       public Node(Object data, Node next) 
       {
            super();
            this.data = data;
            this.next = next;
        }
       
    public Object getData() {
        return data;
    }
    public void setData(Object data) {
        this.data = data;
    }
    public Node getNext() {
        return next;
    }
    public void setNext(Node next) {
        this.next = next;
    } 
    }

    2  实现简单的功能

     1 package com.lt.datastructure.linetable;
     2 
     3 public class SingleLinkedList implements List{
     4     
     5     private Node head = new Node();//头结点,不存储数据,为了方便
     6     
     7     private int size; //几个结点
     8     
     9 
    10     public int size() {
    11         return size;
    12     }
    13 
    14     @Override
    15     public Object get(int i) {
    16         //和顺序表不一样,不能通过索引计算定位,需要从头结点逐个查找
    17         Node p = head;
    18         for(int j = 0 ; j<=i;j++){
    19             p = p.next;
    20           21 
    22         }
    23         return p.data;
    24     }
    25     
    26     @Override
    27     public void add(int i, Object e) {
    28         //头结点
    29         Node p = head;
    30         for(int j=0;j<i;j++){
    31         
    32         p = p.next; 
    33         }                             
    34         Node newNode = new Node();
    35         newNode.data = e;
    36         newNode.next = p.next; 
    37         p.next = newNode;    38         
    39         size++;        
    40     }
    41 
    42     @Override
    43     public void add(Object e) {
    44      this.add(size,e);        
    45     }
    46
  • 相关阅读:
    C++ 虚基类表指针字节对齐
    C++ 虚函数的内存分配
    虚函数&&虚继承
    内存管理简便复习总结
    stack,heap的区别
    内存泄漏(memory leak)和内存溢出
    php+mysqli预处理技术实现添加、修改及删除多条数据的方法
    JavaScript 常用方法总结
    6个超实用的PHP代码片段
    php 备份数据库代码(生成word,excel,json,xml,sql)
  • 原文地址:https://www.cnblogs.com/ltfxy/p/9810909.html
Copyright © 2011-2022 走看看