信管的数据结构讲的太水了,遂重学(看的网课:恋上数据结构与算法,讲的very good),为算法学习打基础(都大三了还在打基础),顺便在leetcode上跟进一些相关的题,记录在这里,这里最方便复习
另一方面发现未来的考试题,除了算法题之外,比较基础的题(对基本数据结构的各种操作),也占了可观的一部分
最后,顺便新入门了java语言,相比C++,java在写算法和数据结构这方面还是方便太多了,比如自动回收机制,但是另一方面java对基础数据类型是值传递,而对其他数据类型就都是地址传递,而且指针在代码里体现的也很不明显,反倒让我容易混淆,但是熟悉了之后发现对于一点没学过指针的人,java真是太友好了(于是很快就把C里关于指针的操作忘光了,而且后面发现考试填代码块都是用C,于是又换回C++实现了)
public class ArrayListIntZH {
//index指数组的元素下标,而不是第几个元素(麻烦+1)
//size指数组当前元素个数
private int[] elements;
private int size;//定义全局变量(不在函数里的)不初始化默认初始值为0,局部变量则初始值随机
private static final int DEFAULT_CAPACITY = 10;
private static final int ELEMENT_NOT_FOUND = -1;
//自定义数组(线性表)长度构造函数
public ArrayListIntZH(int capacity){
if (capacity<10){
capacity = 10;
}
//new是向堆空间申请内存,返回的是内存地址
elements = new int[capacity];
}
//函数重载,非自定义数组长度则默认长度为10
public ArrayListIntZH(){
elements = new int[DEFAULT_CAPACITY];
}
//返回数组当前元素个数
public int size(){
return size;
}
//清空线性表
//理解这个清空为什么是size=0很关键,虽然内在数据没被删,但是我们也访问不了了,直接在原有数组上覆盖改写
public void clear(){
size = 0;
}
//添加元素到线性表末端,这里直接调用后面一个更高级的add
public void add(int element){
add(size,element);
}
//这里是扩容函数,实现了插入时动态数组可以自动扩容
private void ifNeedEnLarge(int needCapacity){
int oldcapacity = elements.length;
if (needCapacity<=oldcapacity){
return;
}else{
int newcapacity = oldcapacity*2;
//默认扩容后的容量是旧容量的2倍
int[] newElements = new int[newcapacity];
for (int i=0;i<size;i++){
newElements[i]=elements[i];
}
elements = newElements;
System.out.println("enLarge Success"+" newCapacity = "+newcapacity);
}
}
//在固定位置添加元素,若超出size则扩容
public void add(int index, int element){
if(index<0||index>size){
throw new IndexOutOfBoundsException("Index="+index+"but,size="+size);
}
ifNeedEnLarge(size+1);
for (int i = size-1;i>=index;i--){
elements[i+1]=elements[i];
}
elements[index]=element;
size++;
}
//移除固定位置元素
//被删元素后面依次向前覆盖,最后一个元素覆盖到倒数第二个元素,直接size就行,不用单独释放最后一个元素
public void remove(int index){
if(index<0||index>size-1){
throw new IndexOutOfBoundsException("Index="+index+"but,size="+size);
}//当给出的index不在合理范围内时,抛出一个错误提示,很严谨,参数是index的都要有这步
//注意for循环的判断条件,当i<n成为判断条件时,i到n就不会执行下面了,下面执行的最多只到n-1
//比如下面我们想让size-1的覆盖size-2的,那么就要让i最大执行时等于size-1,即i小于size
for (int i = index + 1; i<size;i++ ){
elements[i-1]=elements[i];
}
size--;//注意不要总把循环结束后的语句写到循环里面去啊啊啊啊
}
//返回是否线性表为空
public boolean isEmpty(){
return size==0;
}
//返回线性表是否包含某特定元素
public boolean contains(int element){
for (int i=0;i<size-1;i++){
if (elements[i] == element){
return true;
}
}
return false;
}
// 返回线性表的固定位置元素
public int get(int index){
if(index<0||index>size-1){
throw new IndexOutOfBoundsException("Index="+index+"but,size="+size);
}//当给出的index不在合理范围内时,抛出一个错误提示,很严谨,参数是index的都要有这步
return elements[index];
}
//改变线性表的固定位置元素
public void set(int index,int element){
if(index<0||index>size-1){
throw new IndexOutOfBoundsException("Index="+index+"but,size="+size);
}//当给出的index不在合理范围内时,抛出一个错误提示,很严谨,参数是index的都要有这步
elements[index] = element;
}
//返回线性表特定元素的位置
public int indexOf(int element){
for (int i = 0; i<size-1;i++){
if (elements[i]==element){
return i;
}
}
return ELEMENT_NOT_FOUND;
}
//自定义打印数组,返回是string类型,这里StringBuilder
public String arrayPrint(){
//这里用了stringBuilder类,一看就明白应该
//打印样例:size=10 [1,2,3,4,5,6,7,8,9,10]
StringBuilder string = new StringBuilder();
string.append("size = ").append(size).append(" ").append("[");
for (int i = 0; i<size-1; i++ ){
if (i!=size-1) {
string.append(elements[i]).append(",");
}
}
string.append(elements[size-1]).append("]");
return string.toString();
//这里是因为在这里面string是stringbuilder类的对象,不是string类的,不能作为返回值,所以事先转换一下
}
}