2024年最新5种经典排序算法,每个程序员都应该知道

void printArray(int arr[], int size)
{
int i;
for (i = 0; i < size; i++)
printf(“%d “, arr[i]);
printf(”\n”);
}

// Driver program to test above functions
int main()
{
int arr[] = {64, 25, 12, 22, 11};
int n = sizeof(arr) / sizeof(arr[0]);
selectionSort(arr, n);
printf(“Sorted array: \n”);
printArray(arr, n);
return 0;
}













## 3.冒泡排序


冒泡排序是一种排序算法,如果相邻元素的顺序错误,则重复交换相邻元素。每次迭代或传递后,最大的元素到达末尾(在升序的情况下)或最小的元素到达末尾(在降序的情况下)。重复遍历列表直到列表被排序。该算法不适合大型数据集,因为其平均和最坏情况复杂度为 Ο(n^2),其中*n*是项目数



示例:
64 34 25 12 22 11 90
迭代 1:
( 64 34 25 12 22 11 90) -> ( 34 64 25 12 22 11 90),这里,算法比较前两个元素,并从 64 > 34 开始交换。
(34 64 25 12 22 11 90) - > (34 25 64 12 22 11 90),从 64 开始交换 > 25
(34 25 64 12 22 11 90) -> (34 25 12 64 22 11 90),从 64 开始交换 > 12
(34 25 12 64 22 11 90) ) -> (34 25 12 22 64 11 90),从 64 > 22 开始交换
(34 25 12 22 64 11 90) -> (34 25 12 22 11 64 90),从 64 > 11 开始交换
(34 25 12 22 11) 64 90 ) -> (34 25 12 22 11 64 90 ),现在,由于这些元素已经按顺序排列 (90 > 64),算法不会交换它们。
迭代 2:(
34 25 12 22 11 64 90) -> ( 25 34 12 22 11 64 90),从 34 > 25 开始交换
( 25 34 12 22 11 64 90) -> (25 12 34 22 11 64 90),自 34 > 12 起交换(25 12 34 22 11 64 90) -> (25 12 22 34 11 64 90),自 34 > 22 起交换(25 12 22 34 11 64 90) -> (25 12 22 11 34 64 90) ),交换自 34 > 11(25 12 22 11 34 64 90) -> (25 12 22 11 34 64 90),现在,由于这些元素已经按顺序排列 (64 > 34),算法不会交换它们。

迭代 3:
( 25 12 22 11 34 64 90) -> ( 12 25 22 11 34 64 90),从 25 > 12 开始交换
(12 25 22 11 34 64 90) -> (12 22 25 11 34 64 90),自 25 > 22 起交换
(12 22 25 11 34 64 90) -> (12 22 11 25 34 64 90), 自 25 > 11 起交换
(12 22 11 25 34 64 90) -> (12 22 11 25 34 64 90) ),现在,由于这些元素已经按顺序排列 (34 > 25),算法不会交换它们。
迭代 4:
( 12 22 11 25 34 64 90) -> ( 12 22 11 25 34 64 90)
(12 22 11 25 34 64 90) -> (12 11 22 25 34 64 90),从 22 > 11 开始交换
( 12 11 22 25 34 64 90) -> (12 11 22 25 34 64 90)
迭代 5:(
12 11 22 25 34 64 90) -> ( 11 12 22 25 34 64 90),从 12 开始交换 > 11
(11 12 22 25 34 64 90) -> (11 12 22 25 34 64 90)
迭代 6:(
11 12 22 25 34 64 90) -> ( 11 12 22 25 34 64 90)
现在,数组已经排序了,但是我们的算法不知道它是否已完成。该算法需要一整遍而不需要任何交换才能知道它已排序。
迭代7:
( 11 12 22 25 34 64 90) -> ( 11 12 22 25 34 64 90)
(11 12 22 25 34 64 90) -> (11 12 22 25 34 64 90 ) ( 11 12 22 25 34 64 90) -> (11 12 22 25 34 64 90) (11 12 22 25 34 64 90) -> (11 12 22 25 34 64 90) (11 12 22 25 34 64 90) -> (11 12 22 25 34) 64 90) (11 12 22 25 34 64 90 ) -> (11 12 22 25 34 64 90 )




