C/C++排序算法实现(冒泡、选择、插入、快速、归并、希尔)

冒泡排序:

每次将序列中最大的数交换到最后一个。

C++代码:

void Exchange(int &a, int &b) {
	int tmp = a;
	a = b;
	b = tmp;
}

void BubbleSort(int *a, int length) {//冒泡排序、稳定
    for (int i = 0; i < length; i++) {
        for (int j = 0; j < length - i - 1; j++) {
            if (a[j] > a[j + 1]) {
                Exchange(a[j], a[j + 1]);
            }
        }
    }
}

冒泡排序是稳定排序、原地排序(空间复杂度为O(1)的排序),时间复杂度为O(n^2)。

选择排序:

选择最大的元素,与序列最后一个交换

void SelectionSort(int* a, int length) {//选择排序、不稳定
	int max = a[0];
	int pos;
	for (int i = 0; i < length; i++) {
		for (int j = 0; j < length - i; j++) {
			if (a[j] > max) {
				max = a[j];//找最大值
				pos = j;//最大值的位置
			}
		}
		Exchange(a[length - i - 1], a[pos]);//把最大的放在最后一位
		max = a[0];
		pos = 0;
	}
}

选择排序是不稳定排序、空间复杂度为O(1),时间复杂度为O(n^2)。

插入排序:

选定前n个元素作为有序序列,将第n+1个元素插入到序列中的正确位置,从n=1开始。

void InsertSort(int* a, int length) {
	for (int i = 1; i < length; i++) {
		int tmp = a[i];
		int j = i - 1;
		while (j >= 0 && a[j] > tmp) {
			a[j + 1] = a[j];
		}
		a[j + 1] = tmp;
	}
}

插入排序的空间复杂度为O(1),时间复杂度为O(n^2)。

快速排序:

选定一个基准数(一般是序列第一个元素),两个位置指针:i从前到后,j从后到前,在保证i<j的前提下,j移动j元素到小于基准值的位置时停止移动,当i移动到i元素大于基准值的位置时停止移动。对i元素和j元素进行交换,当i=j时,此时的i位置即为基准数最终的位置,基准数与i元素进行交换,由于是j先移动,所以i位置的元素一定小于基准值,交换后,基准值前的元素都小于基准值,基准值后的元素都大于基准值。再将基准值前的序列和基准值后的序列进行快排、递归直到序列为1时停止。

void QuickSort(int* a, int length, int begin, int end) {//快速排序、不稳定
	if (begin >= end)return;
	int i = begin;
	int j = end;
	int tmp = a[i];
	while (i != j) {
		while (a[j] >= tmp && i < j)j--;
		while (a[i] <= tmp && i < j)i++;
		if (i < j) Exchange(a[i], a[j]);
	}
	Exchange(a[begin], a[i]);
	QuickSort(a, length, begin, i - 1);
	QuickSort(a, length, j + 1, end);
}

快速排序是一种优化的冒泡排序,冒泡排序将最大的值放在正确的位置,快速排序将任意一个元素放在正确的位置,其核心思想都是交换。算法空间复杂度为O(logn),平均时间复杂度为O(nlogn)。

归并排序(二路):

先将序列划分到长度为1,在进行归并,归并时的结果放到辅助数组reg中。

void MergeSortRecursive(int* a, int* reg, int begin, int end) {//归并排序、稳定
	if (begin > end)return;
	int len = end - begin;
	int mid = (len >> 1) + begin;//除以2
	int begin1 = begin;
	int end1 = mid;
	int begin2 = mid + 1;
	int end2 = end;
	MergeSortRecursive(a, reg, begin1, end1);
	MergeSortRecursive(a, reg, begin2, end2);//递归法
	int k = begin1;
	while (begin1 <= end1 && begin2 <= end2) {
		reg[k++] = a[begin1] < a[begin2] ? a[begin1++] : a[begin2++];
	}
	while (begin1 <= end1) {
		reg[k++] = a[begin1++];
	}
	while (begin2 <= end2) {
		reg[k++] = a[begin2++];
	}
	for (k = begin; k <= end; k++) {//将reg回注到a
		a[k] = reg[k];
	}
}

归并排序是稳定排序,空间复杂度为O(n),平均时间复杂度为O(nlogn)。

希尔排序:

将序列下标按一定的距离分组,对每组进行插入排序,距离减小为1时再进行排序后的序列是有序序列。

void ShellSort(int* a, int length) {
	for (int gap = length << 1; gap > 0; gap <<= 1) {
		for (int i = gap; i < length; i++) {
			int j = i - gap;
			int tmp = a[i];
			while (j >= 0 && a[j] > tmp) {
				a[j + gap] = a[j];
				j -= gap;
			}
			a[j + gap] = tmp;
		}
	}
}

希尔排序空间复杂度为O(1),平均时间复杂度为O(nlogn)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值