Java基础复习day2
一维数组
-
定义:同时存储多个相同类型的数据,引用数据类型
-
存放于堆区,数组有下标。
-
内存空间连续,空间创建之后是固定的。
-
引用数据类型里面存储的是地址。十六进制。简单数据类型存储的是值,十进制
-
数组没有地址,里面的元素有地址
-
默认第一个元素的地址,充当整个数组的地址。数组的内存连续
-
计算机中的存储,默认单位是字节(Byte)
-
一个int类型,4个字节,所以,数组一个元素的起始地址为1234,第二个1238,第三个123c(16进制,连续的,以字节为单位)
-
初始化本身就是在赋值。
-
两种创建方式:1.创建数组并初始化 2.直接创建数组。
int[] arr = new int[3]; //new int[这里什么都不能写] {就是数组的元素} 这里的数量就是元素的个数 int[] arr1 = new int[] {4,5,7}; //直接写{} 注意:这种方法是在内部进行的new int[] arr2 = {5,7,9,9};
-
值传递:传参时传的是简单数据类型,传的是值。不能控制外部的值的更改。
-
址传递:传递的是地址。数组,对象。函数里面的变化是可以影响外面的变化,改变了地址,相应的值就会改变。
-
为何在堆区是new?----动态开辟内存空间。只要在堆中,就要去new。
二维数组
-
存储多个一维数组的地址
-
二维数组:直接存储的是多个一维数组(的地址)的数组
-
数组的空间都是连续的,并且是固定的。
-
二维数组的创建
//注意点:第一个[]中的数不能省,第二个[]中的数可以省略.写了,代表每个一维数组中元素的个数.不过这个数是一个估值. int[][] arr2 = new int[3][4];
排序
时间复杂度
用来度量算法的运行时间,不是一个确定的概念,只是一个概率值、
- 插入、冒泡、选择排序 n2
- 快排、堆排、归并 n log n
- 基数排序。n。希尔排序:n*1.25
空间复杂度
一般优先考虑时间复杂度,不考虑空间复杂度。
排序方式:
冒泡
//首先找到最大值放于最后
public static void bubbleSort(int arr[])
{
for(int i=0; i<arr.length-1; i++)
{
for(int j = 0; j <arr.length-i-1;j++)
{
if(arr[j]>arr[j+1])
{
arr[j]=arr[j]^arr[j+1];
arr[j+1]=arr[j]^arr[j+1];
arr[j]=arr[j]^arr[j+1];
}
}
}
}
选择
//首先找到最小值放于最前
public static void selectedSort(int arr[])
{
for(int i=0; i<arr.length-1;i++)
{
for(int j=i;j<arr.length-1;j++)
{
if(arr[i]>arr[j+1])
{
arr[i]=arr[i]^arr[j+1];
arr[j+1]=arr[i]^arr[j+1];
arr[i]=arr[i]^arr[j+1];
}
}
}
}
直接插入
(小规模数据,或者数据基本有序时,最高效)
public static void insertedsort(int arr[])
{
for(int i = 1; i < arr.length; i++) // 从第二个数据开始插入
{
int j = i-1; //i-1即为有序组的最后一个元素
int temp = arr[i]; // 无序组中取出第一个元素
while(j >=0 && arr[j] > temp)
{
arr[j+1] = arr[j]; // 若不是合适位置,有序组元素向后移动
j--;
}
arr[j+1] = temp; // 找到合适位置,将元素插入。
}
}
快排
/*
第一种方法
(一)定轴法:
1.备份对轴(首记录)
2.取两个指针left和right,初始值分别是序列的第二个元素和最后一个元素,并且left<=right
3.移动两个指针
*从right所指的位置向左搜索,找到第一个小于轴的元素
*从left所指的位置向右搜索,找到第一个大于轴的元素
*找到后如果left<right,那么就交换两个位置的值
4.重复上述过程,知道left>right
5.把轴放到right的位置,并且将right位置的值放到第一位
6.分别将right位置左边的和右边的进行上述的递归
*/
void quickSort(int* A,int first,int last){ //数组A,first是第一个元素下标,last是最后一个元素下标
if(last<=first) //到了长度小于1这种情况已经是有序列了
return;
int pivot=A[first];
int left=first+1; //left等于第二个元素
int right=last;
int temp;
while(left<=right){
while(A[right]>pivot&&right>=left)//找到一个比first小的,但必须保证left值小于等于right值
right--;
while(A[left]<pivot&&left<=right) //找到一个比first大的,但得保证left值小于等于right值
left++;
if(left>=right) //说明已经是相对有序序列,无需交换
break;
temp=A[left]; //交换位置
A[left]=A[right];
A[right]=temp;
left++,right--; //相应的进一位
}
A[first]=A[right]; //因为right一定是停在从右到左第一个小于first的数上,交换之后,
//依然能保证first值左边的比first小,右边的比first大
A[right]=pivot;
quickSort(A,first,right-1); //左半部分
quickSort(A,left,last); //右半部分
}
/*
(二)挖坑法:
1.备份轴记录
2.取两个指针i和j,初始值就是序列的两端下标,保证i<=j
3.移动两个指针
**从j向左找到第一个小于轴的元素, 放在i的位置
**从i向右找到第一个大于轴的元素,放在j的位置
4.重复,直到i=j,
5.把轴放在i所指的位置
6.分别对i所指的位置的左边和右边进行上述的递归
*/
public static void quickSort(int array[], int left, int right){
if(left>right) //left若大于right,已经满足,不需再进行判断。
{
return ;
}
int i = left, j = right, key = array[left];
while(i<j)
{
while(i<j && array[j]>=key)
{
j--;
}
array[i]=array[j]; //将这个比key小的值赋值给当前a[i],使得key值左边都比key小
while(i<j && array[i]<key)
{
i++;
}
array[j]=array[i]; //将这个比key大的值赋值给当前a[j],使得key值右边都比key大
}
array[i]=key; //将key值赋值给临界点l||r
//当前的l左边都比key小,右边都比key大 只需要更新[left,l-1]和[l+1,right]
quickSort(array,left,j-1);
quickSort(array,i+1,right);
}
归并
归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而**治(conquer)**的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
public static void sort(int arr[])
{
int temp[] = new int[arr.length]; //临时数组,用于排序
sort(arr,0,arr.length-1,temp);
}
//将数组拆分成两份
public static void sort(int arr[], int left, int right, int temp[])
{
if(left < right)
{
int mid = (left + right)>>1;
sort(arr,left,mid,temp); //拆分左边数组
sort(arr,mid+1,right,temp); //拆分右边数组
merge(arr, left, mid, right,temp);
}
}
public static void merge(int arr[], int left, int mid, int right, int temp[])
{
int i = left; //左边序列起始位置
int j = mid+1; //右边序列起始位置
int t = 0; //临时数组起始位置。
while(i<=mid && j<=right)
{
if(arr[i]<=arr[j])
{
temp[t++]=arr[i++];
}
else temp[t++]=arr[j++];
}
while(i<=mid) //将左边剩余元素填充进temp中
{
temp[t++] = arr[i++];
}
while(j<=right) //将右序列剩余元素填充进temp中
{
temp[t++] = arr[j++];
}
t=0;
while(left <= right)
{
arr[left++] = temp[t++];
}
}
// 合并子数组的函数
public static void merge(int[] array, int left, int center, int right) {
// 临时数组,用于排序
int[] tempArray = new int[array.length];
// 用于将排好序的临时数组复制回原数组
int mark = left;
// 第二个数组的左端
int mid = center + 1;
// 用于临时数组的下标
int tempLeft = left;
while (left <= center && mid <= right) {
// 从两个子数组中取出最小的放入临时数组,即按从小到大的顺序重新排布
if (array[left] <= array[mid]) {
tempArray[tempLeft++] = array[left++];
} else {
tempArray[tempLeft++] = array[mid++];
}
}
// 剩余部分依次放入临时数组
while (left <= center) {
tempArray[tempLeft++] = array[left++];
}
while (mid <= right) {
tempArray[tempLeft++] = array[mid++];
}
// 将中间数组中的内容复制回原数组
while (mark <= right) {
array[mark] = tempArray[mark++];
}
}
希尔排序
public static void shellsort(int arr[])
{
//遍历所有的步长
for(int d = arr.length/2;d>0;d=d/2){
//遍历所有的元素
for(int i = d;i<arr.length;i++){
//遍历本组中的所有元素
for(int j = i-d;j>=0;j-=d){
if(arr[j]>arr[j+d])
{
int temp = arr[j];
arr[j] = arr[j+d];
arr[j+d] = temp;
}
}
}
}
}
查找
二分查找:
public static int binarySearch(int arr[], int key)
{
int low = 0;
int high = arr.length-1;
int mid;
while(low<=high)
{
mid = (low+high)>>1;
if(arr[mid] == key)return mid;
else if(arr[mid]>key)
high = mid - 1;
else if(arr[mid]<key)
low = mid + 1;
}
return -1;
}