数据结构和算法1:算法分析&简单排序

1 算法分析

1.1 时间复杂度

比较算法随着输入规模的增长量的规则

1.常数可以忽略;
2.最高次幂的常数因子可以忽略;
3.算法函数中最高次幂越小,算法效率越高。

常见时间复杂度总结

在这里插入图片描述

  • 复杂程度排序:
    O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n3)
  • 尽可能的追求O(1),O(logn),O(n),O(nlogn)这几种时间复杂度
  • 如果发现算法的时间复杂度为平方阶、立方阶或者更复杂的,那我们可以认为这种算法是不可取的,需要优化

1.2 空间复杂度

基本数据类型内存占用情况

数据类型内存占用字节数
byte1
short2
int4
long8
float4
double8
boolean1
char2
  1. 计算机访问内存:每次1个字节
  2. 一个引用(机器地址):8个字节
    例如: Date date = new Date(),则date这个变量需要占用8个字节来表示
  3. 一个对象的头信息:16字节
    例如new Date(),除了Date对象内部存储的数据(例如年月日等信息)占用的内存,该对象本身也有内存开销,每个对象的自身开销是16个字节,用来保存对象的头信息。
  4. 一般内存的使用,如果不够8个字节,都会被自动填充为8字节,以8为单位
  5. 数组被限定为对象,一般会因为记录长度而需要额外的内存,一个原始数据类型的数组一般需要24字节的头信息(16个自己的对象开销,4字节用于保存长度以及4个填充字节)再加上保存值所需的内存
public class A {
	public int a=1;
}
/*
通过new A()创建一个对象,其内存占用情况如下:
1、整型成员变量a占用4个字节
2、对象本身占用16个字节
3、由于4+16=20字节不是以8个字节为单位,所以会自动填充为24个字节
*/		

1.3 算法稳定性

定义

数组arr中有若干元素,其中A元素和B元素相等,且A元素在B元素前面,如果使用某种排序算法排序后,能保证A元素依然在B元素前面,就可以说这个算法 稳定的

如果一组数据需要多次排序,稳定性是有意义的,可以保持第一次排序原有的意义而且可以减少系统开销

稳定的: 冒泡、插入、归并
不稳定的: 选择、希尔、快速

2 简单排序

排序方法简述
冒泡排序相邻比较(太慢)
选择排序每次选最小(不稳)
插入排序分组,未排序组的元素与每一个已排序组的元素进行比较(样本小且基本有序时效率比较高)

2.1 Comparable接口

//学生类
public class Student implements Comparable<Student>{
    private String username;
    private int age;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student{" +
                "username='" + username + '\'' +
                ", age=" + age +
                '}';
    }
    //定义比较规则
    @Override
    public int compareTo(Student o) {
        return this.getAge()-o.getAge();
    }
}
//测试类
public class Test {
    public static void main(String[] args) {
        Student stu1 = new Student();
        stu1.setUsername("zhangsan");
        stu1.setAge(17);
        Student stu2 = new Student();
        stu2.setUsername("lisi");
        stu2.setAge(19);
        Comparable max = getMax(stu1, stu2);
        System.out.println(max);
    }
    //测试方法,获取两个元素中的较大值
    public static Comparable getMax(Comparable c1,Comparable c2){
        int cmp = c1.compareTo(c2);
        if (cmp>=0){
            return c1;
        }else{
            return c2;
        }
    }
}

2.2 冒泡排序

public class BubbleSort {
//冒泡排序算法封装
	public static void bubbleSort(int[] arr) {
		int temp=0; //临时变量
		boolean flag=false; //标识变量,是否进行过交换
		for(int i=0;i<arr.length-1;i++) {
			for(int j=0;j<arr.length-1-i;j++){
				//如果前面的数比后面的数大,则交换
				if(arr[j]>arr[j+1]{
					flag=true;
					temp=arr[j];
					arr[j]=arr[j+1];
					arr[j+1]=temp;
				}
			}
			if(!flag) //在一趟排序中一次都没有交换过
				break;
			else
				flag=false; //重置后进行下一次判断
		}
	}
//测试
	public static void main(String[] args) {
		int arr[]={3, 0, -1, 10, 7};
		bubbleSort(arr);
	}
}

2.3 选择排序

public class SelectSort {
//选择排序算法封装
	public static void selectSort(int[] arr) {
		for (int i = 0; i < arr.length-1; i++) {
			int minIndex = i;
			int min = arr[i];
			for (int j = i + 1; j < arr.length; j++) {
				if (min > arr[j]) {
					min = arr[j]; 
					minIndex = j; 
				}
			}
			// 将最小值,放在最前面, 即交换
			if (minIndex != i) {
				arr[minIndex] = arr[i];
				arr[i] = min;
			}
	}
//测试	
	public static void main(String[] args) {
		int [] arr = {101, 34, 119, 1, -1, 90, 123};
		selectSort(arr);
	}
}

2.4 插入排序

public class Insertion {
    //对数组a中的元素进行排序
    public static void sort(Comparable[] a){
        for (int i=1;i<a.length;i++){
		//当前元素为a[i],依次和i前面的元素比较,找到一个小于等于a[i]的元素
            for (int j=i;j>0;j--){
                if (greater(a[j-1],a[j])){
					//交换元素
                    exch(a,j-1,j);
                }else{
                    break;
                }
            }
        }
    }
    //比较v元素是否大于w元素
    private static boolean greater(Comparable v,Comparable w){
        return v.compareTo(w)>0;
    }
    //数组元素i和j交换位置
    private static void exch(Comparable[] a,int i,int j){
        Comparable t = a[i];
        a[i]=a[j];
        a[j]=t;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值