2022.1.6 时间复杂度及简单排序算法

2022.1.6 时间复杂度及简单排序算法

1. 时间复杂度

  • 定义:在常数操作数量的表达式中,除去低阶项和高阶项的系数所剩下来的东西,记作O(剩下),读作 big O(剩下),时间复杂度按照算法执行的最差情况估计;

  • 评价一个算法流程的好坏,先看时间复杂度的指标,然后再分析不同数据样本下的* 实际运行时间 *,也就是”常数运行时间“。

2. 简单排序算法

(1)选择排序
  • 从数组下标为零的位置(比较的数)开始,依次与后面n-1个数(被比较的数)进行比较,找到最小的数并放在比较的数。

  • 代码:


public class selectionSoft {
public static void main(String[] args)
{
int[] arr = {4,6,2,9,4,8,6,4,5,7,1};
SelectionSoft(arr);
}

public static void SelectionSoft(int[] arr)
{
for(int i=0;i<arr.length;i++)
{
for(int j=i+1;j<arr.length;j++)
{
if(arr[j]<arr[i])
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
for(int i:arr)
{
System.out.print(i+" ");
}
}
}

  • 运行结果:

    image-20220105201333631

(2)冒泡排序:从第i个数一直到n-1个数上一直找最小值或最大值,交换。
(3)插入排序:
  • code:

        public static void insertionSoft(int[] arr)
    {
    for(int i=1;i<arr.length;i++)
    {
    for(int j=i-1;j>=0;j--)
    {
    if(arr[j]>arr[j+1])
    {
    int temp = arr[j+1];
    arr[j+1] = arr[j];
    arr[j] = temp;
    }
    }
    }
    for(int cur:arr)
    System.out.print(cur+" ");
    }

     

3.异或

(1)可以实现两个数的值进行交换

int a=1,b=2;(a,b的值必须在内存中为两块不同的区域)
a = a^b;    //a = 1^2,b = 2
b = a^b; //a = 1^2,b = 1^2^2 = 1^0 = 1
a = a^b; //a = 1^2^1 = 0^2 = 2,b=1;

(2) 寻找n个数中出现了奇数次的数

  • eg:在n个数中,只有一种数出现了奇数次,其他的数都出现了偶数次,找出这个数。

    //假设这n个数为arr[1]~arr[n];
    main()
    {
       int eor = 0;
       for(int i=1;i<=n;i++)
      {
           eor = eor^arr[i];
      }
       System.out.println(eor);//最后异或完的eor即为这组数中唯一一个出现了奇数次的数。
    }

     

  • eg:在n个数中,有两种数出现了奇数次,其他的数都出现了偶数次,找出这两个数。

public static void main(String[] args)
{
int[] arr = {4,6,2,9,4,8,6,4,7,9,7,8};
printOddTimesNum(arr);
}


printOddTimesNum(int[] arr)
{
   int eor = 0;
   for(int cur:arr)
  {
       eor^=cur;
  }
   //此时eor为这两个要求的数的异或,eor!=0。
   //eor!=0,这两个出现了奇数次的数在同位次二进制位中必然一个为1一个为0
   //eor的二进制位上必然有一位为1
   
   int rightone = eor ^ (~eor+1);//提取eor二进制位里最右边的1,其余二进制位全部变为0
   int onlyone = 0;
   for(int cur:arr)
  {
       if((cur&rightone)==0)//给所有的数按这两个数不同的二进制位分类,只异或其中的一类
      {
           onlyone^=cur;
      }
  }//执行完循环后,这个onlyone为待求的某一个数
   System.out.println(onlyone+" "+(onlyone^eor));//eor^onlyone 为待求的另外一个数。
}
  • 结果:

 

 

 

4. 二分详解

(1)二分查找 O(logn)(在有序数组里查找某个数是否存在)

    public static void BinarySoft(int[] arr,int x)
{
int min = 0,max = arr.length;
while(min<max)
{
int mid  = (min+max)/2;
if(x==arr[mid])
{
System.out.println(mid);
return;
}

else if(x<arr[mid])
{
max = mid;
}
else
{
min = mid;
}
}
}

(2) 在一个有序数组中,找>=某个数最左侧的位置

public static void main(String[] args)
{
int[] arr = {2,4,4,4,6,7,7,8,8,9,9};
BinarySoft(arr,4);
}

public static void BinarySoft(int[] arr,int x)
{
int min = 0,max = arr.length;
int flag = 0;
while(min<max)
{
int mid = (min+max)/2;
if(x==arr[mid])
{
flag = mid;
if(arr[flag-1]<arr[flag])
break;
else
max = mid;
}

else if(x<arr[mid])
{
max = mid;
}
else
{
min = mid;
}
}
System.out.print(flag-1);
}

(3) 局部最小值问题

 

posted @ 2022-01-06 21:18  张满月。  阅读(85)  评论(0编辑  收藏  举报