前言
学海无涯苦作舟
知道数据结构,但是对数据结构的具体实现并不是很清楚?
从今天开始,慢慢的用熟悉的Java语言实现一遍数据结构
数据结构
什么是数据结构?
数据结构是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合
数据结构的作用
既然数据结构是存储、组织数据的方式,那么一定有下面的功能
- 能够插入一个数据
- 能够查找一个特定的数据
- 能够删除一个特定的数据
- 能够访问所有数据,以便进行其他操作
常见的数据结构
这些数据结构各有自己的特色,希望在接下来的时间里,慢慢通过Java去实现他们
先从最简单的数组开始
数组知识
数组,是用来存放同一种数据类型的集合
声明数组
在Java中数组的声明有两种方法
(1)
数据类型[] 数组名 = new 数据类型[数组长度];
int[] num = new int[5];
注意:[]可以放数组名前、后,但放前面比较规范,更能表现这是一个数组
注意:需要确切的限定数组大小
(2)
数据类型[] 数组名 = {"数组元素1”,"数组元素2"...}
int[] array = {1,2,3}
注意:数组的大小由给定的数组元素个数决定
访问数组元素
数组存在下标索引,从0到数组的长度-1
访问数组时,通过下标即可访问
给数组赋值也需要通过下标确定给数组中某个位置赋值(但是不能越界)
//初始化
int[] num = new int[3];
//赋值
num[0]= 1;
//访问第一个数据
System.out.println(num[0]);
num[3]= 4;
越界错误:ArrayIndexOutOfBoundsException
数组遍历
数组会提供一个length属性表示数组的长度
然后我们选择遍历方法:for、foreach、迭代器遍历数组
int[] a = new int[3];
System.out.println(a.length);
实现数组
数组的性质前面已经表现出来了
来通过Java数组模拟数据结构,希望实现以下功能
- 插入数据(是否传入下标值)
- 根据下标查找数据
- 根据下标删除数据
- 提供length属性,以便遍历
- 修改值
这里简单实现一下int型数组数据结构,且不考虑重复元素
public class MyArray {
//定义一个数组
private int[] intArray;
//数组实际长度
private int realLength;
//数组最大长度
private int length;
//构造一个数组
public MyArray(int arrayLength){
realLength = 0;
length = arrayLength;
intArray = new int[length];
}
//获得数组真实长度
public int size(){
return realLength;
}
//添加元素,返回成功与否
public boolean add(int value){
//数组满了
if (realLength == length){
System.out.println("数组满了,添加失败");
return false;
}
else {
//默认往数组尾添加数据
intArray[realLength] = value;
//真实长度+1
realLength++;
}
return true;
}
//根据下标添加元素,返回成功与否
public boolean add(int index,int value){
//数组满了
if (realLength == length){
System.out.println("数组满了,添加失败");
return false;
}
//越界
if (index < 0 && index > length - 1){
throw new ArrayIndexOutOfBoundsException();
}
//如果是替换
if (index < realLength) {
intArray[index] = value;
}
//如果是添加
else {
intArray[index] = value;
realLength++;
}
return true;
}
//根据下标获取元素
public int get(int index){
//越界
if (index < 0 && index > realLength - 1){
throw new ArrayIndexOutOfBoundsException();
}
return intArray[index];
}
//遍历显示
public void show(){
for (int i : intArray){
System.out.print(i+" ");
}
}
//根据元素查找元素下标
public int find(int value){
int index = -1;
for (int i = 0 ; i < realLength ; i++){
if (i == value){
index = i;
break;
}
}
return index;
}
//根据具体元素值删除元素
public boolean delete(int value){
//先查找该元素的下标
int index = find(value);
//如果没找到
if (index == -1){
return false;
}
else {
deleteMethod(index);
return true;
}
}
//根据下标删除元素
public boolean deleteByIndex(int index){
//越界
if (index < 0 && index > realLength - 1){
throw new ArrayIndexOutOfBoundsException();
}
deleteMethod(index);
return true;
}
//删除方法
private void deleteMethod(int index){
//如果是数组尾元素,直接-1
if (index == realLength-1){
realLength--;
}
//如果不是数组尾元素,需要将该元素后面的元素往前移动一位
else {
for (int i = index ; i < realLength-1 ; i++){
intArray[i] = intArray[i+1];
}
realLength--;
}
}
//修改元素
public boolean modify(int oldValue,int newValue){
int index = find(oldValue);
if (index == -1){
System.out.println("数据不存在");
return false;
}
else {
intArray[index] = newValue;
return true;
}
}
}package com.company.Array;
public class MyArray {
//定义一个数组
private int[] intArray;
//数组实际长度
private int realLength;
//数组最大长度
private int length;
//构造一个数组
public MyArray(int arrayLength){
realLength = 0;
length = arrayLength;
intArray = new int[length];
}
//获得数组真实长度
public int size(){
return realLength;
}
//添加元素,返回成功与否
public boolean add(int value){
//数组满了
if (realLength == length){
System.out.println("数组满了,添加失败");
return false;
}
else {
//默认往数组尾添加数据
intArray[realLength] = value;
//真实长度+1
realLength++;
}
return true;
}
//根据下标获取元素
public int get(int index){
//越界
if (index < 0 && index > length - 1){
throw new ArrayIndexOutOfBoundsException();
}
return intArray[index];
}
//遍历显示
public void show(){
for (int i : intArray){
System.out.println(i);
}
}
//根据元素查找元素下标
public int find(int value){
int index = -1;
for (int i = 0 ; i < realLength ; i++){
if (i == value){
index = i;
break;
}
}
return index;
}
//根据下标删除元素
public boolean delete(int value){
//先查找该元素的下标
int index = find(value);
//如果没找到
if (index == -1){
return false;
}
else {
//如果是数组尾元素,直接-1
if (index == realLength-1){
realLength--;
}
//如果不是数组尾元素,需要将该元素后面的元素往前移动一位
else {
for (int i = index ; i < realLength-1 ; i++){
intArray[i] = intArray[i+1];
}
realLength--;
}
return true;
}
}
//修改元素
public boolean modify(int oldValue,int newValue){
int index = find(oldValue);
if (index == -1){
System.out.println("数据不存在");
return false;
}
else {
intArray[index] = newValue;
return true;
}
}
}
测试一下:
class test{
public static void main(String[] args) {
MyArray myArray = new MyArray(5);
myArray.add(1);
myArray.add(2);
myArray.add(3);
myArray.add(4);
System.out.print("所有元素:");
myArray.show();
System.out.println();
System.out.println("第四个元素是:"+myArray.get(3));
System.out.println("元素2的下标是:"+myArray.find(2));
System.out.println("数组的实际大小:"+myArray.size());
myArray.deleteByIndex(3);
System.out.print("删除元素后:");
myArray.show();
System.out.println();
myArray.modify(2,5);
System.out.print("修改元素:");
myArray.show();
}
}
到这里,数组数据结构实现了,可以分析一下数组
分析
数组是一种最基础的数据结构
数组可以完成数据结构的任务,且很简单,为什么实际应用中并不会选择数组来存储数据?
我们可以分析一下数组的特点
- 插入快
无序数组插入,只需往数组尾放放入数据即可,仅仅需要判断数组是否满了
而如果是有序数组,还要涉及到排序(关于排序后面在实现),这使得插入也不一样快 - 查找慢
无序数组查找时会遍历数组直到找到该元素,当然有序数组查找可以根据算法加快查找速度 - 删除慢
根据元素值删除,需要遍历到该元素值,删除时,除了队尾,每一次删除都需要把后面的元素往前移位 - 大小固定
数组创建时需要确认大小,大小固定,如果设置大了又可能会浪费空间
总的来说,数组的性能太差,所以实际使用时几乎不会使用数组