[C++ implements recursive algorithm, merge sort and heap sort]

1. Recursive algorithm

When we need to execute an algorithm repeatedly, using a recursive algorithm can be a good choice. In this algorithm, a function calls itself until a certain condition is reached which stops the recursion . Recursion is supported in the C++ language. Let's introduce in detail how to use C++ to implement recursive algorithms.

In this tutorial, we will introduce the implementation of the recursive algorithm by taking the Fibonacci sequence as an example.

The Fibonacci sequence, also known as the golden section sequence, was introduced by the mathematician Leonardo Fibonacci with the example of rabbit breeding, so it is also called the "rabbit sequence". It is such a sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, ... In mathematics, the Fibonacci sequence is defined recursively as follows: F (0)= 1, F (1)=1, F (n)= F (n - 1) + F (n - 2) ( n ≥ 2, n ∈ N*)

1. Define the function

First, we need to define a function for computing the nth term of the Fibonacci sequence. Considering that the 0th and 1st items of the Fibonacci sequence are known, we can divide the function into two cases: when n is 0 or 1, we directly return the value of n; otherwise we return Fibonacci The sum of the n-1 and n-2 terms in the Natch sequence. code show as below:

int fibonacci(int n) {
    
    
    if (n == 0 || n == 1) {
    
    
        return n;
    }
    else {
    
    
        return fibonacci(n - 1) + fibonacci(n - 2);
    }
}

2. Test function

We can use this function for testing, calculating the first few terms of the Fibonacci sequence. For example, we can use the following code to calculate the first 10 terms of the Fibonacci sequence:

int main() {
    
    
    for (int i = 0; i < 10; i++) {
    
    
        cout << fibonacci(i) << " ";
    }
    return 0;
}

3. Analyze recursive algorithm

In this example, a recursive algorithm can be used to calculate the nth term of the Fibonacci sequence, with the recursive formula:

F(n) = F(n-1) + F(n-2)

Among them, F(n) represents the nth item of the Fibonacci sequence. When n=0 or 1, we directly return n itself.

It should be noted that in the recursive algorithm, the conditions for terminating the recursion need to be set. In this example, we set the recursion to terminate when n=0 or 1. If the condition to terminate the recursion is not set or the termination condition is set incorrectly, the recursion will continue to execute indefinitely, resulting in problems such as stack overflow.

4. Summary

This tutorial introduces the basic steps of implementing a recursive algorithm using C++, taking the Fibonacci sequence as an example. From defining functions, testing functions to analyzing recursive algorithms, this tutorial hopes to help you better understand the concept of recursive algorithms and master their implementation methods.

The complete code is as follows:

#include<iostream>
using namespace std;
int fibonacci(int n);
int main()
{
    
    
	for (int i = 0; i < 10; i++) {
    
    
        cout << fibonacci(i) << " ";
    }
    return 0;

}

int fibonacci(int n) {
    
    
    if (n == 0 || n == 1) {
    
    
        return n;
    }
    else {
    
    
        return fibonacci(n - 1) + fibonacci(n - 2);
    }
}

2. Merge sort

Merge Sort (Merge Sort) is a divide-and-conquer algorithm. Its basic idea is to recursively split a large array into two small arrays until it can no longer be divided, and then merge these small arrays in pairs and continuously merge them. until the original array is completely sorted . Merge sort is stable, the time complexity is stable at O(nlogn), and the space complexity is O(n).

The following steps will introduce the detailed implementation of merge sort.

1. Divide

First, the array to be sorted is recursively divided into two sub-arrays until each sub-array has only one element. This means that the array has been decomposed into n subarrays of length 1.

2. Merge

Merge the sub-arrays two by two to get n/2 sorted sub-arrays, and then merge these sorted sub-arrays again until only one sorted array of length n is left. The steps to merge two sorted subarrays are:

(1) Create an empty array to store the merged elements.

(2) Traverse the two sorted arrays at the same time, compare their first elements, and add the smaller elements to the new array.

(3) Repeat the above steps until all the elements in one of the arrays are put into the new array.

(4) Add all elements in another array directly to the end of the new array.

(5) Return the new array.

3. Code implementation of merge sort

The following is the code implementation of merge sort:

void merge(int nums[], int left, int mid, int right) {
    
    
    /*将原数组分成两个部分,左半部分为[nums[left], nums[mid]],
    右半部分为[nums[mid + 1], nums[right]]*/
    int n1 = mid - left + 1;
    int n2 = right - mid;
    int L[n1], R[n2];
    for (int i = 0; i < n1; i++) {
    
    
        L[i] = nums[left + i];
    }
    for (int i = 0; i < n2; i++) {
    
    
        R[i] = nums[mid + 1 + i];
    }
    // 将两个数组合并为一个升序数组
    int i = 0, j = 0, k = left;
    while (i < n1 && j < n2) {
    
    
        if (L[i] <= R[j]) {
    
    
            nums[k++] = L[i++];
        }
        else {
    
    
            nums[k++] = R[j++];
        }
    }
    while (i < n1) {
    
    
        nums[k++] = L[i++];
    }
    while (j < n2) {
    
    
        nums[k++] = R[j++];
    }
}

