学习记录—C++实现排序算法汇总

排序分类

首先分为内部排序和外部排序,本文主要研究内部排序。

外部排序排序过程需要访问外存,内存外存也要结合使用,适合处理数据量很大的数据,
如1000T等,使用多路归并排序算法和败者树。

内部排序按照原理分为5大类。插入,选择,交换,归并,基数排序。

插入排序:直接插入排序,折半插入排序,希尔排序。

选择排序:简单选择排序,堆排序。

交换排序:冒泡排序,快速排序。

归并排序。(待更新)

基数排序。(待更新)

排序总结

时间复杂度:算法执行的时间
空间复杂度:算法执行占用的内存
排序方式:in-place(占用常数内存,不占用额外内存),out-place(占用额外内存)
稳定性:原来相等的两个数排序后不乱序为稳定
学习记录—C++实现排序算法汇总_第1张图片

一、冒泡排序

#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;
}

总结

以上就是本人学习排序算法过程中的一些总结,部分注释部分是不同的写法,可自由切换,都经过测试,均可跑通!

你可能感兴趣的:(排序算法,算法,学习)