算法归总—常用排序算法总结

一世执手 提交于 2020-02-08 04:10:35

这次总结一下常用的一些排序用的算法,目前只是一部分,包括:
冒泡排序、桶排序、选择排序、插入排序、快速排序

(一)冒泡排序

冒泡排序是一种稳定的排序方法,因为如果两个相邻的数相同的话,将不会有所交换。
思路是比较两个相邻的数字,比较大的放在右边。
如果一共有n个数字,那么第一次则需要比较n-1次,然后比较的次数依次递减。
第一次比较,将最大的数放到了最后,第二次比较,将倒数第二个最大的数放到了倒数第二的位置,第三次比较将倒数第三最大的数放到了倒数第三的位置,以此类推,比较到最后得到的就是真正的顺序。

#include<bits/stdc++.h>
using namespace std;
int num[15];
int main()
{
	int n;
	cin>>n;    //输入所要排序的数字的个数 
	for(int i = 1;i<=n;i++){
		cin>>num[i];      //输入需要排列的数字 
	}
	for(int i = n-1;i>=1;i--){           //进行冒泡排序操作 
		for(int j = 1;j<=i;j++){
			if(num[j]>num[j+1]){
				num[j] = num[j]^num[j+1];
				num[j+1] = num[j]^num[j+1];
				num[j] = num[j]^num[j+1];
			}
		}
	}
	for(int i = 1;i<=n;i++){
		cout<<num[i]<<" ";
	}
	return 0;
}

这里的冒泡排序交换位置用的是异或方法,不太明白这个方法的小伙伴们,可以百度一下,和我一样强行记住也是可以的。

(二)桶排序

桶排序是将一个范围作为一个桶,将所需要排序的数字放入对应的桶当中,并完成排序,这里讲解一个较为容易理解的桶排序。
众所周知,数组是一个个的存储单位,我们可以将每一个存储单位看成是一个桶,数组的顺序是由小到大,那么就是说这个桶原本就是排好序的,我们将数字放入对应的桶当中,顺序也会因为桶的顺序的缘故而被排列好。
比如一列数字:6,9,5,3
我们可以开辟一段数组a来存储,让这些数字来当数组的下标。
当到达第一个数字的时候,让a[6]++,那么这个里边存的数字将不再是零,我们这样一点点的存储完,最后将不是零的输出出来,便得到了最后的结果。

#include<stdio.h>
#include<stdlib.h>
int main()
{
	int a[11],i,j,t;
	for(i = 0;i<=11;i++){
		a[i] = 0;
	}
	for(i = 0;i<=5;i++){
		scanf("%d",&t);
		a[t]++;
	}
	for(i = 0;i<11;i++){
		for(j = 0;j<a[i];j++){
			printf("%d ",i);
		}
	}
	system("pause");
}

(三)选择排序

顾名思义为选择。
起初整个数列全为无序,称为无序数列,然后从里边选出最小的一个和无序数列的第一个交换,交换完毕后将最小的那个标记为有序,将不再发生改变。依次进行下去,每次都是找出最小的一个,这样子找到最后排列出来就是最后的结果。

#include<bits/stdc++.h>
using namespace std;
int num[15];
int main()
{
	int n,min,temp,k;       //min记录最小值,temp用于交换,k用于标记下标 
	cin>>n;    //输入所要排序的数字的个数 
	for(int i = 1;i<=n;i++){
		cin>>num[i];      //输入需要排列的数字 
	}
	for(int i = 0;i<=n-1;i++){
		min = num[i+1];
		k = i+1;
		for(int j = 1+i;j<=n;j++){
			if(min>num[j]){
				min = num[j];
				k = j;
			}
		}
		temp = num[i+1];
		num[i+1] = min;
		num[k] = temp;
	}
	for(int i = 1;i<=n;i++){
		cout<<num[i]<<" ";
	}
	return 0;
}

(四)插入排序

插入排序就是先选择第一个为排好序的,然后从第二个开始,跟第一个比较,如果大于第一个,就放在右边,小于第一个就放在左边,然后第三个再从后边开始比较,先和第二个比,如果大于第二个直接放在第二个数字的右边,如果小于第二个数字,那么再和第一个数字比较,大于第一个数字的话,就放在第一个和第二个之间,如果小于第一个数字的话,就放在最前边,每一次都是这样的比较方式。

#include<iostream>
#include<cstdio>
using namespace std;
int a[15];
int main () {
	int n,x,k;
	cin>>n;
	for (int i=0; i<n; i++) {
		scanf ("%d", &x);
		for (k=i; k>0; k-- ) {
			if ( a[k-1] > x )
				a[k]=a[k-1];
			else break;
		}
		a[k] = x;
	}
	for (int i=0; i<n; i++)
		printf("%d ", a[i]);
	return 0;
}

(五)快速排序

快速排序的精髓是寻找到基准点,然后先从右边开始寻找比基准点小的数,再从左边寻找比基准点大的数,然后进行交换,直到两个寻找的指针碰面,让这两个指针指向的数字和基准数交换。

至于为什么要先从右边开始,因为一般寻找基准值都是最左边的数,那么重叠指针对应的那个数必然是要与最左边的交换的,而左边应该是小的一方,如果左边指针先动,最后停的那个位置必然是比基准值大的,那么交换的话还是不对的顺序。

然后分别在基准点的左右两边再度看做两个数列,进行刚才的操作,这就是一个递归的过程。

#include<bits/stdc++.h>
using namespace std;
int a[101];
void quicksort(int left,int right){
	int i,j,num,temp;
	if(left>right){
		return;
	}
	num = a[left];
	i = left;
	j = right;
	while(i!=j){
		while(a[j]>=num&&i<j) j--;
		while(a[i]<=num&&i<j) i++;
		if(i<j){
			temp = a[i];
			a[i] = a[j];
			a[j] = temp;
		}
	}
	a[left] = a[i];
	a[i] = num;
	quicksort(left,i-1);
	quicksort(i+1,right);
}
int main()
{
	int n;
	cin>>n;
	for(int i = 1;i<=n;i++){
		cin>>a[i];
	}
	quicksort(1,n);
	for(int i = 1;i<=n;i++){
		cout<<a[i]<<" ";
	}
	return 0;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!