void mergeSort(int nums[], int left, int right) {
    
    
    if (left < right) {
    
    
        int mid = left + (right - left) / 2;
        mergeSort(nums, left, mid);
        mergeSort(nums, mid + 1, right);
        merge(nums, left, mid, right);
    }
}

4. Test code

Here is a test code:

int main() {
    
    
    int nums[] = {
    
    2, 5, 1, 6, 3, 8, 4, 7};
    int len=sizeof(nums)/sizeof(nums[0]);
    cout<<"排序前:";
	for (int i=0;i<len;i++) {
    
    
        cout << nums[i] << " ";
    } 
	mergeSort(nums, 0, len - 1);
    cout<<"\n排序后:"; 
	for (int i=0;i<len;i++) {
    
    
        cout << nums[i] << " ";
    }
    return 0;
}

In the above code, from the test data {2, 5, 1, 6, 3, 8, 4, 7}, the sorted data obtained by merge sort is {1, 2, 3, 4, 5, 6, 7 , 8}.

5. Summary

Merge sort is an efficient sorting algorithm that recursively divides an array in half and then merges the two halves into a sorted array. Sorting can be efficiently implemented under large-scale data. It should be noted that the implementation process of merge sort involves a lot of pointers and loops, and more care needs to be taken during implementation to avoid problems such as crossing the boundary.

6. Complete code

#include<iostream>
using namespace std;

void merge(int nums[], int left, int mid, int right) {
    
    
    /*将原数组分成两个部分,左半部分为[nums[left], nums[mid]],
    右半部分为[nums[mid + 1], nums[right]]*/
    int n1 = mid - left + 1;
    int n2 = right - mid;
    int L[n1], R[n2];
    for (int i = 0; i < n1; i++) {
    
    
        L[i] = nums[left + i];
    }
    for (int i = 0; i < n2; i++) {
    
    
        R[i] = nums[mid + 1 + i];
    }
    // 将两个数组合并为一个升序数组
    int i = 0, j = 0, k = left;
    while (i < n1 && j < n2) {
    
    
        if (L[i] <= R[j]) {
    
    
            nums[k++] = L[i++];
        }
        else {
    
    
            nums[k++] = R[j++];
        }
    }
    while (i < n1) {
    
    
        nums[k++] = L[i++];
    }
    while (j < n2) {
    
    
        nums[k++] = R[j++];
    }
}

void mergeSort(int nums[], int left, int right) {
    
    
    if (left < right) {
    
    
        int mid = left + (right - left) / 2;
        mergeSort(nums, left, mid);
        mergeSort(nums, mid + 1, right);
        merge(nums, left, mid, right);
    }
}
int main() {
    
    
    int nums[] = {
    
    2, 5, 1, 6, 3, 8, 4, 7};
    int len=sizeof(nums)/sizeof(nums[0]);
    cout<<"排序前:";
	for (int i=0;i<len;i++) {
    
    
        cout << nums[i] << " ";
    } 
	mergeSort(nums, 0, len - 1);
    cout<<"\n排序后:"; 
	for (int i=0;i<len;i++) {
    
    
        cout << nums[i] << " ";
    }
    return 0;
}

3. Heap sort

Heap sort is a sorting algorithm based on binary heap, its time complexity is O(nlogn), and it is widely used in practical applications. The basic idea of ​​heap sorting is to build the sequence to be sorted into a binary heap, and then take out the top elements of the heap in turn until the heap is empty .

1. Definition of heap

A heap is a complete binary tree, which is divided into two types: max-heap and min-heap.

Max heap: The value of each node is greater than or equal to the value of its left and right child nodes.

Min-heap: The value of each node is less than or equal to the value of its left and right child nodes.

2. The basic idea of ​​heap sorting

The basic idea of ​​heap sorting is to build the sequence to be sorted into a binary heap, and then take out the top elements of the heap in turn until the heap is empty. The specific process is as follows:

(1) Construct the sequence to be sorted into a maximum heap.

(2) Exchange the elements at the top of the heap with the elements at the bottom of the heap, remove the elements at the bottom of the heap, and rebuild the remaining elements into a maximum heap.

(3) Repeat step (2) until the heap is empty.

3. Implementation of heap sort

