线性表的链式存储

Posted sshhsun-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性表的链式存储相关的知识,希望对你有一定的参考价值。

数据结构 —- 线性表


单链表

线性表的链式存储是用若干地址分散的存储单元存储数据元素,逻辑上相邻的数据元素在物理地址上不一定相邻,必须采用附加信息表示元素之间的顺序关系,因此存储一个数据元素的存储单元至少包含两部分–数据域和地址域

代码实现

package com.sshhsun.list;

public class MSinglyLinkedList<T> implements LList<T> 

    protected Node<T> head;

    public MSinglyLinkedList() //默认构造方法,创建单节点,即data和next均为null
        this.head = new Node<T>();
    

    //由指定的数组中的对象创建单链表,采用尾插入构造链表
    public MSinglyLinkedList(T[] element) 
        this();
        Node<T> rear = this.head;
        for (int i = 0; i < element.length; i++) 
            rear.next = new Node<T>(element[i], null); // 尾插入创建节点链入rear节点
            rear = rear.next; // rear指向新的莲尾节点
        
    

    @Override
    public boolean isEmpty() 

        return this.head.next == null;
    

    @Override
    public int length() 
        int i = 0;
        Node<T> p = this.head.next;
        while (p != null) 
            p = p.next;
            i++;
        
        return i;
    

    @Override
    public String toString() 

        StringBuilder str = new StringBuilder("(");
        Node<T> p = this.head.next;
        while (p != null) 
            str.append(p.data.toString());
            if (p.next != null) 
                str.append(",");
            
            p = p.next;
        
        str.append(")");
        return str.toString();

    

    @Override
    public T get(int i)  // 返回第i个元素,若i制定序号无效,则返回null
        if (i >= 0) 
            Node<T> p = this.head.next;
            for (int j = 0; p != null && j < i; j++) 
                p = p.next;
            
            if (p != null) 
                return p.data;
            
        
        return null;
    

    @Override
    public void set(int i, T x) // 设置第i个元素为x,若i指定序号无效则抛出越界异常。
        if (x == null) 
            return;
        
        if (i >= 0) 
            Node<T> p = this.head.next;
            for (int j = 0; p != null && j < i; j++) 
                p = p.next;
            
            if (p != null) 
                p.data = x;
            
         else 
            throw new IndexOutOfBoundsException(i + "");
        
    

    @Override
    public void insert(int i, T x) // 将x对象插在序号为i 节点前,O(n)
        if (x == null) 
            return;
        
        Node<T> p = this.head;
        for (int j = 0; p.next != null && j < i; j++)   // 循环停止时,p指向第i-1个节点或者最后一个节点。
            p = p.next;
        

        //插入x作为p节点的后继节点,包括头插入,中间/尾插入
        p.next = new Node<T>(x, p.next); 
    

    @Override//在单链表的组后添加对象
    public void append(T x) 
        insert(Integer.MAX_VALUE, x);
    

    @Override
    public T remove(int i)  //删除序号为i的节点,若操作成功,则返回被删除对象,否则返回null 
        if (i>=0) 
            Node<T> p = this.head;
            for (int j = 0; p.next != null && j < i; j++)   // 循环停止时,p指向第i-1个节点或者最后一个节点。
                p = p.next;
            
            if (p.next!=null) 
                T old=p.next.data;
                p.next=p.next.next;
                return old;
            
        
        return null;
    

    @Override
    public void removeAll() 
        this.head.next = null;
    

    @Override
    public int search(T key) 

        return 0;
    



单链表的应用 1

使用单链表进行求平均值

package com.sshhsun.list;

public class SinglyLinkedList_average 

    public static void main(String[] args) 
        MSinglyLinkedList<Integer> list = new MSinglyLinkedList<Integer>(
                random(10));
        System.out.println("list :" + list.toString() + "\\n" + "i ="
                + list.length());
        System.out.println("average  is :" + average(list));
    

    public static Integer[] random(int n) 
        Integer[] element = new Integer[n];
        for (int i = 0; i < n; i++) 
            element[i] = new Integer((int) (Math.random() * 100));
        
        return element;
    

    public static double average(MSinglyLinkedList<Integer> list) 
        if (list.isEmpty()) 
            throw new IllegalArgumentException("不能对空单链表计算平均值");
        
        int sum = 0, i = 0, max = Integer.MIN_VALUE, min = Integer.MAX_VALUE;
        Node<Integer> p = list.head.next;
        while (p != null) 
            int value = p.data.intValue();
            sum += value;
            if (value > max) 
                max = value;
            
            if (value < min) 
                min = value;
            
            p = p.next;
            i++;
        
        if (i == 1 || i == 2) 
            return (double) sum / i; //如果不超过两个数据,就不用去除最高分和最低分
        
        return (double) (sum - min - max) / (i - 2);//超过两个数据,就去除最高分和最低分
    



单链表的应用 2

用单链表求解约瑟夫环问题

package com.sshhsun.list;

//使用顺序表(或者单链表)解决约瑟夫问题
public class Josephus 

    public Josephus(int number, int start, int distance) 
        MSinglyLinkedList<String> list = new MSinglyLinkedList<String>(); // 使用单链表解决问题

        for (int i = 0; i < number; i++) 
            list.append((char) ('A' + i) + "");
        
        System.out.println("约瑟夫环(" + number + "," + start + "," + distance
                + ")");
        System.out.println(list.toString());
        int i = start;
        while (list.length() > 1) 
            i = (i + distance - 1) % list.length(); // 计数按循环规律变化,顺序表可看作是环形结构
            System.out.print("删除" + list.remove(i).toString() + " ,");
            System.out.println(list.toString());
        
        System.out.println("最后的人是" + list.get(0).toString());
    

    public static void main(String[] args) 
        new Josephus(5, 0, 3);
    


以上是关于线性表的链式存储的主要内容,如果未能解决你的问题,请参考以下文章

数据结构开发:线性表的链式存储结构

线性表的链式存储(C代码实现)

用C语言编写链式存储结构下实现线性表的创建,插入,删除,按值查找

线性表的顺序存储结构和链式存储结构

线性表的链式存储

线性表中的顺序存储与链式存储