您的位置:首页 > 理论基础 > 数据结构算法

数据结构之(1)数组

2015-11-10 15:16 711 查看

背景

表现优秀程序,是选择合适的数据结构和优秀的算法的必然结果,作为一名务实、精进的程序员,对数据结构的学习,熟练,自然成了必要的课程。闲话不多说,程序中的数据结构,是与语言无关的,常见的数据结构有:

数组(静态数组、动态数组)、

线性表、链表(单向链表、双向链表、循环链表)

队列



树(二叉树、查找树、平衡树、线索树、线索树)

在接下来的学习中,会对以上各种数据结构进行操作(add/get/delete),并简单的评估其效率(时空复杂度);在本博客中,尽量精准到概念化、原理画、源码化,所以会有很多概念梳理,原理、源码分析,看到的大神勿喷;

开始

一 数组的定义

数组是最简单的数据结构,根据定义方式有:

1.静态数组(Java中的,数组)

数组定义后,其开辟的内存空间大小已定,不能再追加元素

int  []arr=new int[]{1,2,3,4};//静态初始化
int []arr1=new  int [10];//动态初始化
arr1[0]=1;
arr1[1]=2;
....


2.动态数组(Java中的ArrayList)

ArrayList的本质还是数组,因为数组定义后,其开辟的内存空间大小已定,不能再追加元素;ArraList在数组的基础上,使用java.util.Arrays这个工具类,将数组扩容,再将原数组元素,复制到一个数组;

我们看下面这个方法,ArrayList中add() corecode

private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;//原数组长度
int newCapacity = oldCapacity + (oldCapacity >> 1);//扩容后长度
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);//返回扩容后的数组
}


问题来了,那这个Arrays是如何实现,点开Arrays.copyOf(elementData, newCapacity);

public static <T,U> T[] copyOf(U[] original, int newLength,  Class<? extends T[]> newType) {
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);//获得一个新数组
//调用native的方法,native的方法是用c写的
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}


之分别;根据数据是否有序,又分为:

1.无序数组:数据是没有规律的

2.有序数组;数据经过排序

数组的,add操作速度很快,为:o(1),但是查找和杀出比较慢,为:o(N)

二.数组元素的排序

定义:有数组,int [] arr=new int[]{95, 13, 88, 49, 12, 25, 84, 63, 73, 96, 70, 45, 38, 47, 53, 69, 81, 73, 33, 32},将数组按照由小到的顺序实现排序;

1冒泡排序

分析:将素组中元素,从左到右,一次两两比较大小,比较大的数字,交互到右边

然后在以此,重复N-1次;

代码实现:

//冒泡排序实现2
public  static  void bubbleSortImp(){
int[] newArr = productArray(20);
int size=newArr.length;
int  temp;
for(int  i=size-1;i>0;i--){//指定外层的,遍历
for(int j=i;j>0;j--){//内层的,相邻数字比较,及当前位置的移动
temp=newArr[i];
if(newArr[i]<newArr[j-1]){
newArr[i]=newArr[j-1];
newArr[j-1]=temp;
}
}
}

StringBuffer buffer = new StringBuffer();
buffer.append("NewArray:");
buffer.append(Arrays.toString(newArr));
System.out.println(buffer.toString());

}
结果:
测试数组:OldArray:[95, 13, 88, 49, 12, 25, 84, 63, 73, 96, 70, 45, 38, 47, 53, 69, 81, 73, 33, 32]
排序结果:NewArray:[12, 13, 25, 32, 33, 38, 45, 47, 49, 53, 63, 69, 70, 73, 73, 81, 84, 88, 95, 96]


2.选择排序

分析:将数组中数据,从左到右,依次取数字和左边数字比较,如果左边数字比较小则将当前数组元素和左边数字交换

代码:

//选择排序实现
public  static  void selectSortImp(){
int[] newArr = productArray(20);
int  size=newArr.length;
int  temp;
for(int i=0;i<size-1;i++){
temp=newArr[i];
for(int j=i+1;j<=size-1;j++){

if(newArr[i]>newArr[j]){
newArr[i]=newArr[j];
newArr[j]=temp;
}
}
}

StringBuffer buffer = new StringBuffer();
buffer.append("NewArray:");
buffer.append(Arrays.toString(newArr));
System.out.println(buffer.toString());

}
结果:

测试数组:OldArray:[12, 57, 86, 75, 50, 13, 4, 55, 81, 62, 91, 61, 67, 14, 66, 53, 42, 78, 12, 44]
排序结果:NewArray:[4, 12, 12, 42, 44, 61, 66, 78, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 91]


3.插入排序

分析:

代码实现:

// 插入排序实现
public static void insertSortImp() {
int[] newArr = productArray(20);
int size = newArr.length;
int j = 0;
long  start=System.currentTimeMillis();
for (int i = 1; i < size; i++) {
int temp = newArr[i];
j = i;
while (j >0 && newArr[j - 1]>= temp) {//找到打破有序的元素
newArr[j] = newArr[j - 1];//交互
j--;
}
newArr[j] = temp;//将j号元素插入部分有序的最后位置

}
long  end=System.currentTimeMillis();
StringBuffer buffer = new StringBuffer();
System.out.println("insertSortImp".concat("\n"));
buffer.append("NewArray:");
buffer.append(Arrays.toString(newArr));
System.out.println(buffer.toString());
System.out.println("CostTime=".concat(String.valueOf(end-start)));

}
测试数组:OldArray:[17, 29, 21, 30, 75, 83, 95, 52, 96, 46, 9, 43, 16, 71, 8, 68, 0, 66, 90, 92]
排序结果:NewArray:[0, 8, 9, 16, 17, 21, 29, 30, 43, 46, 52, 66, 68, 71, 75, 83, 90, 92, 95, 96]


对象的排序

以上我们操作的都是基本数据类型,但是实际开发中我们经常要操作对象类型数据

,对一组对象进行排序,

例如:将十个人,按照年龄大小排序,并且输出排序结果;

分析:我们要实现这两个接口的一个:1.Comparable

Comparator,使用的时候是这样实现的,comparetor要实现的方法:

@Override
public int compare(Person o1, Person o2) {
// TODO Auto-generated method stub
//此处person类,按照年龄,从大到小,注意返回值
if (o1.getAge() > o2.getAge()) {
return 1;
} else {
return 0;
}

}


Comparable与之类似

@Override
public   int compareTo(Person o) {
if(this.age>o.age){
return 1;
}else{
return 0;
}


完整过程:

Person person = new Person();
person.setAge(20);
person.setName("yangliang");
Person person2 = new Person();
person2.setAge(18);
person2.setName("beauty");
Person person3 = new Person();
person3.setAge(15);
person3.setName("fdfas");
....
ArrayList<Person> list = new ArrayList<Person>();
list.add(person);
list.add(person2);
list.add(person3);
....
Collections.sort(list, new Comparator<Person>() {

@Override
public int compare(Person o1, Person o2) {
// TODO Auto-generated method stub
if (o1.getAge() > o2.getAge()) {
return 1;
} else {
return 0;
}

}
});
排序结果:
[Person [age=20, name=yangliang], Person [age=18, name=beauty], Person [age=15, name=fdfas]....]


这里我们看到一个Collections,工具类,后面再详细介绍
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: