数据结构排序合集(笔记)

目录

一.插入排序与希尔排序

二.选择排序与堆排序

三.冒泡排序和快速排序

四.归并排序

五.计数排序


一.插入排序与希尔排序

|----------|---------------|-----------|---------|
| | 时间复杂度 | 空间复杂度 | 稳定性 |
| 插入排序 | O(N^2) | O(1) | 稳定 |
| 希尔排序 | O(N^1.3) | O(1) | 不稳定 |

插入排序:

希尔排序(两个排序的时间复杂度是一样的,即使是四循环,他们效率也相同):


二.选择排序与堆排序

|----------|----------------|-----------|---------|
| | 时间复杂度 | 空间复杂度 | 稳定性 |
| 选择排序 | O(N^2) | O(1) | 不稳定 |
| 堆排序 | O(N*logN) | O(1) | 不稳定 |


void SelectSort(int* a, int n)//选择排序
{
	int begin = 0;
	int end = n - 1;
	while(begin < end)
	{
		int mini = begin;
		int maxi = end;
		for (int i = begin; i <= end; i++)//选出最大和最小进行交换
		{
			if (a[i] < a[mini])
			{
				mini = i;
			}
			if (a[i] > a[maxi])
			{
				maxi = i;
			}
		}
		swap(&a[mini], &a[begin]);
		if (begin == maxi)
			maxi = mini;
		swap(&a[maxi], &a[end]);
		end--;
		begin++;
	}
}

(选择排序是特别慢,也没有稳定性的排序,可能连冒泡都比不过)

堆排序( 因为要排升序,所以建大堆):


三.冒泡排序和快速排序

|----------|----------------|-------------------|---------|
| | 时间复杂度 | 空间复杂度 | 稳定性 |
| 冒泡排序 | O(N^2) | O(1) | 稳定 |
| 快速排序 | O(N*logN) | O(logN)~O(N) | 不稳定 |

冒泡排序:

快速排序:

int Getmid(int*a,int left,int right)//三数取中
{
	int midi = (left + right) / 2;
	if (a[right] > a[left])
	{
		if (a[midi] > a[right])
		{
			return right;
		}
		else if (a[midi] < a[left])
		{
			return left;
		}
		else
			return midi;
	}
	else// if (a[left] >= a[right])
	{
		if (a[midi] > a[left])
		{
			return left;
		}
		else if (a[midi] < a[right])
		{
			return right;
		}
		else
			return midi;
	}
}

不用使用递归的qsort(用堆去模拟递归)

void QuickSortNonR(int* a, int left, int right)
{
	Stack st;
	StackInit(&st);
	StackPush(&st, right);
	StackPush(&st, left);
	while (!StackEmpty(&st))
	{
		int begin = StackTop(&st);
		StackPop(&st);
		int end = StackTop(&st);
		StackPop(&st);

		int keyi = PartSort3(a, begin, end);
		if (keyi + 1 < end)
		{
			StackPush(&st, end);
			StackPush(&st, keyi + 1);
		}
		if (begin < keyi - 1)
		{
			StackPush(&st, keyi - 1);
			StackPush(&st, begin);
		}
	}
	StackDestroy(&st);
}

四.归并排序

|------|------------|---------|-----|
| | 时间复杂度 | 空间复杂度 | 稳定性 |
| 归并排序 | O(N*logN) | O(logN) | 稳定 |


void _MergeSort(int* a, int* tmp, int left,int right)
{
	if (left >= right)
		return;
	int midi = (left + right) / 2;
	_MergeSort(a, tmp, left, midi);
	_MergeSort(a, tmp, midi+1, right);
	//归 
	int begin1 = left, end1 = midi;
	int begin2 = midi+1, end2 = right;
	int i = left;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (a[begin1] <= a[begin2])
		{
			tmp[i++] = a[begin1++];
		}
		else
		{
			tmp[i++] = a[begin2++];
		}
	}
	while (begin1 <= end1)
	{
		tmp[i++] = a[begin1++];
	}
	while (begin2 <= end2)
	{
		tmp[i++] = a[begin2++];
	}
	memcpy(a+left, tmp+left, sizeof(int)*((right - left)+1));
}

非递归实现归并排序:

void MergeSortNonR(int* a, int n)
{
	int* tmp = (int*)malloc(n*sizeof(int));
	if (tmp == NULL)
	{
		perror("malloc fail");
		return;
	}
	int gap = 1;
	while (gap < n)
	{
		for (int i = 0; i < n;i += 2*gap)//
		{
			int begin1 = i, end1 = i + gap - 1;
			int begin2 = i + gap, end2 = i + 2 * gap - 1;
			int j = i;
			//[i,end1] [i+gap,end2]

			if (begin2 >= n)
				break;
			if (end2 >= n)
				end2 = n-1;
			printf("[%d %d]  [%d %d]", begin1, end1, begin2, end2);
			while (begin1 <= end1 && begin2 <= end2)
			{
				if (a[begin1] <= a[begin2])
				{
					tmp[j++] = a[begin1++];
				}
				else
				{
					tmp[j++] = a[begin2++];
				}
			}

			while (begin1 <= end1)
			{
				tmp[j++] = a[begin1++];
			}
			while (begin2 <= end2)
			{
				tmp[j++] = a[begin2++];
			}
			memcpy(a+i, tmp+i, sizeof(int) * (end2 - i +1));//
		}
		printf("\n");
		gap = 2*gap;
	}
	free(tmp);
	tmp = NULL;
}

五.计数排序

// 计数排序
void CountSort(int* a, int n)
{
	int max = a[0], min = a[0];
	for (int i = 0; i < n; i++)//选出最大最小得到区间大小
	{
		if (max < a[i])
			max = a[i];
		if (min > a[i])
			min = a[i];
	}

	int range = max - min +1 ;
	int* count = (int*)calloc(range,sizeof(int));
	if (count == NULL)
	{
		perror("malloc fail");
		return;
	}

	for (int i = 0; i < n; i++)//给新数组进行计数
	{
		count[a[i] - min]++;
	}
	int j = 0;
	for (int i = 0; i < range; i++)//覆盖旧数组
	{
		while (count[i]--)
		{
			a[j++] = i + min;
		}
	}
	free(count);
	count = NULL;
}
相关推荐
Kenneth風车11 分钟前
【机器学习(七)】分类和回归任务-K-近邻 (KNN)算法-Sentosa_DSML社区版
人工智能·算法·低代码·机器学习·分类·数据分析·回归
m0_631270402 小时前
标准C++(二)
开发语言·c++·算法
沫刃起2 小时前
Codeforces Round 972 (Div. 2) C. Lazy Narek
数据结构·c++·算法
爱coding的橙子2 小时前
CCF-CSP认证考试准备第十五天 202303-3 LDAP
算法
QXH2000003 小时前
Leetcode—环形链表||
c语言·数据结构·算法·leetcode·链表
小灰灰爱代码4 小时前
C++——判断year是不是闰年。
数据结构·c++·算法
小灰灰爱代码4 小时前
C++——求3个数中最大的数(分别考虑整数、双精度数、长整数数的情况),用函数重载方法。
数据结构·c++·算法
爱coding的橙子6 小时前
CCF-CSP认证考试准备第十七天
数据结构·c++·算法
常某某的好奇心6 小时前
56 - I. 数组中数字出现的次数
算法
hungry12346 小时前
CF EDU 169
算法