Java interview often ask knowledge, understand the sorting algorithm at one time, and summarize the commonly used sorting algorithms

Posted by mikew2 on Sat, 01 Jan 2022 18:42:32 +0100

realization

public class SelectionSort {

    public int[] selectionSort(int[] A, int n) {

        //Record minimum subscript value

        int min=0;

        for(int i=0; i<A.length-1;i++){

            min = i;

            //Find the minimum value after the beginning of subscript i

            for(int j=i+1;j<A.length;j++){

                 if(A[min]>A[j]){

                     min = j;

                 }

            }

            if(i!=min){

                swap(A,i,min);

            }

        }

        return A;

    }

    private void swap(int[] A,int i,int j){

        int temp = A[i];

        A[i] = A[j];

        A[j] = temp;

    }

} 

Insert sort

The working principle of the insertion sorting algorithm is to construct an ordered sequence, scan the unordered data from back to front in the sorted sequence, find the corresponding position and insert it. Therefore, in the process of scanning from back to front, it is necessary to repeatedly move the sorted elements backward step by step to provide insertion space for the latest elements

realization

public class InsertionSort {

    public int[] insertionSort(int[] A, int n) {

      //The idea of inserting playing cards with simulation

        //Inserted playing cards

        int i,j,temp;

        //One has been inserted, continue to insert

        for(i=1;i<n;i++){

            temp = A[i];

            //Move all the cards in front of i that are larger than the card to be inserted one bit back, leaving one bit free for the new card

            for(j=i;j>0&&A[j-1]>temp;j--){

                A[j] = A[j-1];

            }

            //Fill the empty one with the inserted card

            A[j] = temp;

        }

        return A;

    }

} 

Merge sort

The core of merge sort is the idea of divide and conquer. First divide the array into the front and back parts from the middle, then sort the front and back parts respectively, and then merge the two parts in good order, so that the whole array is in order

If two ordered tables are merged into one, it is called two-way merging

Merge sort is a stable sort algorithm

realization

public class MergeSort {

	public static void main(String[] args) {

		int data[] = { 9, 5, 6, 8, 0, 3, 7, 1 };

		megerSort(data, 0, data.length - 1);

		System.out.println(Arrays.toString(data));

	}

 

	public static void mergeSort(int data[], int left, int right) { // Both ends of the array

		if (left < right) { // Equal means that there is only one number and there is no need to dismantle it

			int mid = (left + right) / 2;

			mergeSort(data, left, mid);

			mergeSort(data, mid + 1, right);

			// After splitting, we will merge, that is, we will recursively return

			merge(data, left, mid, right);

		}

	}

 

	public static void merge(int data[], int left, int mid, int right) {

		int temp[] = new int[data.length];		//A temporary array is used to hold the merged data

		

		int point1 = left;		//Indicates the position of the first number on the left

		int point2 = mid + 1;	//Indicates the position of the first number on the right

		

		int loc = left;		//It means where we are now

		while(point1 <= mid && point2 <= right){

			if(data[point1] < data[point2]){

				temp[loc] = data[point1];

				point1 ++ ;

				loc ++ ;

			}else{

				temp[loc] = data[point2];

				point2 ++;

				loc ++ ;

			}

		}

    

		while(point1 <= mid){

			temp[loc ++] = data[point1 ++];

		}

		while(point2 <= right){

			temp[loc ++] = data[point2 ++];

		}

		for(int i = left ; i <= right ; i++){

			data[i] = temp[i];

		}

	}

} 

Shell Sort

Basic idea:

Firstly, the number of a group to be sorted is divided into several groups according to a certain increment d (n/2, n is the number of numbers to be sorted). The subscript difference of records in each group is d, and all elements in each group are directly inserted and sorted, and then a smaller increment is used (d/2) group it, and then perform direct insertion sorting in each group. When the increment is reduced to 1, the sorting is completed after direct insertion sorting

