Simple Sort Algorithm, Bisection, and Logarithm

Simple Sort Algorithm, Bisection, and Logarithm

selection sort

For the first time, the smallest (or largest) element is selected from the data elements to be sorted, and stored at the beginning of the sequence, and then the smallest (largest) element is found from the remaining unsorted elements, and then placed in the The end of the sorted sequence. And so on, until the number of all data elements to be sorted is zero.

code :

/**
 * 选择排序
 */
public static void selectionSort(int[] arr){
    // 如果数组为空或只有一个元素故不需要进行排序,直接返回即可
    if(arr == null || arr.length < 2 ){
        return;
    }
    for(int i = 0; i < arr.length -1;i++ ){ // 从i~N-1中找出最小的元素并放到i位置上
        int minIndex = i;
        for(int j = i+1;j < arr.length;j++){ //从i~N-1上找最小值的下标
            minIndex = arr[j] < arr[minIndex]? j : minIndex;
        }
        swap(arr,i,minIndex);
    }
}

// 交换arr的i和j位置上的值
private static void swap(int[] arr, int i, int j) {
    int tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

Bubble Sort

Repeatedly visit the column of elements to be sorted, compare two adjacent elements in turn, and exchange them if the order (such as from large to small, initial letter from Z to A) is wrong. The work of visiting elements is repeated until no adjacent elements need to be exchanged, that is to say, the element column has been sorted.

/**
 * 冒泡排序
 */
public static void bubbleSort(int[] arr){
    // 数组为空或数组元素为1则不需要进行排序,直接推出即可
    if(arr == null || arr.length<2){
        return;
    }
    for(int i = 0; i < arr.length-1; i++){ // 控制比较轮次,一共 n-1 趟
        for (int j = 0; j < arr.length-1-i; j++){ // 控制两个挨着的元素进行比较
            if(arr[i] > arr[j]){
                swap(arr,arr[i],arr[j]);
            }
        }
    }
}
// 交换arr的i和j位置上的值  ^ 表示异或运算,不同为1相同为0
// 数组中这样交换两个数的前提是 i j 位置上的数一定不相同 否则i j 位置上的数均会变成0
// 不提倡这么写!!!
private static void swap(int[] arr, int i, int j) {
	arr[i] = arr[i] ^ arr[j];
	arr[j] = arr[i] ^ arr[j];
	arr[i] = arr[i] ^ arr[j];
}

Supplement: Do not apply for additional space to exchange the value of two numbers

The premise here is that a and b are two separate areas in memory!
insert image description here

Supplement: XOR interview questions

There are n kinds of numbers in an arr array

1. One kind of number appears odd number of times, and other numbers appear even number of times, how to find out the number that appears odd number of times?

2. The two numbers can appear an odd number of times, and the other numbers can appear an even number of times. How to find out the number that appears an odd number of times?

untie:

  1. Set a variable to ero ero=All elements in the array are XORed ero=A number that appears an odd number of times

Because the XOR operation satisfies the commutative and associative laws, the same is 0, the XOR result of an even number of numbers is 0, and any number and 0 XOR is equal to itself. (Similar to Xiaoxiaole)

  1. Set a variable as ero, set a and b as numbers that appear an odd number of times ero= XOR all elements in the array ero=a^b is not equal to 0 because there are two types of numbers, so a is not equal to b

a^b != 0 means that a and b have at least one bit different, assuming that the 8th bit is different. Divide all the numbers into two categories, the numbers with the 8th bit being 1 and the numbers with the 8th bit being 0 (numbers that appear even number of times will also be classified in this way), and a and b will only occupy one side of them. eor1 XOR the number whose 8th digit is 1, and the number that appears even number of times is still not disturbed and wiped into 0. At this time, eor1 gets a or b, and at this time the other number in a and b is obtained with ero^ero1!

/**
 * 异或运算面试题 第二问
 */
public static void printOddTimesNum2(int[] arr){
    int eor = 0;
    for(int i : arr){
        eor ^= i;
    }
    // eor = a ^ b
    // eor != 0
    // eor必然有一个位置上是1 选择最右侧的数值为1
    // 将一个不为0的数最右侧的1提取出来  ~eor 表示 eor取反
    int rightOne = eor & (~eor + 1); // 也就是说  一个数 & 自身取反+1 则把自己最右侧的数给弄出来了

    int onlyOne = 0; // eor1
    for(int cur : arr){
        if((cur & rightOne) == 1){ //那个位置 等于 1 我才进行异或  相当于两边只要了一侧
            onlyOne ^= cur;
        }
    }

    System.out.println("两个出现了奇数次的数为: "+ onlyOne + " " + (eor ^ onlyOne));

}

insertion sort

Refers to the elements to be sorted, assuming that the previous n-1 (where n>=2) numbers have been sorted, now insert the nth number into the previously sorted sequence, and then find the suitable one position, so that the sequence inserted into the nth number is also sorted. According to this method, all elements are inserted until the entire sequence is sorted, which is called insertion sort. Insertion sorting is equivalent to ensuring that the first element is in order, the first 2 elements are in order, the first 3 elements are in order, and the first 4 elements are in order...

/**
 * 插入排序(优于选择排序和冒泡排序)
 */
public static void insertSort(int[] arr){
    if(arr == null || arr.length < 2){
        return;
    }
    for (int i = 1; i < arr.length; i++) { // 0到i做到有序
        for(int j = i-1 ; j >= 0 && arr[j] > arr[j + 1]; j--){
            swap(arr,i,j+1);
        }
    }
}

dichotomy

First, assuming that the elements in the table are arranged in ascending order, compare the key recorded in the middle position of the table with the search key, if the two are equal, the search is successful; otherwise, use the record in the middle position to divide the table into two sub-tables, the front and the back, if If the key recorded in the middle position is greater than the search key, the previous sub-table is further searched; otherwise, the latter sub-table is further searched. Repeat the above process until a record meeting the condition is found, making the search successful, or until the child table does not exist, at this time the search is unsuccessful.

  1. Find if a certain number exists in an ordered array

Time complexity O(LogN)

  1. In an ordered array, find the leftmost position of >= a certain number

eg: Find the leftmost number of 1 2 2 2 2 2 3 3 3 3 4 4 4 4 4 5 5 5 5 5 5 >=3?

The difference between this and the first point is that to find whether a number exists by two points, you only need to find it, but to find a number on the leftmost side, you need to carry out two points all the time!

  1. local minimum problem

eg: The elements in the array arr are unordered, any two adjacent numbers are not equal, please find a local minimum number and the time complexity is less than O(n).

Local minimum: i-1 i i+1 If the number at position i in the array is both smaller than the number on i-1 and smaller than the number on i+1, then i is called the local minimum number.

0 1 2 … M-1 M M+1 …N-2 N-1

Find M in the first dichotomy, and return M if M is less than the number on M-1 and less than the number on M-2. Otherwise, if you continue to search from one side, you will definitely find a local minimum position!

The concept and use of logarithms

  1. There is a method you want to test a
  2. The implementation complexity is not good but the method b is easy to implement
  3. Implement a random sample generator
  4. Run method a and method b on the same random sample to see if the results are the same.
  5. If there is a random sample that makes the comparison results inconsistent, print the sample for manual intervention, and change to method a or method b
  6. When the number of samples is large, the comparison test is still correct, and it can be determined that method a is correct.

As the name implies, the logarithm is a tool for comparing data. Generally, the data comparison test is performed in an OJ-free environment, which can realize the test of its own data without relying on the online platform. For example, there are two methods: method a (want to test) and method b (very simple but not efficient). You use a random sample generator to generate a series of data and compare the data generated by method a with the data generated by method b. , if the data are inconsistent, it means that one of the methods has an error, and if they are consistent, it means that the method is correct. This is the principle of the logarithm .

/**
 * 生成随机数组
 */
public static int[] generateRandomArray(int maxSize,int maxValue){

    // Math.random() -> [0,1) 所有的小数,等概率返回一个
    // Math.random() * N -> [0,N) 所有小数等概率返回一个
    // (int)(Math.random() * N) -> [0,N-1] 所有的整数,等概率返回一个
    int[] arr = new int[(int) ((maxSize+1)*Math.random())]; // 数组长度随机
    for(int i = 0; i < arr.length; i++){
        arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) ((maxValue + 1) * Math.random());
    }

    return arr;
}

public static void main(String[] args) {
   // 对数器代码实现举例
   int testTime = 500000; // 表示测试的次数
   int maxSize = 100; // 确保了每次生成的数的大小范围在0~100之间
   int maxValue = 100; // 确保了每一次生成的数值是在0~100之间
   boolean succeed = true;
    for (int i = 0; i < testTime; i++) {
        int[] arr1 = generateRandomArray(maxSize,maxValue);
        int[] arr2 = copyArray(arr1); // 将数组arr1拷贝一份
        insertionSort(arr1);
        comparator(arr2);
        if(!isEqual(arr1,arr2)){
            succeed = false;
            break;
        }
    }
	system.out.println(succeed);
}

Guess you like

Origin blog.csdn.net/ailaohuyou211/article/details/127128452