Basic Operation of Search and Sort: Search and Sort Algorithms for Large Sets

Posted by mrcodex on Sun, 28 Jul 2019 06:44:49 +0200

A key

Search algorithms focus on: sequential search, binary search, hash table search, binary sort tree search.

The sorting algorithm focuses on bubble sorting, insertion sorting, merge sorting and fast sorting.

Sequential lookup

Algorithmic description

Sequential lookup of linear tables suitable for sequential or linked storage.

Algorithmic Thought

Sequential lookup, also known as linear lookup, belongs to the disordered lookup algorithm. Starting from one end of the data structure linear table, scan sequentially, and compare the key words of the scanned nodes with the given value k in turn. If they are equal, the search will be successful; if the key words equal to k are not found at the end of the scan, the search will fail.

Algorithmic Implementation

int sequenceSearch(int a[], int value, int len)
{
    int i;
    for(i=0; i<len; i++)
        if(a[i]==value)
            return i;
    return -1;
}

algorithm analysis

The average length of a successful lookup is (assuming that the probability of each data element is equal) ASL = 1/n(1+2+3 +). + n) = (n+1)/2; when the search is unsuccessful, it needs n+1 comparison, and the time complexity of sequential search is O(n); therefore, the time complexity of sequential search is O(n).

Binary search

Algorithmic description

Elements must be ordered, and if they are disordered, they must be sorted first.

Algorithmic Thought

Also known as half-fold search, it belongs to ordered search algorithm. Comparing the given value k with the keyword of the intermediate node, the middle node divides the linear table into two subtables, and if they are equal, the search is successful; if they are not equal, then according to the comparison result between k and the keyword of the intermediate node, it determines which subtable to look for next step, and so on, recursively proceeds until it finds or finds out that there is no such subtable at the end of the search. Sample nodes. Note: The precondition of half-fold search is to store ordered tables sequentially. For static lookup tables, once-rank does not change any more. Half-fold search can achieve good efficiency. However, for data sets that need frequent insertion or deletion operations, maintaining orderly sorting can cause a lot of work, so it is not recommended.

Algorithmic Implementation

//Binary Search, Conventional Edition
int binarySearch1(int a[], int value, int len)
{
    int low, high, mid;
    low = 0;
    high = len-1;
    while(low<=high)
    {
        mid = low+(high-low)/2;    //Preventing spillovers
        if(a[mid]==value)
            return mid;
        if(a[mid]>value)
            high = mid-1;
        if(a[mid]<value)
            low = mid+1;
    }
    return -1;
}
 
//Binary Search, Recursive Edition
int binarySearch2(int a[], int value, int low, int high)
{
    int mid = low+(high-low)/2;
    if(a[mid]==value)
        return mid;
    if(a[mid]>value)
        return BinarySearch2(a, value, low, mid-1);
    if(a[mid]<value)
        return BinarySearch2(a, value, mid+1, high);
}

algorithm analysis

In the worst case, the number of keyword comparisons is log2(n+1), so the time complexity is O(log2n).

 

Bubble sort

Algorithmic description

It belongs to exchange sort, stable sort

Algorithmic Thought

Compare the size of two adjacent numbers, put the largest number on the right, counter i ++;

Continue repeating operation 1 until the end of a[n-2] and a[n-1] comparisons, and the maximum value in array a has been in a[n-1];

Reduce the length of the sorted array n by 1, repeat operation 1 and operation 2 until n is 1, and the sorting is completed.

Algorithmic Implementation

void bubbleSort(int* array, int length)
{
    for (int i = 0; i < length - 1; ++i)
    {
        //bool is_Swap=false;
        for (int j = 0; j < length - 1 - i; ++j)
        {
            if (array[j] > array[j + 1])
            {
                //is_Swap=true;
                int temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
                /*
                Exchange can also be done in the following ways
                a = a + b;
                b = a - b;
                a = a - b;
                Exchange can also be done in the following ways
                a=a^b;
                b=b^a;
                a=a^b;
                */
            }
        }
        //if(is_Swap==false)
            //return;
    }
}

algorithm analysis

Average time complexity: O(n^2). Best case: If the sequence of data to be sorted is in order, the sorting can be completed by one trip of bubbling. The number of comparisons of sorting is n-1, and there is no movement, and the time complexity is O(n). To achieve O(n) complexity, you need to add a token (Bool variable) to the code. Worst case: If the sequence of data to be sorted is i n reverse order, bubbling sorting requires n-1 trips, each time for n-i sorting comparison and movement, that is, the number of comparison and movement reaches the maximum: the number of comparison = n(n_1)/2=O(n^2), the number of movement is equal to the number of comparison, so the worst time complexity is O(n^2).

 

Insertion sort

Algorithmic description

It belongs to insertion class sorting and stable sorting.

Algorithmic Thought

Starting with the second element of the array to be sorted, compare its size with the previous number, find the appropriate location and insert it until all elements have been inserted.

Algorithmic Implementation