Hill sort method (reduced increment method) belongs to insertion sort. It is a method to divide the whole non sequence into several small subsequences for insertion sort respectively

If the length of the array is 10, the array elements are 25, 19, 6, 58, 34, 10, 7, 98, 160 and 0

The algorithm process of hill sorting is as follows:

realization

public static int[] ShellSort(int[] array) {

        int len = array.length;

        int temp, gap = len / 2;

        while (gap > 0) {

            for (int i = gap; i < len; i++) {

                temp = array[i];

                int preIndex = i - gap;

                while (preIndex >= 0 && array[preIndex] > temp) {

                    array[preIndex + gap] = array[preIndex];

                    preIndex -= gap;

                }

                array[preIndex + gap] = temp;

            }

            gap /= 2;

        }

        return array;

    } 

Quick sort

Basic idea of quick sort: divide the records to be arranged into two independent parts through one-time sorting. If the keywords of one part of the records are smaller than those of the other part, the two parts of the records can be sorted separately to achieve the order of the whole sequence

  • First, take a number from the sequence as the reference number.

  • In the partition process, all numbers larger than this number are placed on its right, and all numbers less than or equal to it are placed on its left.

  • Repeat the second step for the left and right intervals until there is only one number in each interval.

Implementation 1

public class QuickSort {

    public static void quickSort(int[]arr,int low,int high){

         if (low < high) {     

             int middle = getMiddle(arr, low, high);     

             quickSort(arr, low, middle - 1);//Recursive left 

             quickSort(arr, middle + 1, high);//Recursive right 

          }  

    }

    public static int getMiddle(int[] list, int low, int high) {     

        int tmp = list[low];    

        while (low < high) {     

            while (low < high && list[high] >= tmp) {//Greater than the keyword is on the right

                high--;     

            }     

            list[low] = list[high];//If less than the keyword, switch to the left 

            while (low < high && list[low] <= tmp) {//Less than the keyword is on the left

                low++;     

            }     

            list[high] = list[low];//If it is greater than the keyword, switch to the left 

        }     

       list[low] = tmp;           

       return low;                   

    } 

} 

Implementation 2

public class QuickSort {

 

	public static void quickSort(int data[], int left, int right) {

 

		int base = data[left]; // Benchmark number, take the first of the sequence

		int ll = left; // It shows the position from the left

		int rr = right; // Indicates the position to find from the right

		while (ll < rr) {

			// Find a number smaller than the benchmark number from the back

			while (ll < rr && data[rr] >= base) {

				rr--;

			}

			if (ll < rr) { // It means finding something bigger than it

				int temp = data[rr];

				data[rr] = data[ll];

				data[ll] = temp;

				ll++;

			}

			while (ll < rr && data[ll] <= base) {

				ll++;

			}

			if (ll < rr) {

				int temp = data[rr];

				data[rr] = data[ll];

				data[ll] = temp;

				rr--;

			}

		}

		// It must be that recursion is divided into three parts. Continue to quickly arrange left and right. Pay attention to adding conditions, otherwise recursion will overflow the stack

		if (left < ll)

			quickSort(data, left, ll - 1);

		if (ll < right)

			quickSort(data, ll + 1, right);

	}

} 

optimization

Basic quick sort selects the first or last element as the benchmark. However, this has been a very bad way to deal with it

If the array is already ordered, the segmentation at this time is a very bad segmentation. Because each partition can only reduce the sequence to be sorted by one, this is the worst case, and the quick sort is reduced to bubble sort, with a time complexity of O(n^2)

Triple median

The general practice is to use the median of the three elements at the left end, right end and center as the hub element

For example, the sequence to be sorted is 8 1 4 9 6 3 5 2 7 0

8 on the left, 0 on the right and 6 in the middle

After we sort the three numbers here, the middle number is used as the pivot, and the pivot is 6

Insert sort