(1) Build the largest heap

The process of constructing the maximum heap can adopt a bottom-up method, starting from the last non-leaf node, and adjusting each node to its subtree in turn to become the maximum heap. The specific implementation is as follows:

void AdjustHeap(int arr[], int i, int n)
{
    
    
    int temp = arr[i];
    int j = 2 * i + 1;
    while (j < n)
    {
    
    
        if (j + 1 < n && arr[j + 1] > arr[j])
        {
    
    
            j++;
        }
        if (arr[j] > temp)
        {
    
    
            arr[i] = arr[j];
            i = j;
            j = 2 * i + 1;
        }
        else
        {
    
    
            break;
        }
    }
    arr[i] = temp;
}

void buildMaxHeap(int arr[], int n)
{
    
    
    for (int i = n / 2 - 1; i >= 0; i--)
    {
    
    
        AdjustHeap(arr, i, n);
    }
}

(2) Heap sort

The implementation process of heap sort is as follows:

void heapSort(int arr[], int n)
{
    
    
    buildMaxHeap(arr, n);
    for (int i = n - 1; i > 0; i--)
    {
    
    
        swap(arr[0], arr[i]);
        AdjustHeap(arr, 0, i);
    }
}

4. Optimization of heap sorting

(1) Optimize the heap building process

In the process of building a heap, for a node i, its left and right child nodes are 2i+1 and 2i+2 respectively. If the larger value of the left and right child nodes is greater than the value of the i node, then it is necessary to combine the larger value with The i-node swaps, and then continues to adjust downwards. This process can be implemented with a loop, which avoids recursive calls and improves efficiency.

void AdjustHeap(int arr[], int i, int n)
{
    
    
    int temp = arr[i];
    for (int j = 2 * i + 1; j < n; j = 2 * j + 1)
    {
    
    
        if (j + 1 < n && arr[j + 1] > arr[j])
        {
    
    
            j++;
        }
        if (arr[j] > temp)
        {
    
    
            arr[i] = arr[j];
            i = j;
        }
        else
        {
    
    
            break;
        }
    }
    arr[i] = temp;
}

(2) Optimize the sorting process

During the sorting process, each time the top element of the heap is exchanged with the bottom element of the heap, the size of the heap is reduced by 1, and then the heap needs to be readjusted. However, since the bottom element of the heap has been exchanged to the top of the heap, and the part above the bottom element of the heap is still a maximum heap, the top element of the heap can be adjusted directly without rebuilding the entire heap, which can reduce some unnecessary operation.

void heapSort(int arr[], int n)
{
    
    
    buildMaxHeap(arr, n);
    for (int i = n - 1; i > 0; i--)
    {
    
    
        swap(arr[0], arr[i]);
        AdjustHeap(arr, 0, i);
    }
}

5. The stability of heap sorting

Heap sort is an unstable sorting algorithm, because in the process of adjusting the heap, the positions of the same elements may be exchanged. For example, for the sequence {5, 2, 5, 1, 6, 2}, after heap sorting, it may become {1, 2, 2, 5, 5, 6}, where the relative positions of two 2s occur Change.

6. Complete code

#include<iostream>
using namespace std;
//构建最大堆 
void AdjustHeap(int arr[], int i, int n)
{
    
    
    int temp = arr[i];
    for (int j = 2 * i + 1; j < n; j = 2 * j + 1)
    {
    
    
        if (j + 1 < n && arr[j + 1] > arr[j])
        {
    
    
            j++;
        }
        if (arr[j] > temp)
        {
    
    
            arr[i] = arr[j];
            i = j;
        }
        else
        {
    
    
            break;
        }
    }
    arr[i] = temp;
}

void buildMaxHeap(int arr[], int n)
{
    
    
    for (int i = n / 2 - 1; i >= 0; i--)
    {
    
    
        AdjustHeap(arr, i, n);
    }
}
//堆排序 
void heapSort(int arr[], int n)
{
    
    
    buildMaxHeap(arr, n);
    for (int i = n - 1; i > 0; i--)
    {
    
    
        swap(arr[0], arr[i]);
        AdjustHeap(arr, 0, i);
    }
}

int main()
{
    
    
	int arr[]={
    
    4,6,3,7,2,9};
	int len=sizeof(arr)/sizeof(arr[0]);
	cout<<"原数组:"; 
	for(int i=0;i<len;i++){
    
    
		cout<<arr[i]<<" ";
	}	
	heapSort(arr,len);
	cout<<endl;
	cout<<"排序后:";
	for(int i=0;i<len;i++){
    
    
		cout<<arr[i]<<" ";
	}
 } 

Guess you like

Origin blog.csdn.net/qq_43884946/article/details/131186691