首先分为内部排序和外部排序,本文主要研究内部排序。
外部排序排序过程需要访问外存,内存外存也要结合使用,适合处理数据量很大的数据,
如1000T等,使用多路归并排序算法和败者树。
内部排序按照原理分为5大类。插入,选择,交换,归并,基数排序。
插入排序:直接插入排序,折半插入排序,希尔排序。
选择排序:简单选择排序,堆排序。
交换排序:冒泡排序,快速排序。
归并排序。(待更新)
基数排序。(待更新)
时间复杂度:算法执行的时间
空间复杂度:算法执行占用的内存
排序方式:in-place(占用常数内存,不占用额外内存),out-place(占用额外内存)
稳定性:原来相等的两个数排序后不乱序为稳定
#include
#include
using namespace std;
//时间复杂度:O(n2)
//空间复杂度:O(1)
// 稳定
void bubble_Sort(vector<int>& nums)
{
int n = nums.size();
bool valid = true;
for (int i = 0; i < n&&valid ; i++)
{
valid=false;
for (int j = n - 2; j >= i; j--)//气泡一样往前冒
{
if (nums[j] > nums[j + 1])
{
swap(nums[j], nums[j + 1]);
valid=true;//交换成功为true
// int temp = nums[j];
// nums[j] = nums[j + 1];
// nums[j + 1] = temp;
}
}
}
}
int main()
{
vector<int>v{ 1,10,24,12,16,8,18,89,25 };
bubble_Sort(v);
cout<<"排序从小到大:" << endl;
for(vector<int>::iterator it=v.begin(); it!=v.end();it++)
{
cout << *it << " ";
}
cout << endl;
system("pause");
return 0;
}
//直接插入排序
//稳定
//原始数据越有序,排序时间越快
//时间复杂度最好O(n):本来有序
//时间复杂度最坏O(n2):逆序
//空间复杂度O(1):一个哨兵额外空间
// 优化地方
//1)比较次数
//2)移动次数
#include
#include
using namespace std;
//直接插入:顺序查找插入位置
//void Insert_Direct(vector&s)
//{
// int n = s.size();
// for (int i = 1; i < n; i++)
// {
// if (s[i] < s[i - 1])//如果后一个比前一个大,就不用移动了
// {
// int j=0;
// int temp = s[i];//哨兵
// for (j = i - 1; j>=0&&s[j] > temp; j--)
// {
// s[j + 1] = s[j];
// }
// s[j + 1] = temp;
// }
// }
//}
//折半插入排序
//时间和空间复杂度不变
//n较大时,减小比较次数查找快,移动次数没有减小
//二分查找插入位置
void Insert_Binary(vector<int>& s)
{
int n = s.size();
for (int i = 1; i < n; ++i)
{
int temp = s[i];//哨兵
int low = 0, high = i - 1;
while (low <= high)
{
int mid = low + (high - low) / 2;
if (temp > s[mid])
{
low = mid + 1;
}
else
{
high = mid - 1;
}
}
for (int j = i - 1; j >= high + 1; --j)
{
s[j + 1] = s[j];
}
s[high+ 1] = temp;
}
}
int main()
{
vector<int>v{ 1,10,24,12,16,8 };
//Insert_Direct(v);
Insert_Binary(v);
cout<<"排序从小到大:" << endl;
for(vector<int>::iterator it=v.begin(); it!=v.end();it++)
{
cout << *it << " ";
}
cout << endl;
system("pause");
return 0;
}
//简单选择排序
//时间复杂度:O(n2)
//空间复杂度:O(1)
//不稳定
//待排序数据元素中选出最小(最大)元素,直接放在起始位置
//剩余未排序的元素中找到最小(最大)元素,放在已排序序列的末尾
#include
#include
using namespace std;
void choose_Sort(vector<int>& nums)
{
int n = nums.size();
//外层循环完成数据交换,内层循环完成数据比较
for (int i = 0; i < n; i++)
{
int min = i;
for (int j = i + 1; j < n; j++)
{
if (nums[j] < nums[min])
{
min = j;
}
}
if (min != i)
{
swap(nums[min], nums[i]);
}
}
}
int main()
{
vector<int>v{ 1,10,24,12,16,8,18,89,25 };
choose_Sort(v);
cout<<"排序从小到大:" << endl;
for(vector<int>::iterator it=v.begin(); it!=v.end();it++)
{
cout << *it << " ";
}
cout << endl;
system("pause");
return 0;
}
//希尔排序
//时间复杂度O(n^1.25)~O(1.6n^1.25)
//空间复杂度O(1)
//跳跃式接近,慢慢的有序,最后一次少量移动
//增量序列是递减的,互质的,最后一个增量值是1
#include
#include
using namespace std;
void shell_Sort(vector<int>& s)
{
int n = s.size();
int dk = n;
do
{
dk = dk / 3 + 1;//dk步长
for (int i = dk; i < n; i += dk)
{
if (s[i] < s[i - dk])
{
int temp = s[i];
int j = 0;
for (j = i - dk; j >= 0 && s[j] > temp; j -= dk)
{
s[j + dk] = s[j];
}
s[j + dk] = temp;
}
}
} while (dk > 1);//dk=1跳出
}
int main()
{
vector<int>v{ 1,10,24,12,16,8,18,89,25 };
shell_Sort(v);
cout<<"排序从小到大:" << endl;
for(vector<int>::iterator it=v.begin(); it!=v.end();it++)
{
cout << *it << " ";
}
cout << endl;
system("pause");
return 0;
}
//快速排序算法
// 不稳定
//原始数据越无序,排序时间越快
//时间复杂度:O(nlog(n))
//空间复杂度:O(n)
#include
using namespace std;
#include
//递归快速排序,从小到大
//void Quick_Sort(vector& s,int low,int high)
//{
// if (low >= high) return;
// int i, j, base, temp;
// i = low, j = high;
// base = s[low];//取最左边的数为基准数
// while(i
// {
// while (s[j] >= base && i < j) j--;
// while (s[i] <= base && i < j) i++;
// if (i < j)
// {
// temp = s[i];
// s[i] = s[j];
// s[j]= temp;
// }
// }
// //基准数归位
// s[low] = s[i];
// s[i] = base;
// Quick_Sort(s, low, i - 1);//递归左子表
// Quick_Sort(s, i+ 1, high);//递归右子表
//}
递归快速排序,从大到小
//void Quick_Sort(vector& s, int low, int high)
//{
// if (low >= high) return;
// int i, j, base, temp;
// i = low, j = high;
// base = s[low];//取最左边的数为基准数
// while (i < j)
// {
// while (s[j] <= base && i < j) j--;
// while (s[i] >= base && i < j) i++;
// if (i < j)
// {
// temp = s[i];
// s[i] = s[j];
// s[j] = temp;
// }
// }
// //基准数归位
// s[low] = s[i];
// s[i] = base;
// Quick_Sort(s, low, i - 1);//递归左子表
// Quick_Sort(s, i + 1, high);//递归右子表
//}
int Is_Pivot(vector<int>& nums, int low, int high);
void Quick_sort(vector<int>& nums, int low, int high)
{
while (low < high)
{
int pivot = Is_Pivot(nums, low, high);
Quick_sort(nums, low, pivot - 1);
low = pivot + 1;
}
}
int Is_Pivot(vector<int>& nums, int low, int high)
{
int temp = nums[low];//哨兵
while (low < high)
{
while (nums[high] >= temp && low < high) high--;
nums[low] = nums[high];
while (nums[low] <= temp && low < high) low++;
nums[high] = nums[low];
}
nums[low] = temp;
return low;//返回枢轴点下标
}
int main()
{
vector<int>v{ 1,10,24,12,16,8 };
Quick_sort(v,0,5);
cout<<"排序从小到大:" << endl;
//cout << "排序从大到小:" << endl;
for(vector<int>::iterator it=v.begin(); it!=v.end();it++)
{
cout << *it << " ";
}
cout << endl;
system("pause");
return 0;
}
//堆排序
//不稳定
//时间复杂度:O(nlog(n))
//空间复杂度:O(1)
#include
#include
using namespace std;
void heapadjust(vector<int>& nums, int i, int maxsize);
int heapsort(vector<int>& nums, int k)
{
int n = nums.size();
for (int i = n / 2; i >= 1; i--)
{
heapadjust(nums, i, n);
}
int size = n;
for (int i = 1; i < k; i++)
{
swap(nums[0], nums[size - 1]);
heapadjust(nums, 1, size - 1);
size--;
}
return nums[0];
}
//堆的建立
void heapadjust(vector<int>& nums, int i, int maxsize)
{
int temp = nums[i - 1];
for (int j = i * 2; j <= maxsize; j *= 2)
{
if (j + 1 <= maxsize && nums[j] > nums[j - 1])
{
j++;
}
if (temp > nums[j - 1])break;
nums[i - 1] = nums[j - 1];
i = j;
}
nums[i - 1] = temp;
}
//调整大顶堆,升序输入
//n数组长度,i待调整节点,数组下标从0开始
void heapify(vector<int>& nums,int n,int i)
{
int largest = i, lson = 2 * i + 1, rson = 2 * i + 2;
if (lson < n && nums[largest] < nums[lson])
{
largest = lson;
}
if (rson < n && nums[largest] < nums[rson])
{
largest = rson;
}
if (largest != i)
{
swap(nums[largest], nums[i]);
heapify(nums, n, largest);//递归待调整节点largest
}
}
void heap_Sort(vector<int>& nums, int n)
{
//建堆
for (int i = n / 2 - 1; i >= 0; i--)
{
heapify(nums, n, i);//调整节点n/2-1
}
//排序
for (int i = n - 1; i >= 0; i--)
{
swap(nums[i], nums[0]);
heapify(nums, i, 0);//调整堆顶节点
}
}
int main()
{
vector<int>v{ 1,10,24,12,16,8 };
heap_Sort(v, 6);
for(vector<int>::iterator it=v.begin(); it!=v.end();it++)
{
cout << *it << " ";
}
system("pause");
return 0;
}
以上就是本人学习排序算法过程中的一些总结,部分注释部分是不同的写法,可自由切换,都经过测试,均可跑通!