When the length of the sequence to be sorted is divided to a certain size, insert sorting is used. Reason: for small and partially ordered arrays, it is better to arrange quickly than to arrange well. When the length of the sequence to be sorted is divided to a certain size, the efficiency of continuous segmentation is worse than that of insertion sorting. At this time, interpolation can be used instead of fast sorting

Repeating array

After one split, you can gather the elements equal to the key together. When you continue the next split, you don't need to split the elements equal to the key

After a partition, the elements equal to the key are gathered together, which can reduce the number of iterations and improve the efficiency

Specific process: there are two steps in the processing process

The first step is to put the elements equal to key into both ends of the array during the partition process

The second step is to move the element equal to the key around the pivot after the division

give an example:

Sequence to be sorted 1 4 6 7 6 6 7 6 8 6

Select pivot from three values: Number 6 with subscript 4

After conversion, the sequence to be divided: 6 4 6 7 1 6 7 6 8 6

Pivot key: 6

The first step is to put the elements equal to key into both ends of the array during the partition process

The result is: 6 4 1 6 (pivot) 7 8 7 6 6 6

At this point, all elements equal to 6 are placed at both ends

The second step is to move the element equal to the key around the pivot after the division

The result is: 1 4 6 6 6 (pivot) 6 6 6 7 8 7

At this point, all elements equal to 6 are moved around the pivot

After that, fast sorting was performed in two subsequences: 1,4 and 7,8,7

Heap sort

Heap is a special kind of tree. As long as these two points are met, it is a heap.

  • Heap is a complete binary tree;

  • The value of each node in the heap must be greater than or equal to (or less than or equal to) the value of each node in its subtree.

The heap whose value of each node is greater than or equal to the value of each node in the subtree is called "large top heap".

The heap whose value of each node is less than or equal to the value of each node in the subtree is called "small top heap".

Generally, large root heap is used in ascending order and small root heap is used in descending order

How to implement a heap

A complete binary tree is more suitable for storing arrays. Using an array to store a complete binary tree is very memory saving. Because we do not need to store the pointers of the left and right child nodes, we can find the left and right child nodes and parent nodes of a node simply through the subscript of the array.

For example, find the parent node and left and right child nodes of a number in array arr, such as the number with known index i

  1. Parent node index: (i-1)/2 (here, divide by 2 in the computer and omit the decimal)

  2. Left child index: 2*i+1

  3. Right child index: 2*i+2

Therefore, the definition and nature of heap:

  • Large root pile: arr (I) > arr (2 * I + 1) & & arr (I) > arr (2 * I + 2)

  • Small root pile: arr (I) < arr (2 * I + 1) & & arr (I) < arr (2 * I + 2)

last

Due to space constraints, Xiaobian cuts out several diagrams of knowledge explanation here, and the program ape (yuan) in need can praise it Stamp here to get all the information for free Get oh

For example, find the parent node and left and right child nodes of a number in array arr, such as the number with known index i

  1. Parent node index: (i-1)/2 (here, divide by 2 in the computer and omit the decimal)

  2. Left child index: 2*i+1

  3. Right child index: 2*i+2

Therefore, the definition and nature of heap:

  • Large root pile: arr (I) > arr (2 * I + 1) & & arr (I) > arr (2 * I + 2)

  • Small root pile: arr (I) < arr (2 * I + 1) & & arr (I) < arr (2 * I + 2)

last

Due to space constraints, Xiaobian cuts out several diagrams of knowledge explanation here, and the program ape (yuan) in need can praise it Stamp here to get all the information for free Get oh

[external chain picture transferring... (img-hBn9LJrq-1628293219717)]

[external chain picture transferring... (img-kZZcbSy6-1628293219718)]

[external chain pictures are being transferred... (img-fiOao87a-1628293219719)]

[external chain picture transferring... (img-ApK8ACpt-1628293219721)]

[external chain picture transferring... (img-th3OKQyn-1628293219723)]

Topics: Java Back-end Interview Programmer