目录
注:以下排序均默认为升序排序。
冒泡排序
一、基本思想:
从前往后,依次比较相邻的两个数,把较大的数放到后面;一次循环后,可以在当前最末尾位置得到一个当次循环的最大值。
- 时间复杂度:O(n²)
- 空间复杂度:O(1)
- 排序稳定程度 :稳定
- 缺点:传统的冒泡排序中每一趟排序只能找到一个最大值或最小值,效率低。
二、代码实现:
-----------------------------------C#------------------------------------------------
#include<stdio.h>
void Swap(int* a, int* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
void Bubble(int arr[], int size)
{
if (size <= 1)
return;
int ret;
//依次将最大的数放置到数组末尾,将第二大的数放到倒数第二位...
for (int i = 0; i < size - 1; ++i)
{
ret = 1;
//从前往后,比较相邻两个数,把大的放在后边.之前已放置成功的可以不再参与比较
for (int j = 0; j < size - 1 - i; ++j)
{
if (arr[j] > arr[j + 1])
{
Swap(&arr[j], &arr[j + 1]);
ret = 0;
}
}
//冒泡每次都会比较相邻两个数并交换次序不对的组,若一次循环后,都没进行交换,则已经完成排序
if (ret)
break;
}
}
//test.c
int main()
{
int arr[] = { 3,4,5,1,2};
int size = sizeof(arr) / sizeof(arr[0]);
Bubble(arr, size);
for (int i = 0; i < size; ++i)
printf("%d", arr[i]);
system("pause");
return 0;
}
-------------------------------------C++---------------------------------------------
#include<vector>
#include<iostream>
using namespace std;
class Bubble
{
public:
vector<int> sort(vector<int> arr)
{
vector<int> ret;
if (arr.size() <= 1)
return ret;
int changed;//标识位
//依次将最大的数放置到数组末尾,将第二大的数放到倒数第二位...
for (int i = 0; i < arr.size()-1; i++)
{
changed = 1;
//从前往后,比较相邻两个数,把大的放在后边.之前已放置成功的可以不再参与比较
for (int j = 0; j < arr.size() - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
//arr=swap(arr,j,j+1);
changed = 0;
}
}
//冒泡每次都会比较相邻两个数并交换次序不对的组,若一次循环后,都没进行交换,则已经完成排序
if (changed)
break;
}
ret = arr;
return ret;
}
/*
vector<int> swap(vector<int> arr, int a, int b)
{
vector<int> ret;
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
ret = arr;
return ret;
}
*/
};
//test.c
int main()
{
vector<int> array{ 3, 4, 5, 1, 2 };
vector<int>ret;
Bubble b;
ret=b.sort(array);
for (int i = 0;i<ret.size();++i)
{
cout << ret[i];
}
cout << endl;
system("pause");
return 0;
}
选择排序
一、基本思想:
首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
- 时间复杂度 :O(n²)
- 空间复杂度 :O(1)
- 排序稳定程度 :不稳定
- 适用场景:数据规模越小越好
二、代码实现:
void Swap(int* a, int* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
void SelectSort(int arr[], int size)
{
if (size <= 1)
return;
int min, ret;
for (int i = 0; i < size - 1; ++i)
{
min = i;
for (int j = i + 1; j < size; ++j)
{
if (arr[min] > arr[j])
min = j;//找出当前最小元素的位置
}
Swap(&arr[min], &arr[i]);
}
}
//test.c
int main()
{
int arr[] = { 3,4,5,1,2};
int size = sizeof(arr) / sizeof(arr[0]);
SelectSort(arr, size);
for (int i = 0; i < size; ++i)
printf("%d", arr[i]);
system("pause");
return 0;
}
直接插入排序
一、基本思想:
通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。也就是说:从第二个元素开始,将当前元素插入到前面对应位置,使当前元素i和之前元素形成有序数组。
- 时间复杂度:O(n²)
- 空间复杂度:O(1)
- 排序稳定程度:稳定
- 适用场景:数据量小,元素接近有序。(尽可能少搬移元素)
二、代码实现:
void Swap(int* a, int* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
void InsertSort(int arr[], int size)
{
if (size <= 1) {
return;
}
int pos;
for (int i = 1; i < size; ++i)
{
pos = i;
while (pos != 0 && arr[pos] < arr[pos - 1])
{
Swap(&arr[pos], &arr[pos - 1]);
pos--;
}
}
}
//test.c
int main()
{
int arr[] = {3,4,5,1,2};
int size = sizeof(arr) / sizeof(arr[0]);
InsertSort(arr, size);
for (int i = 0; i < size; ++i)
printf("%d", arr[i]);
system("pause");
return 0;
}