![冒泡排序的实现。](https://img-blog.csdnimg.cn/img_convert/c90d010afd19681f52f3c5e5cfd901e7.png)




冒泡排序



算法:
Bubble_Sort(int a[], n)
{
int swapped, i, j;
for (i=0; i<n; i++)
{
交换 = 0;
for (j=0; j<ni-1; j++)
{
if (a[j] > a[j+1])
{
交换 (a[j], a[j+1]); }
交换=1; if (交换== 0)
中断 ; } }





// C program for implementation of Bubble sort
#include <stdio.h>

void swap(int *xp, int *yp)
{
int temp = *xp;
*xp = *yp;
*yp = temp;
}

// An optimized version of Bubble Sort
void bubbleSort(int arr[], int n)
{
int i, j;
bool swapped;
for (i = 0; i < n-1; i++)
{
swapped = false;
for (j = 0; j < n-i-1; j++)
{
if (arr[j] > arr[j+1])
{
swap(&arr[j], &arr[j+1]);
swapped = true;
}
}

 // IF no two elements were swapped by inner loop, then break 
 if (swapped == false) 
    break; 

}
}

/* Function to print an array */
void printArray(int arr[], int size)
{
int i;
for (i=0; i < size; i++)
printf("%d ", arr[i]);
printf(“n”);
}

// Driver program to test above functions
int main()
{
int arr[] = {64, 34, 25, 12, 22, 11, 90};
int n = sizeof(arr)/sizeof(arr[0]);
bubbleSort(arr, n);
printf(“Sorted array: \n”);
printArray(arr, n);
return 0;
}











## 4. 归并排序


与上述三种排序算法不同,该算法基于分而治之技术。它将输入数组分为两半,为两半调用自身,然后合并已排序的两半。归并排序的核心是函数`merge()`,用于合并两半。merge(A, p, q, r) 是一个关键过程,它假设 A[p..q] 和 A[q+1..r] 已排序,并将两个已排序的子数组合并为一个。


当您需要稳定且 O(N log N) 排序时,合并排序是唯一的选择。


### 合并()函数


合并过程也称为异地过程




![归并排序的实现](https://img-blog.csdnimg.cn/img_convert/d097dbe7bb008e7bd7f08801c1e91ac4.png)





算法:
merge(A, p, q, r)
{
n1= q-p+1
n2= rq
设 L[1:n+1] 和 R[1:n2+1] 为
(i=1:n1) 的新数组
L[i]= A[p+i-1]
for (j=1:n2)
R[j]= A[q+j]
L[n1 + 1]= 无穷大
R[n2 + 1]= 无穷大
i= 1、j=1
for (k=p:r)
{
if (L[i] <= R[j])
A[k] = L[i]
i= i+1
else
A[k] = R[j ]
j= j+1
}
}


###### 



/* C program for Merge Sort */
#include <stdio.h>
#include <stdlib.h>

// Merges two subarrays of arr[].
// First subarray is arr[l…m]
// Second subarray is arr[m+1…r]
void merge(int arr[], int l, int m, int r)
{
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;

/* create temp arrays */
int L[n1], R[n2];

/* Copy data to temp arrays L[] and R[] */
for (i = 0; i < n1; i++)
    L[i] = arr[l + i];
for (j = 0; j < n2; j++)
    R[j] = arr[m + 1 + j];

/* Merge the temp arrays back into arr[l..r]*/
i = 0; // Initial index of first subarray
j = 0; // Initial index of second subarray
k = l; // Initial index of merged subarray
while (i < n1 && j < n2)
{
    if (L[i] <= R[j])
    {
        arr[k] = L[i];
        i++;
    }
    else
    {
        arr[k] = R[j];
        j++;
    }
    k++;
}

/* Copy the remaining elements of L[], if there 
are any */
while (i < n1)
{
    arr[k] = L[i];
    i++;
    k++;
}

/* Copy the remaining elements of R[], if there 
are any */
while (j < n2)
{
    arr[k] = R[j];
    j++;
    k++;
}

}

/* l is for left index and r is right index of the
sub-array of arr to be sorted */
void mergeSort(int arr[], int l, int r)
{
if (l < r)
{
// Same as (l+r)/2, but avoids overflow for
// large l and h
int m = l + (r - l) / 2;

    // Sort first and second halves
    mergeSort(arr, l, m);
    mergeSort(arr, m + 1, r);

    merge(arr, l, m, r);
}

}

/* UTILITY FUNCTIONS /
/
Function to print an array */
void printArray(int A[], int size)
{
int i;
for (i = 0; i < size; i++)
printf(“%d “, A[i]);
printf(”\n”);
}

/* Driver program to test above functions */
int main()
{
int arr[] = {12, 11, 13, 5, 6, 7};
int arr_size = sizeof(arr) / sizeof(arr[0]);

printf("Given array is \n");
printArray(arr, arr_size);

mergeSort(arr, 0, arr_size - 1);

printf("\nSorted array is \n");
printArray(arr, arr_size);
return 0;

}


### 合并排序


整个归并排序按以下方式工作:



![归并排序的实现。](https://img-blog.csdnimg.cn/img_convert/d04cc3c1e8608b5ab1bf5e1dc5a65d5e.png)



归并排序



算法:
Merge_Sort(A, p ,r)
{
if p<r
q= [(p+r)/2]
Merge_Sort(A, p ,q)
Merge_Sort(A, q+1, r)
merge(A, p, q, r)
}











## 5. 快速排序


快速排序也是一种分治算法。它选择一个元素作为主元,并围绕所选主元对给定数组进行分区,以便所有较小的元素都位于主元的左侧,所有较大的元素都位于主元的右侧。QuickSort 有许多不同的版本,它们以不同的方式选择枢轴:


* 始终选择第一个元素作为枢轴。
* 始终选择最后一个元素作为基准(在下面实现)。
* 选择一个随机元素作为基准。
* 选择中位数作为枢轴。


快速排序的关键过程是`partition()`方法。分区的目标是,给定一个数组和数组中的一个元素 r 作为主元,将*r*放在排序数组中的正确位置,并将所有较小的元素(小于*r*)放在*r*之前,并将所有较大的元素(大于 r )放在 r 之前。比*r* ) 在*r*之后。所有这些都应该在线性时间内完成。


对于小输入,与合并排序相比,快速排序是最好的算法。当您不需要稳定的排序并且平均情况性能比最坏情况性能更重要时,请选择快速排序。我们先看看分区算法及其实现。


### 分区()算法


我们从最右边的元素开始,并跟踪较小(或等于)元素的索引*r*。


* 如果我们找到小于*r*的元素*j*,则我们增加*i*指针并交换 i 和 j 的元素。
* 如果我们找到一个大于*r 的元素**j*,那么我们只需增加*j*指针即可。




![快速排序的实现。](https://img-blog.csdnimg.cn/img_convert/a931185fdb1332e80d53ed5d3a8d696f.png)




快速排序



算法:
分区(A, p, r)
{
x= A[r]
i= p-1
for (j= p:r-1)
{
if (A[j] <= x)
{
i= i+1
交换 A[ i] 与 A[j]
}
}
将 A[i+1] 与 A[r] 交换,
返回 i+1
}


### 快速排序


整个快速排序的工作原理如下:


* 它检查条件*p* < *r*。如果为 True,则进入 if 循环,否则退出循环
* 然后,应用分区算法来选择枢轴元素并将其放置在正确的位置。
* 经过分区算法后,整个数组被分为两半,所有小于主元元素的元素都在其左侧,所有大于主元元素的元素都在其右侧。
* 快速排序应用于两半。
* 整个循环继续将数组分成两部分,直到找到一个满足*p* > *r*的元素。



算法:
Quick_Sort(A, p ,r)
{
if (p<r)
{
q= 分区(A, p, r)
Quick_Sort(A, p, q-1)
Quick_Sort(A, q+1, r)
}
}




![快速排序的实现](https://img-blog.csdnimg.cn/img_convert/30e661f705c74eb72775aad0971f046a.png)




快速排序





/* C implementation QuickSort */
#include <stdio.h>

// A utility function to swap two elements
void swap(int *a, int *b)
{
int t = *a;
*a = *b;
*b = t;
}

/* This function takes last element as pivot, places the pivot element at its correct position in sorted
array, and places all smaller (smaller than pivot) to left of pivot and all greater elements to right
of pivot
*/
int partition(int arr[], int low, int high)
{
int pivot = arr[high]; // pivot
int i = (low - 1); // Index of smaller element

for (int j = low; j <= high - 1; j++)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以点击这里获取!

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 18
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值