Java实现线性表-顺序表示和链式表示

顺序表示和链式表示的比较:

1.读写方式:顺序表可以顺序存取,也可以随机存取;链表只能从表头顺序存取元素;

2.逻辑结构与物理结构:顺序存储时,逻辑上相邻的元素其对应的物理存储位置也相邻;链式存储时,逻辑上相邻的元素,其物理存储位置则不一定相邻;

3.查找、插入和删除操作:

  按值查找,当线性表在无序的情况下,两者的时间复杂度均为o(n);而当顺序表有序时,可采用折半查找,此时时间复杂度为o(log n);

  按位查找,顺序表支持随机访问,时间复杂度为o(1);而链表的平均时间复杂度为o(n)。

  顺序表的插入和删除操作平均需要移动半个表长的元素;链表的插入、删除操作时,只需修改相关节点的指针即可。

4.空间分配:顺序存储一般是基于静态存储分配,一单存储空间装满就不能扩充;链式存储的节点空间只有在需要的时候申请分配,只要内存有足够的空间即可分配。

顺序表示的实现:

public class ArrayList<E> {
    final int defaultSize=0;
    int maxSize;   //线性表的最大长度
    int length;  //线性表当前长度
    Object[] arrayList;   //存储线性表的数组

    /*
     * 构造函数
     */
    public ArrayList(int size){
        initList(size);
    }

        //按给定size初始化顺序表
    public void initList(int size) {
        if(size < 0){
            throw new RuntimeException("数组大小错误:" + size);
        }else{
            this.maxSize= size;
            this.length=0;
            this.arrayList = new Object[size];
        }
    }

         //表长
    public int length() {
        return length;
    }

        //按值查找
    public int locateElem(Object e) {
        for(int i=0 ;i<length;i++){
            if(arrayList[i] == e){
                return i;
            }
        }
        return -1;
    }

        //按位查找
    public Object getElem(int i) {
        if(i<0 || i>=length ){
            throw new RuntimeException("参数出错:"+i);
        }
        if(length ==0){
            throw new RuntimeException("顺序表为空");
        }
        return arrayList[i];
    }

        //插入
    public void insert(int i, Object e) {
        if(i<0 || i>length+1 ){
            throw new RuntimeException("新元素插入位置有误:"+i);
        }
        if(i >= maxSize){
            throw new RuntimeException("顺序表已满,不能再插入新的元素");
        }
        for(int j=length;j<i; j--){
            arrayList[j]=arrayList[j-1];
        }
        arrayList[i]=e;
        length++;
    }

        //删除
    public void delete(int i, Object e) {
        if(i<0 || i > length-1){
            throw new RuntimeException("需删除元素位置有误:"+i);
        }
        if(length == 0){
            throw new RuntimeException("顺序表为空,不能删除元素");
        }
        for(int j=i;j<length-1;j++){
            arrayList[j] = arrayList[j+1];
        }
        arrayList[length-1]="";
        length--;
    }

       //判空
    public boolean isEmpty() {
        return length==0 ? true : false;
    }

        //删除顺序表
    public void destroyList() {
        this.arrayList=null;
        this.length=0;
        this.maxSize=0;
    }
}

单链表表示的实现:

class Node<E>{
    E e;  //数据
    Node<E> next; //下一个节点

    Node(){}

    Node(E e){
        this.e = e;
        this.next = null;
    }
}

public class LinkedList<E> {
    private Node<E> header = null;   //头结点
    int size=0;     //链表大小

    public LinkedList() {
        this.header = new Node<E>();
    }

    //得到链表的长度
    public int length() {
        return size;
    }

    //按值查找节点,返回该节点的位置
    public int locateElem(E e) {
        Node<E> temp = header;
        int count = 1;
        while(temp.next != null && temp.e != e){
            temp = temp.next;
            count ++;
        }
        return count;
    }

    //找到第index个位置的节点
    public Node<E> getNode(int index) {
        if(index > size || index < 0){
            throw new RuntimeException("索引值有错:" + index);
        }
        Node<E> temp = new Node<E>();
        temp = header;
        int count=1;
        while(count != index){
            temp = temp.next;
            count ++;
        }
        return temp;
    }

