数据结构与算法-线性表

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法-线性表相关的知识,希望对你有一定的参考价值。

近期在学习数据结构,反反复复已经看过几遍了,也做了一些练习题,但总感觉不记录一下,思路就不是很清晰,所以,从今天开始总结这段时间对数据结构的学习。

 

无论学习什么,基础知识都是最总要的,数据结构也不例外。线性表就是数据结构的基础,很多常见的数据结构都是基于线性表来实现的。

 

那么,什么是线性表呢?官方的定义是:

  零个或多个数据元素的有限序列

 

可以从两个方面来理解线性表,首先它是一个序列,也就是其中的元素有先后顺序,其次是有限的,对于无线数列,也只能存在于理论数学中。

 

说了这么多,小结一下:

  1)线性表是数据结构中的基础,它是零个或多个数据元素的有限序列。

      2)线性表中头结点没有直接前驱节点

      3)线性表中尾节点没有直接后继节点

      4)线性表中节点的类型相同

 

每种数据结构都有与之对应的操作,线性表的基本操作包括:初始化、获取长度、是否为空、获取节点、添加节点、删除节点。

线性表包括两种存储方式,一种是顺序存储,一种是链式存储。下面就分别用这两种结构实现线性表的基本操作。

 

线性表的顺序存储:

 1 public class ArrayLineTable<E> {
 2 
 3     private E[] datas;
 4     private int maxSize;
 5     private int size;
 6     
 7     //初始化
 8     public ArrayLineTable(int maxSize){
 9         datas = (E[])new Object[maxSize];
10         this.maxSize = maxSize;
11         this.size = 0;
12     }
13     
14     public ArrayLineTable(){
15         this(10);
16     }
17     
18     
19     //添加元素:向最后添加
20     public void add(E value){
21         //判断线性表是否已满
22         if(this.size == maxSize) {
23             throw new RuntimeException("线性表已满");
24         }
25         datas[size] = value;
26         this.size ++;
27     }
28     
29     public void add(int index, E value) {
30         if(this.size == maxSize){
31             throw new RuntimeException("线性表已满");
32         }
33         
34         if(index < 0 || index >= datas.length - 1){
35             throw new RuntimeException("索引错误");
36         }
37         
38         //移动元素
39         for(int i = datas.length- 1; i <= index; i --) {
40             datas[i + 1] = datas[i];
41         }
42         
43         datas[index] = value;
44         this.size ++;
45     }
46     
47     
48     //删除
49     public void delete(int index) {
50         
51         if(this.size == 0) {
52             throw new RuntimeException("线性表为空");
53         }
54         
55         if(index < 0 || index > datas.length - 1){
56             throw new RuntimeException("索引错误");
57         }
58         
59         for(int i = index; i < datas.length - 1; i ++) {
60             datas[i] = datas[i + 1];
61         }
62         this.size --;
63     }
64     
65     //查询
66     public E get(int index) {
67         if(this.size == 0){
68             throw new RuntimeException("线性表为空");
69         }
70         
71         if(index < 0 || index > datas.length - 1){
72             throw new RuntimeException("索引错误");
73         }
74         
75         return datas[index];
76     }
77 }

 

线性表的连式存储:

public class LinkedLineTable<E> {

    
    private Node<E> head;
    private int size;
    
    //初始化
    public LinkedLineTable(){
        this.head = new Node<E>(null, null);
    }
    
    
    //在链表的末尾添加元素
    public void add(E data){
        
        Node<E> temp = head;
        //遍历到最后一个节点
        while(temp.next != null){
            temp = temp.next;
        }
        
        //创建新的节点
        Node<E> newNode = new Node<E>(data, null);
        temp.next = newNode;
    
        this.size ++;
    }
    
    
    //在指定为位置添加节点
    public void add(E data, int index){
        
        int counter = 0;
        Node<E> temp = head.next;
        while(temp.next != null && counter < index - 1){
            temp = temp.next;
            counter ++;
        }
        
        //遍历到index位置的前一个节点
        //创建一个新的节点
        Node<E> node = new Node<E>(data, null);
        
        node.next = temp.next;
        temp.next = node;
        
        this.size ++;
    }
    
    //删除指定位置上的元素
    public void delete(int index){
        
        if(head.next == null){
            throw new RuntimeException("线性表为空");
        }
        
        if(index >= this.size){
            throw new RuntimeException("索引错误");
        }
        
        int counter = 0;
        Node<E> temp = head.next;
        while(temp.next != null && counter < index - 1){
            temp = temp.next;
            counter ++;
        }
        
        //遍历到index的前一个位置
        //删除index上的节点
        Node<E> delNode = temp.next;
        temp.next = delNode.next;
        delNode.next = null;
        this.size --;
        
        
    }
    
    
    //获取指定位置上的元素
    public E get(int index) {
        
        Node<E> temp = head.next;
        int counter = 0;
        while(temp.next != null && counter < index){
            temp = temp.next;
            counter ++;
        }
        return temp.data;
        
    }
    
    
    
    //打印链表中的值
    public void display(){
        
        Node<E> temp = head.next;
        while(temp != null){
            System.out.print(temp.data + " ");
            temp = temp.next;
        }
        
        System.out.println();
    }
    
    
    private static class Node<T>{
        private T data;
        private Node<T> next;
        
        public Node(T data, Node<T> next){
            this.data = data;
            this.next = next;
        }
    }
}

 

循环链表的实现:

/**
 * Created by Administrator on 2017/5/25.
 */

//循环链表的实现:带有头结点的实现
public class CircleLinkedLineList<E> {


    private Node<E> head;
    //private Node<E> tail;
    private int size;

    //初始化
    public CircleLinkedLineList(){
        this.head = new Node<E>(null, null);
        //tail = head;
        this.head.next = head;

        this.size = 0;
    }


    //尾部添加节点
    public void add(E data){

        //创建新的节点
        Node<E> newNode = new Node<E>(data, null);

        //第一次添加节点
        if(this.head.next == this.head){
            this.head.next = newNode;
            newNode.next = head;

        }else{

            Node<E> temp = head;
            while(temp.next != head){
                temp = temp.next;
            }

            temp.next = newNode;
            newNode.next = head;

        }

        this.size ++;
    }

    //删除链表中的节点
    public void delete(E data){
        Node<E> temp = this.head;

        while(temp.next != head){
            if(temp.next.data.equals(data)){
                Node<E> delNode = temp.next;

                temp.next = delNode.next;
                delNode.next = null;

                this.size --;
            }else{
                temp = temp.next;
            }
        }
    }

    public Node<E> get(int i){
        if(i <= 0 || i >size){
            throw new RuntimeException("索引位置错误");
        }

        Node<E> newNode = new Node<E>(null, null);
        int count = 0;
        Node<E> temp = head;
        while(temp.next != head){

            if(count == i){
                newNode.data = temp.next.data;

            }
            temp = temp.next;
            count ++;

        }
        return newNode;
    }

    //判断链表中是否存在某个元素
    public boolean isContain(E data){
        Node<E> temp = head;

        while(temp.next != head){
            if(temp.next.data.equals(data)){
                return true;
            }
            temp = temp.next;
        }

        return false;
    }



    private static class Node<T> {
        private T data;
        private Node<T> next;

        public Node(T data, Node<T> next){
            this.data = data;
            this.next = next;
        }
    }
}

 

以上是关于数据结构与算法-线性表的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法-线性表之双向链表

顺序表——“数据结构与算法”

数据结构与算法全套数据结构笔记持续更新

数据结构与算法全套数据结构笔记持续更新

数据结构与算法分析(线性表实现)

数据结构与算法学习笔记:线性表Ⅰ