左程云算法笔记(持续更新)

第一讲:时间复杂度与简单排序算法

. 时间复杂度的O表示一个最坏情况,上限

. 两个同时间复杂度的算法进行比较要实际测试
· O(log2^N)默认为以2为底

. 异或^)可以理解为无进位相加(可解释异或的交换性质)。

· 0^a=a,a^a=0

. 二分法不一定要在有序数组中运用(找局部最小值)

用异或交换数字

注意用异或的交换和结合性质理解

    a=a^b;
    b=a^b;      //b=a^b^b=a^0=a;
    a=a^b;      //a=a^b^a=a^a^b=0^b=b;
.异或高阶运用

异或运算偶数次的同一数为0,奇数次为本身
提取最右侧的1:

int rightone=eor & (~eor+1);

对数器

1.有想测的方法a,另外有已知不好的方法b
2.生成随机样本产生器
3.样本在a,b中都测试一遍。看结果是否相同。(先小样本,人工看。再大数据量测)

选择排序

for(int i=0;i<len;i++){
    
    int minIndex=i;
    for(int j=i;j<len;j++){
   
        minIndex=arr[j]<arr[minIndex]?j:minIndex;
    }
    swap(arr,i,minIndex);
 }
}   

冒泡排序

for(int i=len-1;i>0;i--){
    //指定最开始的范围
    for(int j=0;j<i;j++){
   
        if(arr[j]>arr[j+1]){
   
            swap(arr[j],arr[j+1]);
        }
    }
}

插入排序

for(int i=1;i<arr.length;i++){
    //每步想要完成的目标
    for(int j=i-1;j>=0&&arr[j]>arr[j+1];j--){
   //j是目标的前一个数字
        swap(arr[j],arr[j+1]);
    }
}
/*关于第二层for循环中&&可以理解为,有一个没达到条件就终止循环,  
这是很严格的,所以用&&表示这种严格程度 
*/

第二讲:认识O(NlogN)的排序

·Mid常规写法:(L+R)/2 —>可能会溢出;所以用Mid=L+(R-L)/2或者L+(R-L)>>1

·递归可以理解为后序遍历树,悬而未决的函数进栈(压栈push)

·递归函数Master公式:T(N)=a*T(N/b)+O(N^d)

----》a为子问题调用次数,b为子问题是母问题数据量的倍数,O(N^d)是函数剩余的时间复杂度

·利用Master公式求时间复杂度:

logb^ad :O(N^logb^a)
logb^a=d :O(N^d*logN)

归并排序

·归并排序的核心是双指针,一个指向头,一个指向中间+1位置。不断找最小的拷贝到新数组中。直到一个指针到了头(前指针到中间或者后指针到尾巴),再把另一个未到头的直接拷贝进新数组。实现了区域小块的排序。

·递归的本质就是不断把需要排序的区域缩小化,中间mid作为下一个区域的边界。

public static void process(int[] arr,int L,int R){
   
    if(L==R)return;
    int mid=L+((R-L)>>1);//这样算中点可以防止溢出,>>优先级比+低
    process(arr,L,mid);
    process(arr,mid+1,R);
    merge(arr,L,mid,R);
}
public static void merge(int[]arr,int L

你可能感兴趣的:(算法,排序算法,数据结构)