常用的排序算法:冒泡,简单选择,直接插入,快速排序,堆排序

排序:将原来无序的一个序列重新排列成有序的序列。

排序的稳定性:指待排序的序列中有两个或两个以上相同的项,在排序前和排序后,它们的相对位置有没有发生变化,如果没有变化,则是稳定的;反之不稳定。


插入类的排序:直接插入排序、折半插入排序、希尔排序。

交换类的排序:冒泡排序、快速排序。

选择类排序:简单选择排序、堆排序。

归并类排序:两路合并排序。

基数类排序


冒泡排序:

算法思想:首先将第一个记录和第二个记录比较,如果第一个大,则二者交换,否则不交换;然后第二个记录和第三个记录比较,如果第二个大,则二者交换,否则不交换......一直进行下去,最终最大的那个记录被换到了最后,一趟冒泡完成。重复直到一趟排序过程中没有发生元素交换结束。
时间复杂度:
最好:O(n):   待排序列有序。
最坏:O(n^2)   待排序列逆序。
平均时间复杂度:O(n^2)
稳定性:稳定。

#include <iostream>
using namespace std;
void bubblesort(int *data,int count)
{
	for(int i=0;i<count-1;i++)
	{
		for(int j=0;j<count-i-1;j++)
		{
			if(data[j]>data[j+1])
			{
				int temp =data[j];
				data[j]=data[j+1];
				data[j+1]=temp;
			}
		}
	}
}
int main()
{
    int data[]={5,2,7,3,6};
	int len=sizeof(data)/sizeof(int);
	bubblesort(data,len);
	for(int i=0;i<len;i++)
	{
	cout<<data[i]<<" ";
	}
	return 0;
}


简单选择排序:

算法思想:从头到尾扫描序列,找出最小的一个记录,和第一个记录交换,接着从剩下的记录中继续这种选择和交换,最终是序列有序。
时间复杂度:
最好:O(n^2) 
最坏:O(n^2) 
平均时间复杂度:O(n^2) 
稳定性:不稳定。

#include <iostream>
using namespace std;
void selectsort(int *data,int count)
{
	for(int i=0;i<count-1;i++)
	{
		for(int j=i+1;j<count;j++)
		{
			if(data[i]>data[j])
			{
				int temp =data[i];
				data[i]=data[j];
				data[j]=temp;
			}
		}
	}
}
int main()
{
    int data[]={5,2,7,3,6};
	int len=sizeof(data)/sizeof(int);
	selectsort(data,len);
	for(int i=0;i<len;i++)
	{
	cout<<data[i]<<" ";
	}
	return 0;
}


直接插入:

算法思想:每趟将一个待排序的元素作为关键字,按照其关键字值的大小插入到已经排好的
          部分序列的适当位置上,直到插入完成。
时间复杂度:
最好:O(n)         待排序列有序。
最坏:O(n^2)     待排序列逆序。
平均时间复杂度:O(n^2) 
稳定性:稳定。

#include <iostream>
using namespace std;
void insertsort(int *data,int count)
{
	int temp,pos;
	for(int i=1;i<count;i++)
	{
		temp=data[i];
		pos=i-1;
		while((pos>=0)&&temp<data[pos])
		{
			data[pos+1]=data[pos];
			pos--;
		}
		data[pos+1]=temp;
	}
}
int main()
{
    int data[]={5,2,7,3,6};
	int len=sizeof(data)/sizeof(int);
	insertsort(data,len);
	for(int i=0;i<len;i++)
	{
	cout<<data[i]<<" ";
	}
	return 0;
}


快速排序:

算法思想:一趟快速排序是以一个"枢轴"为中心,将序列分成两部分,枢轴的一边全是比它小的另一边全是比它大的。
时间复杂度:
最好:O(nlogn)       待排序列越接近无序。
最坏: O(n)             待排序列越接近有序。
平均时间复杂度:O(nlogn)
稳定性:不稳定。

#include <iostream>
using namespace std;
void quicksort(int *data,int l,int r)
{
	if(l<r)
	{
		int i=l,j=r,x=data[l];
		while(i<j)
		{
			while((i<j)&&(data[j]>=x))
				j--;
			if(i<j)
				data[i++]=data[j];
			while((i<j)&&(data[i]<x))
				i++;
			if(i<j)
				data[j--]=data[i];
		}
		data[i]=x;
		quicksort(data,l,i-1);
		quicksort(data,i+1,r);
	}
}
int main()
{
    int data[]={5,2,7,3,6};
	int len=sizeof(data)/sizeof(int);
	quicksort(data,0,len);
	for(int i=0;i<len;i++)
	{
		cout<<data[i]<<" ";
	}
	return 0;
}


堆排序:

算法思想:

        堆是一种数据结构,可以把堆看成一棵完全二叉树,这棵树满足:任何一个非叶节点的值都不大于(或不小于)其左右孩子的值。若父亲大孩子小,则这样的堆叫做大顶堆,若父亲小孩子大,则这样的堆叫做小顶堆。

        根据堆的定义知道,代表堆的这棵完全二叉树的根节点的值是最大(或最小)的,因此将一个无序序列调整为一个堆,就可以找出这个序列的最大(或最小)值,然后将找出的这个值交换到序列的最后(或最前),这样有序序列的元素增加1个,无序序列的元素减少1个,对新的无序序列重复这样的操作,就实现了排序。

时间复杂度:
最好:O(nlogn)      
最坏:O(nlogn)     
平均时间复杂度:O(nlogn
稳定性:不稳定。

#include<iostream>
using namespace std;
void sift(int r[],int low,int high)
{
	int i=2*low+1;
	if(i<=high-1)
	{
		int righti=i+1;
		if(righti<=high-1)
			if(r[i]<r[righti])
				i=righti;
		if(r[low]<r[i])
		{
			int temp=r[i];
			r[i]=r[low];
			r[low]=temp;
			sift(r,i,high);
		}
	}
}
void heapsort(int r[],int n)
{
	for(int i=n-1;i>=0;i--)
	{
		sift(r,i,n);
	}
	int j=n-1;
	for( i=1;i<=n;i++,j--)
	{
		int temp=r[0];
		r[0]=r[j];
		r[j]=temp;
		sift(r,0,j);		
	}
}
int main()
{
    int data[]={5,2,7,3,6};
	int len=sizeof(data)/sizeof(int);
	heapsort(data,len);
	for(int i=0;i<len;i++)
	{
		cout<<data[i]<<" ";
	}
	return 0;
}

希尔排序:
算法思想:其本质还是插入排序,只是将待排序的序列按某种规则分成几个子序列,分别对这几个子序列进行直接插入排序。
平均时间复杂度:O(n^1.3)
稳定性:不稳定。


1、经过一趟排序,能够保证一个元素到达最终位置,这样的排序有交换类排序的两种(冒泡、快速)和选择类排序的(简单选择、堆)。

2、排序方法的元素比较次数和原始序列无关-----------简单选择排序和折半插入排序。

3、排序方法的排序趟数和原始序列有关----------交换类的排序。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值