void insertSort(int* array,int length) 
{
    int i = 0, j = 0, temp = 0;
    for (i = 1; i < length; ++i) 
    {
        //If the element is smaller than the previous element, all the elements larger than the element are moved one bit back.
        //Until you find where the element is to be inserted and insert it.
        if (array[i] < array[i-1])
        {
            temp = array[i];
            for (j = i-1; temp < array[j] && j >= 0 ; --j) 
            {
                array[j+1] = array[j];
            }
            array[j + 1] = temp;
        }
    }
}

algorithm analysis

Average time complexity: O (n ^ 2). Best case: When the records to be sorted are already in order, the number of times to compare is n-1=O(n). Worst case: If the record to be sorted is in reverse order, the maximum number of comparisons is n*(n-1)/2=O(n^2)

Merge Sort

Algorithmic description

It has wide application and stable ranking.

Algorithmic Thought

Merging and sorting is a typical application of dividing and dividing method. First, each subsequence is ordered, and then each subsequence is ordered. Combining two ordered subsequences into an ordered table is called two-way merging. Step: First, the ordinal sequence will be divided into two parts, two parts and four parts. Until there is only one data in each region, each subsequence can be regarded as an ordered sequence. Then merge. Each merge is an ordered sequence merge.

Algorithmic Implementation

 

void MergeArray(int* array, int first, int mid, int last, int* temp)
{
    //take a[first...mid]and a[mid+1...last]merge
    int i = first, j = mid + 1, k = 0;
    int lengthA = mid+1, lengthB = last+1;
    while (i < lengthA&&j < lengthB) 
    {
        if (array[i] < array[j])
            temp[k++] = array[i++];
        else
            temp[k++] = array[j++];
    }
    while (i < lengthA) 
    {
        temp[k++] = array[i++];
    }
    while (j < lengthB) 
    {
        temp[k++] = array[j++];
    }
    for (i = 0; i < k; ++i) 
    {
        array[first + i] = temp[i];
    }
}

void MergeSort(int* array, int first, int last, int* temp) 
{
    if (first >= last)
        return;
    int mid = (first + last) / 2;
    MergeSort(array, first, mid, temp);//Left order
    MergeSort(array, mid + 1, last, temp);//Order on the right
    MergeArray(array, first, mid, last, temp);//Merging two ordered subsequences
}

algorithm analysis

The average, best and worst time complexity is O(n*log n)

It can be understood that merging requires O(log n) steps, and that merging ordered subsequences at each step requires O(n) operations. The time complexity must be O(n*log n).

Quick sort

Algorithmic description

Fast ranking is the fastest among the sorting algorithms of exchange classes. The idea of divide-and-conquer is adopted and the order is unstable.

Algorithmic Thought

Choose one element from n elements as the criterion of partition, and generally choose the first element.

Put less than the element on the left, greater than or equal to the element on the right, and put the element in the middle.

Then repeat operations 1 and 2 on the left and right subsequences respectively until there is only one element in each subsequence and the sorting is completed.

Algorithmic Implementation

 

//Version 1
void QuickSort(int* array,int low,int high) 
{
    if (low >= high)
        return;
    int left = low;
    int right = high;
    int key = array[left];//Choose the first element as the distinguishing element, and of course the last one.
    while (left != right)
    {
        while (left != right&&array[right] >= key)//From right to left, put less than key The elements are placed in key On the left
            --right;
        array[left] = array[right];
        while (left != right&&array[left] <= key)//From left to right, the bar is larger than the bar. key The elements are placed in key To the right of the
            ++left;
        array[right] = array[left];
    }
    array[left] = key;//here left Be equal to right

    //One divides into two, divides and conquers the thought, recursively calls.
    QuickSort(array, low, left - 1);
    QuickSort(array, left + 1, high);
}

As we all know, Partition functions play an important role both in quick sorting and in finding the K-th problem, so we have Version 2 when we write them separately.

int Partition(int* array,int left,int right)
{
    int key = array[left];
    while (left != right)
    {
        while (left != right&&array[right] >= key)//From right to left, put less than key The elements are placed in key On the left
            --right;
        array[left] = array[right];
        while (left != right&&array[left] <= key)//From left to right, the bar is larger than the bar. key The elements are placed in key To the right of the
            ++left;
        array[right] = array[left];
    }
    array[left] = key;
    return left;//Return discernibility function
}

//Fast row principal function
void quicksort(int* arr, int left, int right)
{
    if(left< right)
    {
        int middle = mypartition(arr, left, right);
        quicksort(arr, left, middle-1);
        quicksort(arr, middle+1, right);
    }
}

algorithm analysis

 

Average time complexity: O(n*log n). Reason: Fast queuing divides an array into two to the end, so it needs O(log n) times. Each operation needs to be sorted n times. Therefore, in most cases, the time complexity is O(n*log n). Best case: After each sorting, each partition makes the length of the two subfiles roughly equal, and the time complexity is O(n*log n). Worst case: The elements to be sorted have been sorted. After the first n-1 comparison, the first element keeps its position unchanged and a sub-sequence of n-1 elements is obtained; after the second n-2 comparison, the second element is located in its original position and a sub-sequence of n-2 elements is obtained, and the total number of comparisons is n(n-1)/2=O(n^2).

Topics: Oracle less