Data structure---common sorting and quick sorting (c language)

Commonly used sort

Bubble Sort

Bubble sort algorithm idea

  • Starting from the head of the array , continuously compare the sizes of two adjacent elements, and let the larger element gradually move backward (exchange the values ​​of the two elements) until the end of the array. After the first round of comparison, the largest element can be found and moved to the last position.
  • After the first round, continue to the second round. The comparison is still from the head of the array , and the larger elements are gradually moved backwards until the second-to-last element of the array. After the second round of comparison, the next largest element can be found and placed in the penultimate position.
  • By analogy, after performing **n-1 (n is the length of the array)** rounds of "bubbling", all the elements can be arranged.

Bubble sort C language implementation

#include <stdio.h>

int main(){
    
    

    int nums[10] = {
    
    4, 5, 2, 10, 7, 1, 8, 3, 6, 9};
    int i, j, temp, isSorted;

    //优化算法:最多进行 n-1 轮比较

    for(i=0; i<10-1; i++){
    
    

        isSorted = 1; //假设剩下的元素已经排序好了

        for(j=0; j<10-1-i; j++){
    
    

            if(nums[j] > nums[j+1]){
    
    

                temp = nums[j];

                nums[j] = nums[j+1];

                nums[j+1] = temp;

                isSorted = 0; //一旦需要交换数组元素,就说明剩下的元素没有排序好

            }

        }

        if(isSorted) break; //如果没有发生交换,说明剩下的元素已经排序好了
}

    for(i=0; i<10; i++){
    
    

        printf("%d ", nums[i]);
    }

    printf("\n");

    return 0;
}

Insertion sort

Principle of simple insertion sort algorithm

  • Select an element from the entire sequence to be sorted and insert it into the already ordered subsequence to obtain an ordered subsequence with elements plus one. Until the elements to be inserted in the entire sequence are 0, the entire sequence is all ordered .

In actual algorithms, we often choose the first element of the sequence as an ordered sequence (because an element is definitely ordered), and we gradually insert the following elements into the previous ordered sequence until the entire sequence is ordered .

The schematic diagram is as follows:
Insert picture description here

Insert sort code implementation:

#include <stdio.h>

/*
直接插入排序:
    直接插入排序就是从待排序列中选出一个元素,插入到已经有序的元素之中,直到所有的元素都插入到有序序列中所有的元素就全部
有序了。
    通常的做法就是将第一个元素看做是有序的元素(即待排序列的第一个元素看做是有序序列),然后我们将第二个元素和有序序列(即
第一个元素)作比较,按正确的序列插入到序列中去。然后在将第三个元素和前面有序序列(即整个待排序列的前两个元素)作比较,将第
三个插入到前两个元素中去,使得前三个元素有序。以此类推,直到所有的元素都有序。
*/

void insertSort(int *arr[],int len);

int main(int argc, char *argv[])
{
    
    
    int arr[5]={
    
    
        3,89,72,43,1
    };
    insertSort(arr,5);
    int i;
    for(i=0;i<5;i++){
    
    
        printf("%d ",arr[i]);
    }
    return 0;
}

/*
简单插入排序函数
*/
void insertSort(int *arr[],int len){
    
    
    int i;
    int j;
    int temp;  //定义一个临时变量,用于交换数据时存储
    for(i=1;i<len;i++){
    
      //因为我们要对该待排序列的每一个元素都和前面的已排好序的序列进行插入,所以我们会对序列进行遍历
        for(j=0;j<i;j++){
    
      //第二层循环主要用于对已排好序的序列进行扫描,和要插入进来的数据进行逐一比较,然后决定插入到哪里
            if(arr[j]>arr[i]){
    
    //从前往后对已排好序的元素和待插入元素进行大小比较,然后直到找到一个元素比被插入元素大,则交换位置
                temp=arr[i];
                arr[i]=arr[j];
                arr[j]=temp;
            }
        }
    }
}

Select sort

Principles of Selection Sorting Algorithm

  • Selection sort is a simple and intuitive sorting algorithm. It is very similar to bubble sorting. It compares n-1 rounds, and each round compares n-1–i times, and finds a maximum or minimum value in each round.
  • However, bubble sorting puts the highest value found in each round to the far right, while selective sorting puts the highest value found in each round to the far left. And in algorithm, bubble sorting is to compare adjacent numbers one by one. Take sorting from small to large as an example. As long as the front is larger than the back, the two numbers are exchanged until the largest number is floated. "To the far right, and so on. The selection sort is to save the subscript of the first element first, and then all the following numbers are compared with the first element in turn. If a smaller number is encountered, the subscript of the smaller number is recorded, and then all the following numbers The numbers are compared with the smaller number in turn, until the subscript of the smallest number is found, and then the number is placed to the far left, that is, the number with the subscript 0 is interchanged. If the subscript of the smallest number is 0, then there is no need to swap.
  • Therefore, the selection sorting algorithm is to first determine whether the subscript of the smallest number is 0. If it is not, it means that the smallest number is not the first element, and then swap this number with the first element, so that the smallest number in a round That number was found and placed on the far left.
  • In the second round, the subscript of the second element of the new sequence is also saved, and all subsequent numbers are compared with the second element in turn. If a smaller number is encountered, the subscript of the smaller number is recorded, and then all subsequent numbers The numbers of are sequentially compared with the smaller number, until the smallest one is found at the end, and this smallest is the "second smallest" in the entire sequence. Then judge whether the subscript of this number is equal to 1, if it is not equal to 1, it means that the "second smallest" number is not the second element, then the number and the second element are swapped, so that the second round will be Find the "second smallest" number and place it in the second position. Repeat this way until the entire sequence is sorted from small to large.
  • If it is sorted from largest to smallest, then record the subscript of the largest number, and find the largest number in each round and put it on the left.

