常用排序算法总结

直接插入排序

平均情况:O(n*n)    最好情况:O(n)    最坏情况:O(n*n)    辅助空间:O(1)    稳定性:稳定 

对第i+1位置上的数,将其插入前i个有序数组中,插入以后形成新的有序数组。

#include <iostream>
using namespace std;
void insert_sort(int arr[],int len)
{
	int i,j,temp;
	for (i=1;i<len;i++)
	{
		temp=arr[i];
		for (j=i-1;j>=0&&temp<arr[j];j--)
			arr[j+1]=arr[j];
		arr[j+1]=temp;
	}
}
void print_array(int a[],int len)
{
	for(int i=0;i<len;i++)
		cout<<a[i]<<" ";
}
void main()
{
	int a[]={7,3,5,8,9,1,2,4,6};
	insert_sort(a,9);
	print_array(a,9);
}

 

希尔排序

由于分组的存在,相等的元素可能会分在不同组,导致它们的次序可能发生变化,因此 稳定性:不稳定 .

当待排序的记录较少或基本有序时,直接插入排序的优势比较明显,但在现实中满足这两个条件很难。如何让待排序的记录个数较少呢?方法:将记录分组,分割成若干个子序列,此时每个子序列待排序的记录个数就比较少了,在子序列内部进行直接插入排序。当整个序列都基本有序时,再对全体记录进行一次直接插入排序。

#include <iostream>
using namespace std;
void shell_sort(int arr[],int len)
{
	int i,j,temp,d;
	for (d=len/2;d>0;d/=2) //控制增量
	{
		for (i=d;i<len;i++) //这个for循环就是前面的直接插入排序
		{
			temp=arr[i];
			for (j=i-d;j>=0&&temp<arr[j];j-=d)
				arr[j+d]=arr[j];
			arr[j+d]=temp;
		}
	}
}
void print_array(int a[],int len)
{
	for(int i=0;i<len;i++)
		cout<<a[i]<<" ";
}
void main()
{
	int a[]={7,3,5,8,9,1,2,4,6};
	shell_sort(a,9);
	print_array(a,9);
}

 

冒泡排序

平均情况:O(n*n)    最好情况:O(n)    最坏情况:O(n*n)    辅助空间:O(1)    稳定性:稳定 

根据轻气泡不能在重气泡之下的原则,从下往上扫描数组,凡扫描到较轻气泡,就使其向上"漂浮"。

#include <iostream>
using namespace std;
void bubble_sort(int arr[],int len)
{
	int i=0,j=0,temp;
	int exchange=0; //用于记录每次扫描时是否发生交换
	for (i=0;i<len-1;i++)
	{
		exchange=0;
		for (j=len-2;j>=i;j--)
		{
			if (arr[j+1] < arr[j])
			{
				temp=arr[j+1];
				arr[j+1]=arr[j];
				arr[j]=temp;
				exchange=1;
			}
		}
		if(exchange != 1)
			return;
	}
}
void print_array(int a[],int len)
{
	for(int i=0;i<len;i++)
		cout<<a[i]<<" ";
}
void main()
{
	int a[]={7,3,5,8,9,1,2,4,6};
	bubble_sort(a,9);
	print_array(a,9);
}

 

快速排序

平均情况:O(nlogn)    最好情况:O(nlogn)    最坏情况:O(n*n)    稳定性:不稳定 

选择一个记录作为基准,将小于此记录的划分到左区间,将大于次记录的划分到右区间.

#include <iostream>
using namespace std;
void qsort(int array[],int len)
{
	int start,end,value;
	if(len <= 1)
		return;
	start=0;
	end=len-1;
	value=array[0];
	while(start < end)
	{
		for (;start<end;end--)
		{
			if(array[end] < value)
			{
				array[start++]=array[end];
				break;
			}
		}
		for (;start<end;start++)
		{
			if(array[start] > value)
			{
				array[end--]=array[start];
				break;
			}
		}
	}
	array[start]=value;
	qsort(array,start);
	qsort(array+start+1,len-start-1);
}
void print_array(int a[],int len)
{
	for(int i=0;i<len;i++)
		cout<<a[i]<<" ";
}
void main()
{
	int a[]={7,3,5,8,9,1,2,4,6};
	qsort(a,9);
	print_array(a,9);
}


选择排序

平均情况:O(n*n)    最好情况:O(n*n)    最坏情况:O(n*n)   辅助空间:O(1)  稳定性:不稳定 

对当前第i个位置上的数,选择数组中从i到末尾最小的数字与其交换

