Java复习(二)(数组,排序,查找)

Java基础复习day2

一维数组

  1. 定义:同时存储多个相同类型的数据,引用数据类型

  2. 存放于堆区,数组有下标。

  3. 内存空间连续,空间创建之后是固定的。

  4. 引用数据类型里面存储的是地址。十六进制。简单数据类型存储的是值,十进制

  5. 数组没有地址,里面的元素有地址

  6. 默认第一个元素的地址,充当整个数组的地址。数组的内存连续

  7. 计算机中的存储,默认单位是字节(Byte)

  8. 一个int类型,4个字节,所以,数组一个元素的起始地址为1234,第二个1238,第三个123c(16进制,连续的,以字节为单位)

  9. 初始化本身就是在赋值。

  10. 两种创建方式:1.创建数组并初始化 2.直接创建数组。

    int[] arr = new int[3];
    //new int[这里什么都不能写] {就是数组的元素}   这里的数量就是元素的个数
    	int[] arr1 = new int[] {4,5,7};
    //直接写{}  注意:这种方法是在内部进行的new
    	int[] arr2 = {5,7,9,9};
    
  11. 值传递:传参时传的是简单数据类型,传的是值。不能控制外部的值的更改。

  12. 址传递:传递的是地址。数组,对象。函数里面的变化是可以影响外面的变化,改变了地址,相应的值就会改变。

  13. 为何在堆区是new?----动态开辟内存空间。只要在堆中,就要去new。

二维数组

  1. 存储多个一维数组的地址

  2. 二维数组:直接存储的是多个一维数组(的地址)的数组

  3. 数组的空间都是连续的,并且是固定的。

  4. 二维数组的创建

    //注意点:第一个[]中的数不能省,第二个[]中的数可以省略.写了,代表每个一维数组中元素的个数.不过这个数是一个估值.
    		int[][] arr2 = new int[3][4];
    

排序

时间复杂度

用来度量算法的运行时间,不是一个确定的概念,只是一个概率值、

  1. 插入、冒泡、选择排序 n2
  2. 快排、堆排、归并 n log n
  3. 基数排序。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;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值