冒泡排序
冒泡排序就是两两进行比较,大的往右边调。
从右向左,按降序排列。
两重for循环,时间复杂度为 O(n^2);
nums为引用,所以空间复杂度取决于定义的整形变量,即常数级O(1)。
void bubble_sort(std::vector<int>&nums){
for(int i=0;i<nums.size()-1;i++){
for(int j=0;j<nums.size()-1-i;j++){
if(nums[j]>nums[j+1]){
int temp=nums[j];
nums[j]=nums[j+1];
nums[j+1]=temp;
}
}
}
}
选择排序
选择排序是最容易想到的方法,逐个比较,依次找出最小值往左边调。
理由同上,时间复杂度O(n^2);
空间复杂度,即O(1).
void select_sort(std::vector<int>&nums){
for(int i=0;i<nums.size()-1;i++){
int min=i;
for(int j=i+1;j<nums.size();j++){
if(nums[j]<nums[min])
min=j;
}
int temp=nums[i];
nums[i]=nums[min];
nums[min]=temp;
}
}
插入排序
从左往右每次选取一个元素进入有序数列。
理由同上,时间复杂度O(n^2);
空间复杂度,即O(1).
void insert_sort(std::vector<int>&nums){
for(int i=0;i<nums.size();i++){
for(int j=i;j>0;j--){
if(nums[j]<nums[j-1]){
int temp=nums[j-1];
nums[j-1]=nums[j];
nums[j]=temp;
}
}
}
}
STL sort()
bool cmp(int a,int b){
return a>b;
}
void stl_sort(std::vector<int>&nums){
std::sort(nums.begin(),nums.end());//默认从小到大排序
std::sort(nums.begin(),nums.end(),cmp);//从大到小排序
}
归并排序
算法复杂度O(nlogn).
分治算法:
将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解后进行合并,就可得到原问题的解。
一般步骤:
1.分解,将要解决的问题划分成若干规模较小的同类问题。
2.求解,当子问题划分的较小时,用较简单的方法进行解决。
3.合并,按原问题的要求,将子问题的解逐层进行合并构成原问题的解。
#include<iostream>
#include<vector>
void merge_sort_two_vec(std::vector<int>& sub_vec1,
std::vector<int>& sub_vec2,
std::vector<int>& vec) {
int i = 0;
int j = 0;
while (i < sub_vec1.size() && j < sub_vec2.size()) {
if (sub_vec1[i] <= sub_vec2[j]) {
vec.push_back(sub_vec1[i]);
i++;
}
else {
vec.push_back(sub_vec2[j]);
j++;
}
}
for (; i < sub_vec1.size(); i++) {
vec.push_back(sub_vec1[i]);
}
for (; j < sub_vec2.size(); j++) {
vec.push_back(sub_vec2[j]);
}
}
void merge_sort(std::vector<int>& vec) {
if (vec.size() < 2) {
return;
}
int mid = vec.size() / 2;
std::vector<int>sub_vec1;
std::vector<int>sub_vec2;
for (int i = 0; i < mid; i++) {
sub_vec1.push_back(vec[i]);
}
for (int j = mid; j < vec.size(); j++) {
sub_vec2.push_back(vec[j]);
}
merge_sort(sub_vec1);
merge_sort(sub_vec2);
vec.clear();
merge_sort_two_vec(sub_vec1, sub_vec2, vec);
}
int main() {
std::vector<int>vec;
int test[] = { 5,-7,9,8,1,4,-3,10,2,0 };
for (int i = 0; i < 10; i++) {
vec.push_back(test[i]);
}
merge_sort(vec);
for (int i = 0; i < vec.size(); i++) {
std::cout << vec[i] << std::endl;
}
return 0;
}
快速排序
面试必备!!!
#include<iostream>
#include<ctime>
//产生随机数,[start,end]
int RandomInRange(int start, int end)
{
return start + rand() % (end - start + 1);
}
//调换两数
void Swap(int* data1, int* data2)
{
int temp = *data1;
*data1 = *data2;
*data2 = temp;
}
//在范围内随机选一个数,把小于它的数放在左边,大的放在右边
int Partition(int data[], int length, int start, int end)
{
if (data == nullptr || length <= 0 || start < 0 || end >= length)
throw new std::exception("Invalid Input");
int index = RandomInRange(start, end);
Swap(&data[index], &data[end]);
int small = start - 1;
for (index=start; index < end; index++)
{
if (data[index] < data[end])
{
++small;
if (index != small)
{
Swap(&data[index], &data[small]);
}
}
}
++small;
Swap(&data[small], &data[end]);
return small;
}
//通过递归实现快速排序
void Quick_Sort(int data[], int length, int start, int end)
{
if (start == end)
return;
int index = Partition(data, length, start, end);
if (index > start)
Quick_Sort(data, length, start, index - 1);
if (index < end)
Quick_Sort(data, length, index + 1, end);
}
int main()
{
int data[] = { 3,2,1 };
int length = sizeof(data) / sizeof(data[0]);
int start = 0;
int end = length - 1;
Quick_Sort(data, length, start, end);
for (int i = 0; i < length; i++)
{
std::cout << data[i] << "\t";
}
std::cout << std::endl;
return 0;
}
未完待续。。。