各种排序的比较和实现以及性能分析

排序

常见排序

  • 插入排序:直接插入排序,希尔排序
  • 选择排序:选择排序,堆排序
  • 交换排序:冒泡排序,快速排序(快排)
  • 归并排序:归并排序

插入排序

  • 直接插入排序
    性能: 时间O(n^2) /空间O(1)/ 稳定
void insertsort(int* a, int n)
{
	for (int i = 0; i < n - 1; i++)
	{
		int end = i;
		int tem = a[end + 1];
		while (end >= 0)
		{
			if (tem < a[end])
			{
				a[end + 1] = a[end];
			}
			else
				break;
			end--;
		}
		a[end + 1] = tem;
	}
}
  • 希尔排序
    性能:时间O(nlogn)~O(n^2)/空间O(1)/不稳定
    注:与直接插入一样,只是改变了gap的值,处理大量数据的时候可以让大的数字快速到达后面去
void shellsort(int* a, int n)
{

	int gap = n;
	while (gap > 1)
	{
		gap = gap / 2;
		//gap=gap/3+1;
		for (int i = 0; i < n - gap; i++)
		{
			int end = i;
			int temp = a[end + gap];
			while (end >= 0)
			{
				if (a[end] > temp)
				{
					a[end + gap] = a[end];
				}
				else
					break;
				end -= gap;
			}
			a[end+gap] = temp;
		}
	}
}

选择排序

  • 选择排序
    性能:时间O(n^2)/空间O(1)/不稳定
    注:也可以在原数组里面操作找出最大最小值并记入最大最小值处的下标,然后与前后位置的元素交换
void SelectSort(int* a, int n)
{
	int* p = (int*)malloc(sizeof(int) * n);
	for (int i = 0; i <= n / 2; i++)
	{
		int minn = a[i], maxx = a[i];
		for (int j = i; j < n ; j++)
		{
			if (minn > a[j])
			{
				minn = a[j];
			}
			if (maxx < a[j])
			{
				maxx = a[j];
			}
		}
		p[i] = minn;
		p[n - 1 - i] = maxx;
	}
	memcpy(a, p, sizeof(int) * n);
}
  • 堆排序
    性能:时间O(nlogn)/空间O(1)/不稳定
    注意:建堆要与排序方式相反,使用向下建堆的方式建堆速度更快
void AdjustDwon(int* a, int n, int root)
{//大堆
	int child = root * 2 + 1;
	while (child < n)
	{//判断左右儿子谁更大
		if (child + 1 < n && a[child] < a[child + 1])
			child++;
		if (a[root] < a[child])
		{
			Swap(&a[root], &a[child]);
			root = child;
			child = root * 2 + 1;
		}
		else
			break;
	}
}
void HeapSort(int* a, int n)
{//用数组建堆
	for (int i = (n-1-1) / 2; i >= 0; i--)
		AdjustDwon(a, n, i);
	int end = n - 1;
	//将最大的堆顶与数组尾元素交换
	while (end)
	{
		Swap(&a[0], &a[end]);
		AdjustDwon(a, end, 0);
		end--;
	}
}

交换排序

  • 冒泡排序
    性能:时间O(n^2)/空间O(1)/稳定
    注:可以添加一个flag去判断这一趟有没有交换,没有说明以排完序,可以结束排序了
void BubbleSort(int* a, int n)
{
	for(int i=0;i<n;i++)
		for (int j = 0; j < n - i-1; j++)
		{
			if (a[j] < a[j + 1])
			{
				Swap(&a[j], &a[j + 1]);
			}
		}
}
  • 快速排序(快排)
    性能:时间O(nlogn)/空间 O(logn)~O(n)/不稳定
    注:可以有多种方法去排序,这里采用的最常见的一种方法,快排数据小于10的时候可以采用直接插入,相比于在函数递归性能更佳,添加三数取中,使所取数据更加有有效性,样例采用递归方式实现
    详细见下篇文章:quicksort详解
int getmi(int* a, int l, int r)
{
	int mid = (l + r) / 2;
	if (a[mid] < a[l])
	{
		if (a[mid] > a[r])
			return mid;
		else if (a[r] > a[l])
			return l;
		else
			return r;
	}
	else
	{
		if (a[l] > a[r])
			return l;
		else if (a[r] > a[mid])
			return mid;
		else
			return r;
	}
}
int PartSort1(int* a, int left, int right)
{
	int mid = getmi(a, left, right);
	Swap(&a[mid], &a[left]);
	int k = a[left];
	int l = left+1;
	int r = right;
	while (l < r)
	{
		while (l<r&&a[r] >= k)
			r--;
		while (l<r&&a[l] <= k)
			l++;
		Swap(&a[l], &a[r]);
	}
	Swap(&a[l], &a[left]);
	return l;
}
void QuickSort(int* a, int left, int right)
{
	if (left >= right)
		return;
	if (right - left + 1 < 10)
	{
		InsertSort(a, right - left + 1);
	}
	else
	{
		int k=PartSort1(a, left, right);
		QuickSort(a, left, k - 1);
		QuickSort(a, k+1,right);
	}
}

归并排序

  • 归并排序
    性能:时间O(nlogn)/空间O(n)/稳定
    注:每次归并后一定要将数据赋值回原数组,样例采用递归方式
void _mergesort(int* a, int l,int r, int* p)
{
	if (l >= r)
		return;
	int mid = (l + r) / 2;
	_mergesort(a, l, mid, p);
	_mergesort(a, mid + 1, r, p);
	int c = l;
	int b1 = l, e1 = mid;
	int b2 = mid + 1, e2 = r;
	while (b1 <= e1 && b2 <= e2)
	{
		p[c++] = a[b1] < a[b2] ? a[b1++] : a[b2++];
	}
	while (b1 <= e1)
		p[c++] = a[b1++];
	while (b2 <= e2)
		p[c++] = a[b2++];
	memcpy(a + l, p + 1, sizeof(int) * (r - l + 1));
}
void MergeSort(int* a, int n)
{
	int* p = (int*)malloc(sizeof(int));
	if (p == NULL)
	{
		perror("MegeSort");
		exit(-1);
	}
	_mergesort(a,0, n-1, p);
	free(p);
}

特殊排序

  • 计数排序
    性能:与数据有关,擅长处理范围小的数据,遇强则强实力不详
void CountSort(int* a, int n)
{
	int minn, maxx;
	minn = maxx = a[0];
	for (int i = 1; i < n; i++)
	{
		minn = min(minn, a[i]);
		maxx = max(maxx, a[i]);
	}
	int* p = (int*)malloc(sizeof(maxx - minn + 1));
	memset(p, 0, sizeof(sizeof(maxx - minn + 1)));
	for (int i = 0; i < n; i++)
		p[a[i]-minn]++;
	int c = 0;
	for (int i = 0; i < maxx - minn + 1; i++)
		while (p[i]--)
			a[c++] = i+maxx-minn+1;
	free(p);
}

稳定性:指排序后相同元素的相对顺序是否发生改变

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值