排序实现合集

本文详细介绍了四种基本的排序算法:冒泡排序、选择排序、插入排序和快速排序,通过C++代码展示了它们的实现原理和步骤,包括双层循环、元素交换以及快速排序中的分区和递归调用。
摘要由CSDN通过智能技术生成

#冒泡排序 #选择排序 #插入排序 #快速排序


冒泡排序的实现:

#include <bits/stdc++.h>
using namespace std;

int main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int n;
	cin >> n;
	int a[n];
	for (int i = 1; i <= n; i++) {
		cin >> a[i];

	}
	for (int i = n; i >= 1; i--) {
		for (int j = 1; j <= i - 1; j++) {
			if (a[j] > a[j + 1]) {
				swap(a[j ], a[j + 1]);

			}


		}
	}


	for (int i = 1; i <= n; i++) {
		cout << a[i] << " ";

	}


	return 0;
}

总结: 

冒泡排序采用双层循环,假设理想的排序结果是从左到右从小到大排列。那么外层循环则从最右边的位置开始确定,内层循环从最左边的位置相邻两两进行比较,经过一趟冒泡排序使最大的元素到达最右边。经过第二趟排序使第二大的元素到达次右边的位置上......直到使所有元素有序。


选择排序的实现:

#include <bits/stdc++.h>
using namespace std;

int main() {
	int n;
	cin >> n;
	int a[n];

	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	for (int i = n; i >= 1; i--) {
		int max = 1;
		for (int j = 1; j <= i; j++) {
			if (a[j] > a[max])
				max = j;
		}
		swap(a[max], a[i]);
	}


	for (int i = 1; i <= n; i++) {
		cout << a[i] << " ";
	}


	return 0;
}

总结:  

    与冒泡排序不同的是,选择排序是在排序之前先定义一个下标max,双层循环通过比较以max为下标的值和内层循环 a[j] 的值;如果 a[j] > max,那么更新下标max的值,遍历完一趟,外层循环交换 a[max] 和 a[i] 的位置使 a[max] 到达最右边。(ps:初始化 int max = 1 时不要在全局里定义,否则会出现每执行一次循环max都为1,导致答案错误)


插入排序的实现:

#include <bits/stdc++.h>
using namespace std;

int main() {
	int n;
	cin >> n;
	int a[n];
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	for (int i = 2; i <= n; i++) {
		int val = a[i], j;

		for (j = i; j > 1 && val < a[j - 1]; j--) {
			a[j] = a[j - 1];
		}
		a[j] = val;
	}

	for (int i = 1; i <= n; i++) {
		cout << a[i] << " ";
	}

	return 0;
}

总结:

插入排序的排序过程与冒泡、选择排序不同的是,一开始放入一个元素是有序的(显然),之后每插入一个元素放到合适的位置使元素有序,...,直至所有元素有序。首先 i=1 这一个元素 显然有序, 随后外层循环从 i = 2 时,定义一个 val 存放 a[i] 的值。内层循环从 j = i 开始,将 val 的值与 a[j-1] 进行比较,若 val < a[j-1] ,就把 a [j-1] 向右挪一个位置,j - -  ;否则就把 val 插入到 a [j] 的位置上。以此循环,直到所有元素有序。


快速排序的实现:

#include <bits/stdc++.h>
using namespace std;
const int n = 1e6 + 9;
int  a[n];

int partition(int a[], int l, int r) {
	int i = l, j = r;
	int pivot = a[r];
	while (i < j) {
		while (i < j && a[i] <= pivot)
			i++;
		while (i < j && a[j] >= pivot)
			j--;
		if (i < j)
			swap(a[i], a[j]);
		else
			swap(a[i], a[r]);
	}
	return i;

}

void quicksort(int a[], int l, int r) {
	if (l < r) {
		int mid = partition(a, l, r);
		quicksort(a, l, mid - 1);
		quicksort(a, mid + 1, r);
	}

}




int main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	quicksort(a, 1, n);
	for (int i = 1; i <= n; i++) {
		cout << a[i] << " ";

	}

	return 0;
}

总结:

快速排序相对比较复杂。

定义一个 partition 函数用于将原数组分成两部分,并返回中间位置的下标。该函数的参数包括数组 a、左边界 l、右边界 r。定义一个中轴元素 pivot 为右边界元素,后续通过交换使得中轴元素左边的元素都小于中轴元素pivot,中轴元素右边的元素都大于pivot。

当 i < j 时,i 从最左边向右开始遍历, j 从最右边向左开始遍历,如果 a[ i ] <=pivot, i 就 + +,直到找到存在 a[ i ] > pivot ;相同地,如果 a[ j ] >= pivot, j 就 - -,直到找到存在 a[ j ] < pivot 。此时存在且跳出了循环,如果 i < j ,就交换 a[ i ] 和 a [ j ] 的位置;否则 i 和 j 就相遇了,因为 i 在交换后再向右走一定是 a [i] > pivot ,相遇则交换 a[ i ] 和 a[ r ] 。具体实现如下图所示:

定义一个 quicksort 函数通过  partition  函数获取中间位置的下标,然后递归地对左边和右边的子数组进行快速排序。将左半部分和右半部分分别传递给新的递归调用。递归终止的条件是 l 不小于 r,终止了,也就实现了元素升序排序。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值