Selection of sorting algorithm implementation:

# include <stdio.h>
int main(void)
{
    
    
    int i, j;  //循环变量
    int MinIndex;  //保存最小的值的下标
    int buf;  //互换数据时的临时变量
    int a[] = {
    
    5, 5, 3, 7, 4, 2, 5, 4, 9, 1, 8, 6};
    int n = sizeof(a) / sizeof(a[0]);  //存放数组a中元素的个数
    for (i=0; i<n-1; ++i)  //n个数比较n-1轮
    {
    
    
        MinIndex = i;
        for (j=i+1; j<n; ++j)  //每轮比较n-1-i次, 找本轮最小数的下标
        {
    
    
            if (a[MinIndex] > a[j])
            {
    
    
                MinIndex = j;  //保存小的数的下标
            }
        }
        if (MinIndex != i)  /*找到最小数之后如果它的下标不是i则说明它不在最左边, 则互换位置*/
        {
    
    
            buf = a[MinIndex];
            a[MinIndex] = a[i];
            a[i] = buf;
        }
    }
    printf("最终排序结果为:\n");
    for (i=0; i<12; ++i)
    {
    
    
        printf("%d ", a[i]);
    }
    printf("\n");
    return 0;
}

Merge sort

Principle of merge sort algorithm:

  • (Merge Sort) is an effective sorting algorithm based on the merge operation. The algorithm is a very typical application using the divide and conquer method (Divide and Conquer). Combine existing ordered subsequences to obtain a completely ordered sequence; that is, first make each subsequence in order, and then make the subsequences in order. If two ordered lists are merged into one ordered list, it is called a two-way merge, an algorithm that sacrifices space for time in use.

Here comes from the reprinted source:
merge algorithm:

The core steps of the merge algorithm are:

  • break down
  • merge

Insert picture description here

  • Since merge sorting does not depend on the initial input state of the sequence of elements to be sorted, the length of the two sub-sequences is basically the same each time it is divided, so the merge sort is the best, and the worst and the worst average time complexity is O(n*log2^n ), Is a stable sorting algorithm
  • The optimization of merge sort , the use of insertion sort to process small-scale sub-arrays, generally can shorten the running time of merge sort by 10%~15%

Merge algorithm implementation (c language)

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
 
//分组归并
void _Merge(int *a, int begin1, int end1, int begin2, int end2, int *tmp)
{
    
    
	int index = begin1;
	int i = begin1, j = begin2;
	//注意:当划分的区间足够小时,begin1==end1,begin2==end2
	while (i <= end1&&j <= end2){
    
    
		if (a[i]<=a[j])
			tmp[index++] = a[i++];
		else
			tmp[index++] = a[j++];
	}
	//将左边元素填充到tmp中
	while (i <= end1)
		tmp[index++] = a[i++];
	//将右边元素填充的tmp中
	while (j <= end2)
		tmp[index++] = a[j++];
	//将tmp中的数据拷贝到原数组对应的序列区间
	//注意:end2-begin1+1
	memcpy(a + begin1, tmp + begin1, sizeof(int)*(end2 - begin1 + 1));
}
//归并排序
void MergeSort(int *a, int left, int right, int *tmp)
{
    
    
	if (left >= right)
		return;
	assert(a);
	//mid将数组二分
	int mid = left + ((right - left) >> 1);
	//左边归并排序,使得左子序列有序
	MergeSort(a, left, mid, tmp);
	//右边归并排序,使得右子序列有序
	MergeSort(a, mid + 1, right, tmp);
	//将两个有序子数组合并
	_Merge(a, left, mid, mid + 1, right, tmp);
}
//打印数组
void PrintArray(int *a, int len)
{
    
    
	assert(a);
	for (int i = 0; i < len; i++)
		printf("%d ", a[i]);
	printf("\n");
}
int main()
{
    
    
	int a[] = {
    
     10, 6, 7, 1, 3, 9, 4, 2 };
	int *tmp = (int *)malloc(sizeof(int)*(sizeof(a) / sizeof(int)));
	memset(tmp, -1, sizeof(a) / sizeof(int));
	MergeSort(a, 0, sizeof(a) / sizeof(int)-1, tmp);
	PrintArray(a, sizeof(a) / sizeof(int));
	system("pause");
	return 0;
}

Quick sort

Quick sort algorithm ideas:

  • Find the specific location of an element first , and divide the data into two parts
  • The one on the left is generally based on the method above , you can also find the specific position of an element, and then divide it into two parts
  • By analogy, the first element is finally found, using recursive thinking
    Insert picture description here

Quick sort implementation:

#include <stdio.h>
#include <stdlib.h>

int FindPos(int * a,int low,int high)
{
    
    
    int val = a[low];

    while(low < high)
    {
    
    
        while(low < high && a[high] <= val)
            --high;
        a[low] = a[high];

        while(low < high && a[low] <= val)
            ++low;
        a[high] = a[low];
    } //终止while循环之后,low和high一定是相等的
    a[low] = val;

    return low;   //low可以改为high,返回的是位置
}

void QuickSort(int * a,int low,int high)
{
    
    
    int pos;
    if(low < high)
    {
    
    
        pos = FindPos(a,low,high);
        QuickSort(a,low,pos-1);
        QuickSort(a,pos+1,high);
    }
}

int main()
{
    
    
    int a[6] = {
    
    -2,1,0,5,4,3};
    int i;
    QuickSort(a,0,5);   //第二个参数表示第一个元素的下标  第三个参数表示最后一个元素的下标
    for(i = 0; i < 6; ++i)
    {
    
    
        printf("%d",a[i]);
    }

    printf("\n");
    return 0;
}

Guess you like

Origin blog.csdn.net/qq_41782149/article/details/93378947