Java: Iterable() 和 Iterator() 的区别+顺序表的遍历,更改容量

学算法与数据结构遇到:

我要用hasNext()  和 Next(), 就需要先实现接口Iterable(),就能调用这两个Iterator方法

但是我在想实现了Iterator也可以使用这两个方法()

原因:用Iterable(), 每次调用返回一个从头开始的迭代器。

用Iterator(), 它的迭代器依赖于hasNext()  和 Next()的当前位置,在不同的方法间传递,Next()的位置变得不可知。

查了一下泛型:将操作的数据类型制定为一个参数。

用泛型方法就可以接收不同类型的参数,然后泛型编译之后就不存在了。

//用泛型(将操作的数据定义为一个参数),接收不同的数据类型
public class SequenceListDemo<T> implements Iterable<T>{
}
构造器,申请空间
public SequenceListDemo(int Capacity) {
        this.List = (T[])new Object[Capacity];
        N = 0;
    }
定义操作顺序表的方法
//置空
    public void clear(){
        N = 0;
        //List[0] = null;
    }
    //得到长度
    public int getLength(){
        return (N);
    }
    //判断是否为空
    public boolean isNull(){
        return N==0;
    }
    //添加,从尾部
    public void Add(T t){
        List[N++] = t;
        System.out.println("元素"+t+"已加入");
    }
    //位置i,添加元素t
    public int add_locai(int i, T t){//添加前判断:是否满,位置是否合理
        if (i== List.length){
            System.out.println("插入失败,已满");
            return -1;
        }
        if (i<0 || i>N){
            System.out.println("插入位置错误");
            return -1;
        }
        //从i位置开始元素,往后移
        for (int j=List.length;j>i;j--){
            List[j] = List[j-1];
        }
        List[i] = t;
        N++;
        return 0;
    }
    //删除制定位置i的,最后返回该元素
    public T dele_locai(int i){
        if (i<0 || i>N){
            System.out.println("位置不合理(不在 [0,N))");
        }
        T dele_i;
        dele_i = List[i];  //取出位置i的
        for (int j=i; j<List.length; j++){
            List[j] = List[j+1];
        }
        N--;
        return dele_i;
    }
    //查看元素t第一次出现的位置i
    public int SearFirPlaOf_t(T t){
        int location;
        for (int j=0; j<=N; j++){
            if (List[j]==t){
                location = j;
                return location;
            }// System.out.println("List["+j+"]:"+List[j]+" ");
        }
        return -1;
    }
    //打印所有元素
    public void Pri_List(){
        for (int List_i=0; List_i<=N; List_i++){
            System.out.println("List["+List_i+"]:"+List[List_i]+" ");
        }
    }

最后测试

class Test{
    public static void main(String[] args) {
        SequenceListDemo<Integer> List = new SequenceListDemo<>(20);//创建顺序表,容量10,类型Integer
        List.Add(1);
        List.Add(10);
        List.Add(1548);
        List.Add(50499);
        List.Add(3);

        List.Pri_List();
        List.clear();
        System.out.println("----------");
        List.Pri_List();
    }
}

结果:

 所以我把删除方法加了一行

List[0] = null;

对顺序表的改进,可以在删除操作,和添加操作后面,加上对元素容量的判断。

删除后,长度变小,如果小于容量的1/4,减小容量,容量变成原来的1/2

添加元素后,长度增加,如果长度大于容量的1/2,增大容量,将容量扩增一倍。

这样虽然可以改善部分顺序表占固定内存的缺点,但是就算每次容量计算后增加,减少,也是总会占用内存而不使用。并且每次改变内存的时候,也会使用资源,来创建一个辅助集合。

所以我觉得这个改进比较鸡肋,但是思想可以学一下。

代码如下:

  //添加,从尾部
    public void Add(T t){
        List[N++] = t;
        System.out.println("元素"+t+"已加入");
        if (N>List.length*1/2){
            setCapacity(List.length*2);
        }
        System.out.println(
                List.length
        );
    }
    //位置i,添加元素t,添加后大于1/2,扩容
    public int add_locai(int i, T t){//添加前判断:是否满,位置是否合理
        if (i== List.length){
            System.out.println("插入失败,已满");
            return -1;
        }
        if (i<0 || i>N){
            System.out.println("插入位置错误");
            return -1;
        }
        //从i位置开始元素,往后移
        for (int j=List.length;j>i;j--){
            List[j] = List[j-1];
        }
        List[i] = t;
        N++;
        if (N>List.length*1/2){
            setCapacity(List.length*2);
        }
        return 0;
    }
    //删除制定位置i的,最后返回该元素,发现删除之后小于总容量的1/4,减容
    public T dele_locai(int i){
        if (i<0 || i>N){
            System.out.println("位置不合理(不在 [0,N))");
        }
        T dele_i;
        dele_i = List[i];  //取出位置i的
        for (int j=i; j<N; j++){
            List[j] = List[j+1];
        }
        N--;
        if(N>0&&N<(int)((double)List.length/4)){
            setCapacity(1/2 * List.length);
        }
        return dele_i;
    }

猜你喜欢

转载自blog.csdn.net/qq_54508596/article/details/126236710
今日推荐