• 基于数组的容器类实现 和 基于链表结构的容器类实现


    1. 数据结构
      概念 :数据结构是计算机存储、组织数据的方式。   简单理解:可以看成是对数据存储的一种方式
         

      常见的数据结构:
              数组
              链表:  一种动态的线性的数据结构  ,   优点: 动态创建,节省空间,头部添加容易 ,     缺点:空间上不连续,查找困难。只能从头开始一个一个找

              队列:FIFO 先进先出原则

              堆栈:FILO 先进后出原则
       面试题:

           1. 数组结构和链表结构的区别?        两种数据结构都是线性表

            数组 :查找快   删除 添加比较慢,一旦初始化长度固定,而且连续有序的一片内存空间。

            链表:增删改快 查找慢,将在内存中零散 随机的一些对象通过对象的引用将所有对象的连接起来。  

              1.从逻辑结构角度来看:
                a, 数组必须事先定义长度(元素个数),不能适应数据动态地增减的情况。当数据增加时,可能超出原先定义的元素个数;当数据减少时,造成内存浪费。 

                b,链表动态地进行存储分配,可以适应数据动态地增减的情况,且可以方便地插入、删除数据项。(数组中插入、删除数据项时,需要移动其它数据项)

              2.从时间复杂度看:
                数组利用下标定位,时间复杂度为O(1),链表定位元素时间复杂度O(n);
                数组插入或删除元素的时间复杂度O(n),链表的时间复杂度O(1)。

                1.数组类型的容器是怎么实现的?
                2.链表类型的容器是怎么实现的?
                3.区别:
                  增加和删除 链表结构效率比较快,修改和查询,数组结构的效率比较快

             


      存储方式   :

        1.变量
           2.数组
        3.自定义容器

    2.  基于数组的容器类实现  

    package 基于数组的容器类实现;
    
    import java.util.Arrays;
    
    public class Container {
        private int num = 0;     //容器类保存元素的个数
        private Object [] contain; //定义个保存任何类型的容器
    //    无参的构造方法
        public Container(){
            this(5);
        }
    //有参的构造方法
        public Container(int length){
            this.contain  = new Object[length];
        }
    //获取容器元素个数
        public int getNum(){
            return num;
        }
    //给容器添加元素
        public void add(Object value){
      //if(firstIndex(value)==-1){} 用于去除重复元素
    if(num == this.contain.length){ Object[] temp = new Object[this.contain.length*2]; //扩容 System.arraycopy(contain, 0, temp, 0, num); this.contain = temp; } contain[num] = value; num++; } //重写toString 方法 public String toString(){ Object[] temp =Arrays.copyOf(contain, num); return Arrays.toString(temp); } //容器的其他方法 //1.根据下标获取元素 public Object getElementByIndex(int index){ if(index>=0 && index<num){ return contain[index]; } return -1; } //2.获取元素第一次出现的位置的下标 public int firstIndex(Object obj){ for (int i = 0; i < contain.length; i++) { if(obj.equals(contain[i])){ return i; } } return -1; } //3.通过指定出现的次数,查找指定元素的下标 public int indexOf(Object obj,int count){ for (int i = 0; i < contain.length; i++) { if(obj.equals(this.contain[i])){ count--; if(count==0){ return i; } } } return -1; } //4.指定索引 删除对应位置上的元素 public void delete(int index){ if(index>=0 && index<num){ this.contain[index] = null; //将null值后的所有元素依次向前移一位 for (int i = index; i < contain.length-1; i++) { this.contain[i] = this.contain[i+1]; } Object[] temp = new Object[num]; temp = Arrays.copyOf(contain,temp.length-1); this.contain = temp; num--; } } //5.删除 第一次出现 的指定元素 public void deleteFirstElement(Object obj){ if(firstIndex(obj) != -1){ delete(firstIndex(obj)); } } //6.删除 所有的指定元素 核心思想:永远删除的是第一个元素,直到容器中没有该指定元素(返回负数) public void deleteElement(Object obj){ while(firstIndex(obj) != -1){ delete(firstIndex(obj)); } } //7.删除 所有元素 public void empty(){ this.num = 0; Arrays.fill(contain, null); } }

    3.基于链表结构的容器类实现

    package 基于链表的容器类实现;
    /*
     * 容器类: 保存 :1. 第一个节点的引用(地址),根据这个地址能够找到下一个节点。
     *               2. 节点的个数。
     */
    public class LinkList {
        private Node first;
        private int size;
        //容器类添加元素的方法
        public void add(Object obj){
            //1. 将要添加的元素封装到 节点类中、
            Node ele = new Node(obj);
            //2.当first引用为null时,直接将first指向 上面创建的ele对象(里面保存了要添加的元素)。
            //  当first引用指向了 一个Node类中的对象,先将first引用保存到Node类中temp这个引用变量(相当于获取了第一个节点)。
            //然后通过while循环判断temp.getNext(),即这个对象的下一个引用节点是否为null,如果不为空,将 temp.getNext()赋给temp,继续循环判断。
            // 直到节点的  next引用 为null时,ele对象保存的下一个引用节点中。 外围 size++
            if (first == null) {
                first = ele;
            }else{
                Node temp = first; //获取第一个节点
                while(temp.getNext() != null){
                    temp = temp.getNext();
                }
                temp.setNext(ele);
            }
            size++;
        }
    //重写toString方法,打印容器类的所有元素
        public String toString(){
            StringBuffer sb = new StringBuffer("[");
            Node temp = first;
            while(temp.getNext()!=null){
                sb.append(temp.getObj()+"  ");
                temp = temp.getNext();
            }
            sb.append(temp.getObj()+"]");
            return sb.toString();
        }
    }
    package 基于链表的容器类实现;
    /**
     * 节点类:保存  节点数据元素  和   下一个节点的引用。
     *作用:我想再强调一下数据结构的作用是为数据寻找一个合适的载体,让数据的操作更加快捷。
            Node只不过是一个辅助工具,并不会暴露在外。它与数据相对应,又使数据按链式排布,
            操纵节点也就等于操纵数据,就像提线木偶,我们操作的是"观众"所看不见的线,而不是木偶的各个肢体本身
     */
    public class Node {
        private Object obj;  //节点数据元素
        private Node next;   //下一个节点的引用(地址)
        
    //setter/getter方法    
        public Object getObj() {
            return obj;
        }
        public void setObj(Object obj) {
            this.obj = obj;
        }
        public Node getNext() {
            return next;
        }
        public void setNext(Node next) {
            this.next = next;
        }
    
    //有参的构造方法,给节点元素赋值。
        public Node(Object obj){
            this.obj = obj;
        }
    }
  • 相关阅读:
    Flexigrid在IE下不显示数据的处理
    [置顶] ios 网页中图片点击放大效果demo
    WPF仿360卫士9.0界面设计
    Android调用相机并将照片存储到sd卡上
    Android 将文件保存到SD卡,从卡中取文件,及删除文件
    java 正则表达式学习
    linux下的块设备驱动(一)
    已知用经纬度表示的两点,求两点之间的直线距离
    IndiaHacks 2016
    IndiaHacks 2016
  • 原文地址:https://www.cnblogs.com/gshao/p/10105734.html
Copyright © 2020-2023  润新知