    //尾添加
    public boolean addToLast(E e) {
        if(size == 0){
            header.e = e;
        }else{
            Node<E> newnode = new Node<E>(e);  //根据需要添加的内容封装为节点
            Node<E> last = getNode(size); //得到最后一个节点
            last.next = newnode;
        }
        size ++;
        return true;
    }

    //头添加
    public boolean addTofirst(E e) {
        if(size == 0){
            header.e = e;
        }else{
            Node<E> newnode = new Node<E>(e);  //根据需要添加的内容封装为节点
            newnode.next = header.next;
            header.next = newnode;
        }
        size ++;
        return true;
    }

    //插入到第index个的位置
    public boolean insert(int index, E e) {
        Node<E> newnode = new Node<E>(e);  //根据需要添加的内容封装为节点
        Node<E> cnode = getNode(index-1);  //得到第index-1个节点
        newnode.next = cnode.next;
        cnode.next = newnode;
        size++;
        return true;
    }

    //删除第index个节点
    public boolean delete(int index) {
        Node<E> prinode = getNode(index-1);  //得到被删除的节点的前一个节点
        Node<E> delnode = prinode.next;    //得到被删除的节点
        prinode.next = delnode.next;
        size --;
        return true;
    }

    //判空
    public boolean isEmpty() {
        return size==0 ? true : false;
    }

    public void destroyList() {
        header = null;
        size = 0;
    }

    //输出
    public String toString(){
        StringBuilder s = new StringBuilder("[");
        Node<E> temp = header;
        for(int i=0; i < size;i++){
            s.append(temp.e.toString()+" ");
            temp = temp.next;
        }
        s.append("]");
        return s.toString();
    }
}

双链表表示的实现

class TNode<E>{
    E e;
    TNode<E> prior, next;

    TNode(){}
    TNode(E e){
        this.e = e;
        prior = null;
        next = null;
    }
}

public class DoubleLinkedList<E> {
    private TNode<E> header = null;   //头结点
    int size=0;     //链表大小

    public DoubleLinkedList(){
        this.header = new TNode<E>();
    }

    //尾添加
    public boolean addToLast(E e) {
        if(size == 0){
            header.e = e;
        }else{
            TNode<E> TNode = new TNode<E>(e);  //根据需要添加的内容封装为节点
            TNode<E> last = getNode(size); //得到最后一个节点
            last.next = TNode;
            TNode.prior=last;
        }
        size ++;
        return true;
    }    

    //找到第index个位置的节点
    public TNode<E> getNode(int index){
        if(index > size || index < 0){
            throw new RuntimeException("索引值有错:" + index);
        }
        TNode<E> temp = new TNode<E>();
        temp = header;
        int count =1;
        while(count != index){
            temp = temp.next;
            count ++;
        }
        return temp;
    }

    //插入到第index个的位置
    public boolean insert(int index,E e){
        TNode<E> TNode = new TNode<E>(e);
        TNode<E> cnode = getNode(index-1); //找到第index-1个位置的节点
        TNode.next=cnode.next;
        TNode.prior = cnode;
        cnode.next.prior = TNode;
        cnode.next = TNode;
        size++;
        return true;
    }

    //删除第index个节点
    public boolean delete(int index){
        TNode<E> delnode = getNode(index);
        delnode.prior.next=delnode.next;
        delnode.next.prior= delnode.prior;
        size--;
        return true;
    }
}
时间: 2024-08-05 03:22:05

Java实现线性表-顺序表示和链式表示的相关文章

数据结构Java实现05----栈:顺序栈和链式堆栈

数据结构Java实现05----栈:顺序栈和链式堆栈 一.堆栈的基本概念: 堆栈(也简称作栈)是一种特殊的线性表,堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置进行插入和删除操作,而堆栈只允许在固定一端进行插入和删除操作. 先进后出:堆栈中允许进行插入和删除操作的一端称为栈顶,另一端称为栈底.堆栈的插入和删除操作通常称为进栈或入栈,堆栈的删除操作通常称为出栈或退栈. 备注:栈本身就是一个线性表,所以我们之前讨论过线性表的顺序存储和链式存储,对于栈来说,同样适

2、线性表的实现:链式存储、单链表

