1.插入排序
插入排序是一种简单的排序算法,其工作原理类似于对手中的扑克牌进行排序。该数组实际上分为已排序部分和未排序部分。未排序部分的值被拾取并放置在已排序部分的正确位置。当问题规模较小(因为它的开销较低)或当数据接近排序时(因为它是自适应的),插入排序速度很快并且最适合。
示例:
elements: 9, 6, 5, 0, 8, 2, 7, 1, 3, 4
i : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
让我们循环 for i = 1(数组的第二个元素)到 9(数组的最后一个元素)
我=1。由于 6 小于 9,因此移动 9 并在 9 之前插入 6
6 , 9, 5, 0, 8, 2, 7, 1, 3, 4
我=2。由于 5 小于 6 和 9,因此将 5 移到 6 和 9 之前
5, 6, 9, 0, 8, 2, 7, 1, 3, 4
我=3。由于 0 小于 5,6 和 9,因此将 0 移到 5,6,9
0, 5, 6, 9, 8, 2, 7, 1, 3, 4之前
我=4。由于 8 小于 9,因此将 8 移到 9 之前
0, 5, 6, 8, 9, 2, 7, 1, 3, 4
我=5。由于 2 小于 5,6,8 和 9,因此将 2 移到 5,6,8,9
0, 2, 5, 6, 8, 9, 7, 1, 3, 4之前
我=6。0, 2, 5, 6, 7, 8, 9, 1, 3, 4
i=7。0, 1, 2, 5, 6, 7, 8, 9, 3, 4
i=8。0, 1, 2, 3, 5, 6, 7, 8, 9, 4
i=9。0、1、2、3、4、5、6、7、8、9
插入排序
算法:
插入排序(A)
{
for j=i to A.length
key = A[i];
// 将 A[i] 插入已排序序列 A[1,2,3,..,i-1]
j= i-1;
while (j>0 且 A[j]>key)
A[j+1] = A[j]
j= j-1
A[j+1] = key
}
// C program for insertion sort
#include <math.h>
#include <stdio.h>
/* Function to sort an array using insertion sort*/
void insertionSort(int arr[], int n)
{
int i, key, j;
for (i = 1; i < n; i++)
{
key = arr[i];
j = i - 1;
/* Move elements of arr[0..i-1], that are greater than key, to one position ahead
of their current position */
while (j >= 0 && arr[j] > key)
{
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key;
}
}
// A utility function to print an array of size n
void printArray(int arr[], int n)
{
int i;
for (i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("\n");
}
/* Driver program to test insertion sort */
int main()
{
int arr[] = {12, 11, 13, 5, 6};
int n = sizeof(arr) / sizeof(arr[0]);
insertionSort(arr, n);
printArray(arr, n);
return 0;
}
2. 选择排序
选择排序算法通过从未排序的部分中重复查找最小元素(考虑升序)并将其放在开头来对数组进行排序。该算法在给定数组中维护两个子数组:
- 已经排序的子数组
- 剩余未排序的子数组
在选择排序的每次迭代/传递中,都会从未排序的子数组中选取最小元素(考虑升序)并将其移至已排序的子数组。选择排序具有最小化交换次数的特性。因此,当交换成本较高时,它是最佳选择。
示例:
arr[]= 23 78 45 8 32 46
Pass 1
// 找到arr[0...5]中的最小元素并将其放在开头
8 78 45 23 32 46
Pass 2
// 找到arr[1...5]中的最小元素并将其放在arr[1...5]的开头
8 23 45 78 32 46
Pass 3
// 找到arr[2...5]中的最小元素并将其放在arr[2...5]的开头
8 23 32 78 45 46
Pass 4
// 找到arr[3...5]中的最小元素并将其放在arr[3...5]的开头
8 23 32 45 78 46
Pass 5
// 找到arr[4...5]中的最小元素并将其放在arr[4...5]的开头
8 23 32 45 46 78
选择排序
算法:
void SelectionSort (int a[], int n)
{
int i,j, temp, min;
for (i=0; i<n-1; i++)
{
min = i;
for (j=i+1; j<n; j++)
if (a[j] < a[min])
{
min = j;
}
温度 = a[i];
a[i] = a[min];
a[分钟] = 温度;
}
}
// C program for implementation of selection sort
#include <stdio.h>
void swap(int *xp, int *yp)
{
int temp = *xp;
*xp = *yp;
*yp = temp;
}
void selectionSort(int arr[], int n)
{
int i, j, min_idx;
// One by one move boundary of unsorted subarray
for (i = 0; i < n - 1; i++)
{
// Find the minimum element in unsorted array
min_idx = i;
for (j = i + 1; j < n; j++)
if (arr[j] < arr[min_idx])
min_idx = j;
// Swap the found minimum element with the first element
swap(&arr[min_idx], &arr[i]);
}
}
/* 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, 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 )
冒泡排序
算法:
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) 排序时,合并排序是唯一的选择。
合并()函数
合并过程也称为异地过程
算法:
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)
### 最后的话
最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!
### 资料预览
给大家整理的视频资料:
![](https://img-blog.csdnimg.cn/img_convert/63114f019fe0c41406cdb1067b271565.png)
给大家整理的电子书资料:
![](https://img-blog.csdnimg.cn/img_convert/681f97a75809f66e6c3e4dec919251dc.png)
**如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!**
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618542503)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
hile (i < n1)
### 最后的话
最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!
### 资料预览
给大家整理的视频资料:
[外链图片转存中...(img-IH46Hk3e-1714121534814)]
给大家整理的电子书资料:
[外链图片转存中...(img-VhmtDo16-1714121534815)]
**如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!**
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618542503)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**