2020-09-11

常用排序算法

1.冒泡排序

元素交换
排序最常用的操作就是交换数组中的元素,封装成一个函数,方便后续工作。

/*交换数组元素*/
void swap(int &a,int &b)
{
	int temp = a;
	a = b;
	b = temp;
}
主函数
#include<iostream>
using namespace std;

int main()
{
	int arry[] = { 2,4,1,9,4,5,8,7};
	int len = (int) sizeof(arry) / sizeof(*arry);
	cout << "待排序序列:" ;
	for (int i = 0; i < len; i++)
		cout << arry[i] << ' ';
	cout << endl;
	/*调用排序函数*/
	/*	Sort();
	/*           */
	cout << "排序后序列:";
	for (int i = 0; i < len; i++)
		cout << arry[i] << ' ';
	cout << endl;
	return 0;
}

冒泡排序(BubbleSort):相邻元素两两比较,反序(升序或降序)则交换。

/*Bubble  Sort*/
void BubbleSort(int arry[], int n)
{
	for (int i = 0; i < n - 1; i++)
	{
		for (int j = 0; j < n - i - 1; j++)
		{
			if (arry[j] > arry[j + 1])
			{
				swap(arry[j],arry[j+1]);
			}
		}
	}
}

时间复杂度: O ( n 2 ) O(n^2) O(n2)
空间复杂度: O ( 1 ) O(1) O(1)
算法稳定性:稳定排序算法。

2.选择排序

选择排序(SelectSort):每一次遍历数组,选取最小的元素作为i的关键字。

void SelectSort(int arry[], int len)
{
	for (int i = 0; i < len - 1; i++)
	{
		for (int j = i + 1; j < len; j++)
		{
			int temp;
			if (arry[i] > arry[j])
			{
				swap(arry[i], arry[j]);
			}
		}
	}
}

时间复杂度: O ( n 2 ) O(n^2) O(n2)
空间复杂度: O ( 1 ) O(1) O(1)
算法稳定性:不稳定的排序算法。

3.插入排序

插入排序(InsertSort):将一个元素插入到已经排好的序列中,从而得到一个新的有序的序列。(例:理扑克牌)

void InsertSort(int arry[], int len)
{
	for (int i = 1; i < len; i++)
	{
		for (int j = i - 1; j >= 0 && arry[j + 1] < arry[j]; j--)
		{
			swap(arry[j], arry[j + 1]);
		}
	}
}

时间复杂度: O ( n 2 ) O(n^2) O(n2)
空间复杂度: O ( 1 ) O(1) O(1)
算法稳定性:稳定的排序算法。

4.希尔排序

希尔排序(ShellSort):把数组元素按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个数组恰被分成一组。

void ShellSort(int arry[], int len)
{
	int i, j;
	int increment = len;
	do
	{
		increment = increment / 3 + 1;//增量序列
		for (i = increment + 1; i <= len; i++)
		{
			if (arry[i] < arry[i - increment])
			{
				arry[0] = arry[i];
				for (j = i - increment; j > 0 && arry[0] < arry[j]; j -= increment)
					arry[j + increment] = arry[j];
				arry[j + increment] = arry[0];
			}
		}
	} while (increment > 1);
}

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
空间复杂度: O ( 1 ) O(1) O(1)
算法稳定性:不稳定的排序算法。

5.堆排序

堆排序(HeapSort):是利用堆(大顶堆、小顶堆)这种数据结构而设计的一种排序算法,堆排序是一种选择排序。
S1. 将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)。
S2. 交换堆顶元素与末尾元素,使末尾元素最大。然后继续调整堆,重复交换。

void HeapAdjust(int arry[],int left,int len)
{
	int temp=arry[left];
	for (int i = 2 * left; i <= len; i *= 2)
	{
		if (i < len && arry[i] < arry[i + 1])
			++i;
		if (temp > arry[i])
			break;
		arry[left] = arry[i];
		left = i;
	}
	arry[left] = temp;
}

void HeapSort(int arry[], int len)
{
	for (int i = len / 2; i > 0; i--) //构建大顶堆
	{
		HeapAdjust(arry, i, len);
	}
	for (int i = len; i > 1; i--) 
	{
		swap(arry[i], arry[1]);
		HeapAdjust(arry, 1, i-1);
	}
}

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
空间复杂度: O ( 1 ) O(1) O(1)
算法稳定性:不稳定的排序算法。

6.归并排序

归并排序(MergeSort):采用分治法,将已有序的子序列合并,得到完全有序的序列。

void Merge(int arry[], int L, int mid, int R)
{
	int *temp = new int(R - L + 1);
	int p1 = L, p2 = mid + 1, i = 0;
	while (p1 <= mid && p2 <= R)
	{
		temp[i++] = arry[p1] > arry[p2] ? arry[p2++] : arry[p1++];
	}
	while (p1 <= mid)
		temp[i++] = arry[p1++];
	while (p2 <= R)
		temp[i++] = arry[p2++];

	for (int i = 0; i < R - L + 1; i++)
	{
		arry[L + i] = temp[i];
	}
	delete []temp;
}

void MergeSort(int arry[], int L, int R)
{
	if (L< R)
	{
		int mid = L+(R-L) / 2;
		MergeSort(arry, L, mid);
		MergeSort(arry, mid + 1, R);
		Merge(arry, L, mid, R);
	}
}

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
空间复杂度: O ( n ) O(n) O(n)
算法稳定性:不稳定的排序算法。

7.快速排序

快速排序(QuickSort):先从数列中取出一个数作为基准数,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边,再对左右区间重复第二步,直到各区间只有一个数。 递归实现

void Quick_sort(int arry[], int l, int r)
{
	if (l < r)
	{
		int i = l, j = r, x = arry[l];
		while (i < j)
		{
			while (i < j && arry[j] >= x)
				j--;
			if (i < j)
				arry[i++] = arry[j];

			while (i < j && arry[i] < x) 
				i++;
			if (i < j)
				arry[j--] = arry[i];
		}
		arry[i] = x;
		Quick_sort(arry, l, i - 1); // 递归调用 
		Quick_sort(arry, i + 1, r);
	}
}

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
空间复杂度: O ( n ) O(n) O(n)
算法稳定性:不稳定的排序算法。
推荐书籍《大话数据结构》—程杰
大话数据结构
提取码:fwsr

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值