1 package ren.laughing.datastructure.baseImpl; 2 3 import ren.laughing.datastructure.base.List; 4 import ren.laughing.datastructure.base.Strategy; 5 import ren.laughing.datastructure.exception.OutOfBoundaryException; 6 /** 7 * 线性表的实现:链式存储结构:单链表 8 * @

数据结构导论 四 线性表的顺序存储VS链式存储

前几章已经介绍到了顺序存储.链式存储 顺序存储:初始化.插入.删除.定位 链式存储:初始化.插入.删除.定位 顺序存储:初始化 strudt student{ int ID://ID char name[30];//姓名 char sex; //性别 int class;//班级 int age;//年龄 } student={"01",“zhangsan”,"m","201","20"}: 链式存储:初始化 //建立一个空链

数据结构学习笔记(二) 线性表的顺序存储和链式存储

线性表:由同类型数据元素构成有序序列的线性结构 -->表中元素的个数称为线性表的长度 -->没有元素时,成为空表 -->表起始位置称表头,表结束位置称表尾 顺序存储: 1 package test; 2 3 /** 4 * 线性表(数组) 5 * 6 */ 7 public class Test { 8 private static int m ; 9 private static int[] a; 10 public static void main(String[] args) {

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

顺序存储是分配了一块连续的内存,把这块内存平均分为N份,每份存放一个线性表的单元.从内存利用角度讲,顺序存储需要的是一块连续的内存.特点是查找节点容易,插入. 删除节点比较耗时. 链式存储是分配了几个零散的非连续单元,从内存利用角度讲,它能充分利用那些碎片化的内存.特点是查找节点慢,但插入删除节点快. 怎么理解呢? 下文说的酒店均没有客户记录,就是没有登记某个人住在某个房间. 顺序存储就和某个酒店的一层房间,比如在第一层有100个房间,从1号房间按顺序一致排到底100号房间.你去找一个人,打开1

串的数据结构表——顺序串与链式串

串的结构类似与线性表,只不过串的数据元素是一个字符,即是由零个或多个字符组成的有限序列. 一.串的顺序存储 串的顺序存储结构也就是顺序存储,即串中的字符被依次的存在一组连续的存储单元中,可以类比线性表的顺序存储,可以写出其数据结构如下: typedef struct st { char *ch; //串存放的起始地址,串中第i个字符存储在ch[i-1]中 int length; //串的长度 int strsize; //分配的存储空间的大小,如果不足,在通过realloc()分配增加空间 }s

c数据结构 -- 线性表之 复杂的链式存储结构

复杂的链式存储结构 循环链表 定义:是一种头尾相接的链表(即表中最后一个结点的指针域指向头结点,整个链表形成一个环) 优点:从表中任一节点出发均可找到表中其他结点 注意:涉及遍历操作时,终止条件是判断 p->next == L? 双向链表 定义:在单链表的每个结点离再增加一个指向直接前驱的指针域 prior,这样链表中就形成了有 两个方向不用的链,故称为双向链表 双向循环链表 定义: 和单链的循环表类似,双向链表也可以有循环表 ·让头节点的前驱指针指向链表的最后一个结点 ·让最后一个结点的后继指

栈:顺序栈和链式堆栈

一.堆栈的基本概念: 堆栈(也简称作栈)是一种特殊的线性表,堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置进行插入和删除操作,而堆栈只允许在固定一端进行插入和删除操作. 先进后出:堆栈中允许进行插入和删除操作的一端称为栈顶,另一端称为栈底.堆栈的插入和删除操作通常称为进栈或入栈,堆栈的删除操作通常称为出栈或退栈. 备注:栈本身就是一个线性表,所以我们之前讨论过线性表的顺序存储和链式存储,对于栈来说,同样适用. 二.堆栈的抽象数据类型: 数据集合: 堆栈的数据

数据结构----线性表顺序和链式结构的使用(c)

PS:在学习数据结构之前,我相信很多博友也都学习过一些语言,比如说java,c语言,c++,web等,我们之前用的一些方法大都是封装好的,就java而言,里面使用了大量的封装好的方法,一些算法也大都写好了,java还有三个特性,封装.继承.多态.当然这里不是讲Java,这里主要是说内部结构,大家都知道数据结构有些东西是分为逻辑结构和物理结构的,物理结构有分为顺序结构和链式结构,有不懂得可以百度百科,这里主要是分享线性表的顺序结构.那么什么是线性表呢,线性表是最基本.最简单.也是最常用的一种数据结