线性表

线性表及其基本操作

  1. 线性表的定义:一个线性表(LinearList)是由n(n≥0)个数据元素(结点)所构成的有限序列。线性表逻辑地表示为:(a0,a1,…,an-1)。其中,n为线性表的长度,n=0时为空表。称i为ai在线性表中的位序号。

  2. 线性表的结构特点
    a)它由n个同类型的元素组成;
    b) 有且仅有一个第一个元素和最后一个元素;
    c) 每个元素除第一个元素和最后一个元素之外,有且仅有一个前驱和一个后继。

  3. 基本操作
    a) Clear();
    b) isEmpty();
    c) length();
    d) get(i);
    e) insert(I,x);
    f) remove(i);
    g) indexOf(x);
    h) display();
  4. 线性表抽象数据类型的Java接口描述
public interface IList(){
    public void clear();
    public BooleanisEmpty();
    public int length();
    public Object get(int i);
    public void insert(int i,Object x);
    public void remove(int i);
    public int indexOf(Object x);
    public void display();
}

线性表的顺序存储及其实现

  1. 顺序存储:用一组地址连续的存储单元 依次存放 线性表中的数据元素的存储结构。

这里写图片描述


2.顺序表的存储:

这里写图片描述

3.实现

    public class SqList implements IList {
    private Object[] listElem; 
    private int curLen; 
    //构造一个容量为maxSize的空顺序表函数      
    public SqList (int maxSize) { 
         curLen = 0; 
         listElem = new Object[maxSize];
    }
    // 顺序表置空函数
   public void clear( ) {
    curLen = 0; 
   }
     // 判空函数
    public boolean isEmpty( ) {
        return curLen == 0;
    }
    //求线性表的数据元素并返回其值
    public int length(){
        return curLen;
    }
    //读取线性表第i个元素的值
    public Object get(int i) throws Exception{
        if(i<0||i>curLen-1)
            throw new Exception("元素不存在");
        return listElem[i];
    }
    //在线性表的第i位置插入值x
    public void insert(int i,Object x) throws Exception{
        //判断顺序表是否满
        if(curLen==listElem.length)
            throw new Exception("顺序表已经满");  
        if(i<0||i>curLen)
            throw new Exception("插入位置不合法");
        for(int j=curLen ;j>i;j--)
            listElem[j]=listElem[j-1];
        listElem[i]=x;
        curLen++;   
    }
    //删除指定位置的元素
    public void remove(int i )throws Exception{
        if(i<0||i>curLen)
            throw new Exception("删除位置不合法");
        for(int j = i;j<curLen-1;j++){
            listElem[j]=listElem[j+1];
        }
        curLen--;
    }

    //顺序表的查找操作,返回相应的下标
    public int index(Object x){
        int j =0;
        while(j<curLen&&listElem[j].equals(x){
            j++;
        }

        if(j<curLen)
            return j;
        else 
            return -1;
    }
    //输出顺序表的数据元素
    public void display(){
        for(int j =0;j<curLen;j++){
            system.out.print(listElem[i]+" ");
        }
    }
}

线性表的链式存储及其实现

单链表

  1. 单链表的表示
    a. 用一组 地址任意的存储单元存放线性表中的数据元素。
    b. 以元素 (数据元素的映象) + 指针 (指示后继元素存储位置)= 结点 (表示数据元素 或 数据元素的映象)
    c. 以“结点的序列”表示线性表  称作链表

以线性表中第一个数据元素a0的存储地址作为线性表的地址,称作线性表的头指针。

这里写图片描述


有时为了操作方便,在第一个结点(首结点)之前虚加一个“头结点”,以指向头结点的指针为链表的头指针。
这里写图片描述

2.结点类的描述
这里写图片描述

public class Node{
    public Object data;
    public Node next;
    public Node(){
        this(null,null);
    }   
    public Node(Object data){
        this(data,null);
    }
    public Node(Object data,Node next){
        this.data=data;
        this.next=next;
    }
}


单链表类的描述

    public class LinkList implements IList{
        public Node head;  //单链表的头结点
        public LinkList(){
            head  = new Node();//初始化头节点空
        }
        //构造一个长度为n的单链表
        public LinkList(int n,boolean order ) throws Exception{
            this();//初始化头结点
            if(order)
                create1(n);//尾插法建立单链表
            else
                create2(n);//头插法建立单链表
        }

        //尾插法建立单链表
        public void create1(n) throws Exception{
            Scanner sc = new Scanner(System.in);
            for(int j =0;j<n;j++)
                insert(length(),sc.next());
        }

        //头插法建立单链表
        public void create2(n) throws Exception{
            Scanner sc = new Scanner(System.in);
            for(int j =0;j<n;j++)
                insert(0,sc.next());//生成新结点,插入到表头
        }
        //按位序号查找
        public Object get(int i ) throws Exception{
            Node p = head.next;
            int j =0;
            while(p!=null&&j<i){
                p=p.next;
                j++;
            }
            if(j>i||p==null)
                throw new Exception("元素部存在");
            return p.data;

        }

        //按值查找
        public int indexOf(Object x){
            Node p = head.next;
            int j =0;
            while(p!=null&&!p.equals(x){
                p=p.next;
                j++;
            }
            if(p!=null)
                return j;
            else 
                return -1;
        }

        //带头结点的单链表插入
        public void insert(int i,Object x) throws Exception{
            Node p = head.next;
            int j =-1;
            while(p!=null&&j<i-1){//寻找第i个结点的前驱
                p=p.next;
                j++;
            }
            if(j>i-1||p==null)
                throw new Exception("插入位置不合法");
            Node s = new Node(x);
            s.next = p.next;
            p.next = s;
        }
        //不带头结点的插入操作
        public void insert2(int i , Object x) throws Exception{
            Node p = head;
            int j =0;
            while(p!=null&&j<i-1){
                p = p.next;
                ++j;
            }
            if(j>i-1||p==null)
                throw new Exception("插入位置不合法");
            Node s = new Node(x);
            if(i==0){//插入位置为表头时
                s.next = head;
                head = s;
            }
            else{
                s.next = p.next;
                p.next = s;
            }
        }

        //删除操作
        public void remove(int i )throws Exception{
            Node p = head.next;
            int j =-1;
            while(p!=null&&j<i-1){
                p = p.next;
                j++;
            }
            if(p==null||j>i-1)
                throw new Exception("删除位置不合法");
            p.next = p.next.next;
        }

        //置空
        public void clear(){
            head.data=null;
            head.next=null;
        }
        //判断带头结点的单链表是否为空
        public boolean isEmpty(){
            return head.next == null;
        }
        //带头结点的单链表的长度
        public int length(){
            int length = 0;
            Node p = head.next;
            while(p!=null){
                length++;
                p=p.next;
            }
            return length;
        }

        //输出所有单链表的所有结点
        public void diplay(){
            Node p = head.next;
            while(p!=null){
                System.out.print(p.data+" ");
                p=p.next;
            }
            System.out.print();
        }


    }

顺序存储与链式存储的比较

.顺序表链表
空间大小相对稳定可根据需要进行动态变化,较灵活
存储密度较高(只存放数据元素值本身较低(除存放数据元素值本身之外,还存放指针)
创建简单(利用数组)较复杂(头、尾插法)
存储操作简单(随机存取)较复杂(顺序存取)
插入操作不方便(会引起元素移动)方便(只要修改相关链)
删除操作不方便(会引起元素移动)方便(只要修改相关链)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值