目录
一.数据结构概述
1.数据结构是程序的组成部分:
数据结构 + 算法 = 程序
2.数据结构学什么?
数据结构是一门基础学科,研究数据如何在计算机中组织和存储
3.学习数据结构有什么用?
了解数据在电脑中的组织和存储,就能利用不同特点数据的存储方式来高效的获取数据和修改数据。
4.数据结构分为三类:
线性结构:数组,队列,栈,链表,哈希表......
树形结构:二叉树,二分搜索树,红黑树,AVL树,堆,Trie,线段树,并查集.....
图形结构:邻接矩阵、邻接表......
二.数组
数组优点:查找快
缺点:插入删除移动位置的慢
1.数组创键
创建MyArray类
private int size; //用来保存实际存放的元素
private int[] data;//底层数据结构
//构造方法
public MyArray(){
this(100);//默认100
}
public MyArray(int capacity){
this.data = new int[capacity];
this.size = 0;// ***
}
2.获取数组长度
public int getSize(){
return this.size; //注意是size不是length
}
3.判断是否为空
public boolean isEmpty(){
return this.size==0;//***
}
4.数组中添加元素
①任意位置添加
public void add(int index,int val){
if (index<0||index>this.size){
throw new IllegalArgumentException("index is false");
}
for (int i = this.size-1; i >= index ; i--) {
this.data[i+1] = this.data[i];
}
this.data[index] = val;
this.size+=1;//注意size要更新
}
②头添加
public void addHead(int val){
add(0,val);
}
//已改过
③尾添加
public void addTail(int val){
add(this.size,val);
}
5.获取指定位置的元素
public int getElementByIndex(int index){
if (index<0||index>this.size-1){
throw new IllegalArgumentException("index is false");
}else {
return this.data[index];
}
}
6.修改指定元素位置
//与获取指位置的元素方法相似
public void setElementByIndex(int index,int var){
if (index<0||index>this.size-1){
throw new IllegalArgumentException("index is false");
}else {
this.data[index] = var;
}
}
7.是否包含某元素
public boolean isContain(int searchVar){
for (int i = 0; i < this.size; i++) {
if (this.data[i] == searchVar) {
return true; //遍历包含返回true,否false
}
}
return false;
}
8.根据元素查找索引
//找到返回索引,找不到返回-1
public int findIndex(int searchVar){
for (int i = 0; i < this.size; i++) {
if (this.data[i] == searchVar) {
return i;
}
}
return -1;
}
9.删除元素
①删除第一个元素
public int removeFirstElement(){
if (isEmpty()){
throw new IllegalArgumentException("ThisArray is null");
}
//记下第一个元素,从第1个元素开始都向前移动一位
int res = this.data[0];
for (int i = 1; i < this.size; i++) {
this.data[i-1] = this.data[i];
}
this.size-=1;
return res;
}
与从头添加元素一样可以用删除任意索引元素的方法简化代码
②删除最后一个元素
public int removeTailElement(){
if(isEmpty()){
throw new IllegalArgumentException("ThisArray is null");
}
int res = this.data[this.size-1];
this.size-=1;
return res;
//上三行可以简化为 return this.data[--this.size];
}
与从尾添加元素一样可以用删除任意索引元素的方法简化代码
③删除任意索引的元素
public int removeIndex(int index){
//
int res = this.data[index];
for (int i = index; i < this.size-1; i++) {
this.data[i] = this.data[i+1];
}
this.size-=1;
return res;
}
④删除指定的所有元素
*** 删除一次要注意i的位置,防止跳过一位再遍历
public void removeAllVal(int val){
for (int i = 0; i < this.size;) {
if (this.data[i]==val){
for (int j = i; j < this.size-1; j++) {
this.data[j] = this.data[j+1];
}
this.size-=1;
}else {
i++;//***
}
}
}
10.toString方法
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[");
for (int i = 0; i < this.size; i++) {
if (i!=this.size-1){
stringBuilder.append(data[i]+",");
}else stringBuilder.append(data[i]);
}
stringBuilder.append("]");
String str = new String(stringBuilder);
return str;
}
/*方法2:
用substring从头截取到倒数第二位
StringBuilder sb = new StringBuilder();
for (int i = 0; i < this.size; i++) {
sb.append(this.data[i] + ",");
}
String result = sb.toString();
return result.substring(0, result.length() - 1);
方法3:用流:
Array.stream(this.data).forEach(item->sb.append(item)+",");
*/
11.优化
①空间优化
数组容积的扩充和缩小
②改为泛型,将泛型作为参数
最后代码
import java.util.Random;
public class MyArray1<T> {
private int size; //用来保存实际存放的元素
private T[] data;//底层数据结构
private int capacity;//*****记着初始化
public MyArray1(){
this(100);//默认100
}
public MyArray1(int capacity){
this.capacity=capacity;// capacity 初始化****
this.data = (T[])new Object[capacity];
this.size = 0;// ***
}
public int getCapacity(){
return this.capacity;
}
// 获得数组长度
public int getSize(){
return this.size;
}
//返回数组
public String getArray(){
if(this.data==null){
return null;
}
return toString();
}
//判断数组是否为空
public boolean isEmpty(){
return this.size==0;//***
}
//头部添加
public void addTail(T val){
add(this.size,val);
}
//尾部添加
public void addHead(T val){
add(0,val);
}
//改变数组容积大小
//传入改变的容积大小
public void resize(int newCapacity){
// System.out.println("-------size--------");
//1.创建一个新的数组
T[] newArray =(T[]) new Object[newCapacity];
//2.将原来数组赋给新的数组
for (int i = 0; i < this.size; i++) {
newArray[i] = this.data[i];
}
//3.局部变量newArray 要转为成员变量 传给data
this.data = newArray;
//3.局部变量newCapacity 要转为成员变量 传给capacity
this.capacity = newCapacity;
}
//任意位置添加
public void add(int index,T val){
if (index<0||index>this.size){
throw new IllegalArgumentException("index is false");
}
if (this.size==this.capacity){
resize(this.capacity*2);
}
for (int i = this.size-1; i >= index ; i--) {
this.data[i+1] = this.data[i];
}
this.data[index] = val;
this.size+=1;
}
//获取指定位置的元素
public T getElementByIndex(int index){
if (index<0||index>this.size-1){
throw new IllegalArgumentException("index is false");
}else {
return this.data[index];
}
}
//修改指定位置元素
public void setElementByIndex(int index,T var){
if (index<0||index>this.size-1){
throw new IllegalArgumentException("index is false");
}else {
this.data[index] = var;
}
}
// 判断元素是否存在,是否包含元素
public boolean isContain(T searchVar){
for (int i = 0; i < this.size; i++) {
if (this.data[i].equals(searchVar) ) {
return true;
}
}
return false;
}
//查找元素:由元素查找索引
public int findIndex(T searchVar){
for (int i = 0; i < this.size; i++) {
if (this.data[i].equals(searchVar)) {
return i;
}
}
return -1;
}
//删除元素
//删除最后一个元素
public T removeTailElement(){
return removeIndex(this.size-1);
}
// 删除第一个元素
public T removeFirstElement(){
return removeIndex(0);
}
//删除指定位置的元素
public T removeIndex(int index){
if (index<0||index>=this.size){
throw new IllegalArgumentException("index is null");
}
T res = this.data[index];
for (int i = index; i < this.size-1; i++) {
this.data[i] = this.data[i+1];
}
this.size-=1;
if (this.size<= this.capacity/2&&this.capacity/2>2){
resize(this.capacity/2);
}
return res;
}
//删除指定的所有元素
public void removeAllVal(T val){
for (int i = 0; i < this.size;) {
if (this.data[i].equals(val)){
for (int j = i; j < this.size-1; j++) {
this.data[j] = this.data[j+1];
}
this.size-=1;
}else {
i++;
}
}
if (this.size<= this.capacity/2&&this.capacity/2>2){
resize(this.capacity/2);
}
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[");
for (int i = 0; i < this.size; i++) {
if (i!=this.size-1){
stringBuilder.append(data[i]+",");
}else stringBuilder.append(data[i]);
}
stringBuilder.append("]");
String str = new String(stringBuilder);
return str;
}
public static void main(String[] args) {
Random random = new Random();
MyArray1<Integer> myArray = new MyArray1<>(10);
long startTime = System.nanoTime();
for (int i = 0; i < 45; i++) { //这里验证扩容效果
myArray.add(i,random.nextInt(1000));
}
long endTime = System.nanoTime();
double sumTime = (endTime-startTime)/1000000000.0; //可验证尾插所用的时间长
System.out.println(sumTime);
System.out.println(myArray.getSize());
System.out.println(myArray);
System.out.println(myArray.removeFirstElement());
System.out.println(myArray);
//这里验证缩容效果
System.out.println("---------------------");
while (!myArray.isEmpty()){
myArray.removeFirstElement();
System.out.println(myArray.getCapacity());
}
}
}