#include <iostream>
using namespace std;
void select_sort(int arr[],int len)
{
	int i,j,min,pos;
	for (i=0;i<=len-2;i++)
	{
		min=arr[i];
		pos=i;
		for (j=i+1;j<len;j++)
		{
			if(arr[j] < min)
			{
				min=arr[j];
				pos=j;
			}
		}
		arr[pos]=arr[i];
		arr[i]=min;
	}
}
void print_array(int a[],int len)
{
	for(int i=0;i<len;i++)
		cout<<a[i]<<" ";
}
void main()
{
	int a[]={7,3,5,8,9,1,2,4,6};
	select_sort(a,9);
	print_array(a,9);
}

 

堆排序

平均情况:O(nlogn)    最好情况:O(nlogn)    最坏情况:O(nlogn)    辅助空间:O(1)    稳定性:不稳定 

在测试代码中为大根堆,所有子节点都小于其父节点。堆,实质上是满足如下性质的完全二叉树:树中任一非叶结点的关键字均不小于(或不大于)其左右子节点(若存在)的关键字。排序两大部分:初始建堆和堆重建。堆顶元素arr[0](数组的最大值)被置换到数组的尾部,故需要堆重建。

#include <iostream>
using namespace std;
int heapSize=0;
int Left(int index){return (index<<1)+1;}
int Right(int index){return (index<<1)+2;}
void Swap(int* a,int* b){int temp=*a;*a=*b;*b=temp;}
void maxHeapify(int arr[],int index)
{
	int largest=0;
	int left=Left(index);
	int right=Right(index);
	if(left<=heapSize && arr[left]>arr[index])
		largest=left;
	else
		largest=index;
	if(right<=heapSize && arr[right]>arr[largest])
		largest=right;
	if(largest != index)
	{
		Swap(&arr[index],&arr[largest]);
		maxHeapify(arr,largest);
	}
}
void buildMaxHeap(int arr[],int len)
{
	heapSize=len;
	int i;
	for(i=(len>>1);i>=0;i--)
		maxHeapify(arr,i);
}
void heap_sort(int arr[],int len)
{
	int i;
	buildMaxHeap(arr,len-1);
	for (i=len-1;i>=1;i--)
	{
		Swap(&arr[0],&arr[i]);
		heapSize--;
		maxHeapify(arr,0);
	}
}
void print_array(int a[],int len)
{
	for(int i=0;i<len;i++)
		cout<<a[i]<<" ";
}
void main()
{
	int a[]={7,3,5,8,9,1,2,4,6};
	heap_sort(a,9);
	print_array(a,9);
}

 

归并排序

平均情况:O(nlogn)    最好情况:O(nlogn)    最坏情况:O(nlogn)    辅助空间:O(n)    稳定性:稳定 

归并是指将若干个已排序的子文件合并为一个有序的文件。归并排序有两种实现方法:自底向上和自顶向下。本文介绍自顶向下的“二路归并排序”,设归并排序的当前区间是A[low,high],步骤如下:

(1)分解:将当前区间一分为二,即求分裂点;

(2)求解:递归地对两个子区间A[low,mid]和A[mid+1,high]进行归并排序;

(3)组合:将已排序的两个子区间归并为一个有序的区间R[low,high];

(4)递归的终止条件:子区间长度为1。

#include <iostream>
using namespace std;
void Merge(int arr[],int tmp[],int lPos,int rPos,int rEnd)
{
	int i,lEnd,numElements,tmpPos;
	lEnd=rPos-1;
	tmpPos=lPos;
	numElements=rEnd-lPos+1;
	while(lPos<=lEnd && rPos<=rEnd)
	{
		if(arr[lPos] <= arr[rPos])
			tmp[tmpPos++]=arr[lPos++];
		else
			tmp[tmpPos++]=arr[rPos++];
	}
	//到这里,左端或右端还可能含有剩余元素(只可能有一端剩余)
	while(lPos <= lEnd)
		tmp[tmpPos++]=arr[lPos++];
	while(rPos <= rEnd)
		tmp[tmpPos++]=arr[rPos++];
	for(i=0;i<numElements;i++,rEnd--)
		arr[rEnd]=tmp[rEnd];
}
void msort(int arr[],int tmp[],int low,int high)
{
	if(low >= high)
		return;
	int middle=(high+low)/2;
	msort(arr,tmp,low,middle);
	msort(arr,tmp,middle+1,high);
	Merge(arr,tmp,low,middle+1,high);
}
void merge_sort(int arr[],int len)
{
	int* tmp=new int[len];
	if(tmp != NULL)
	{
		msort(arr,tmp,0,len-1);
		delete[] tmp;
	}
}
void print_array(int a[],int len)
{
	for(int i=0;i<len;i++)
		cout<<a[i]<<" ";
}
void main()
{
	int a[]={7,3,5,8,9,1,2,4,6};
	merge_sort(a,9);
	print_array(a,9);
}





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值