排序算法---之交换排序(冒泡排序&快速排序-左右指针法,挖坑法,前后指针法)

                                                      排序算法----交换排序(冒泡排序&快速排序)

一、排序算法分为:

     1.插入排序(直接插入排序&希尔排序)

     2.选择排序(直接选择排序&堆排序)

     3.交换排序(冒泡排序&快速排序)

     4.归并排序

----快速排序总共有三种方法:(1).左右指针法(2).挖坑法(3).前后指针法

二、几种排序的性能比较

排序方法的比较

类别

排序方法

时间复杂度

空间复杂度

稳定性

平均情况

最好情况

最坏情况

辅助存储

插入排序

直接插入

O(n2)

O(n)

O(n2)

O(1)

稳定

希尔排序

O(n1.3)

O(n)

O(n2)

O(1)

不稳定

选择排序

直接选择

O(n2)

O(n2)

O(n2)

O(1)

不稳定

堆排序

O(nlog2n)

O(nlog2n)

O(nlog2n)

O(1)

不稳定

交换排序

冒泡排序

O(n2)

O(n)

O(n2)

O(1)

稳定

快速排序

O(nlog2n)

O(nlog2n)

O(n2)

O(nlog2n)

不稳定

归并排序

O(nlog2n)

O(nlog2n)

O(nlog2n)

O(n)

稳定

基数排序

O(d(r+n))

O(d(rd+n))

O(d(r+n))

O(rd+n)

稳定

注:基数排序中,n代表关键字的个数,d代表长度,r代表关键字的基数

 

三、冒泡排序

    1.代码

//冒泡排序
void BubbleSort(int* a,size_t n)
{
	assert(a);
	int end = n;
	while(end>0)
	{
		for(int i=0;i<end;++i)
		{
			if(a[i-1]>a[i])
			{
				swap(a[i-1],a[i]);
			}
		}
		--end;
	}
}
//打印函数
void PrintArray(int* a,size_t n)
{
	for(size_t i=0;i<n;++i)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;
}
//测试代码
void  BubbleSortTest()
{
	int a[]={2,5,4,0,9,3,6,8,7,1};
	PrintArray(a,sizeof(a)/sizeof(a[0]));
	BubbleSort(a,sizeof(a)/sizeof(a[0]));
	PrintArray(a,sizeof(a)/sizeof(a[0]));
}
2.时间复杂度:

    最好情况:O(n)

    最坏情况:O(n^2)

    平均情况:O(n^2)

    空间复杂度:O(1)

3.稳定性:稳定

四、快速排序

   方法一左右指针法

   算法代码:

//方法一:左右指针法
int PartSort1(int* a,int left,int right)
{
	int key = a[right];
	int begin = left;//左右指针,下标
	int end = right;
	while(begin<end)
	{
		while(begin<end && a[begin]<=key)//从左边找比key大的值
		{
			++begin;
		}
		while(begin<end && a[end]>=key)//从右边找比key小的值
		{
			--end;
		}
		if(begin<end)
		{
			swap(a[begin],a[end]);
		}
		swap(a[begin],a[right]);
	}
	return a[begin];
}
void QuickSort1(int* a,int left,int right)
{
	assert(a);
	if(left<right)
	{
		int div = PartSort1(a,left,right);
		QuickSort1(a,left,div-1);
		QuickSort1(a,div+1,right);
	}
}
//打印函数
void PrintArray(int* a,size_t n)
{
	for(size_t i=0;i<n;++i)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;
}
//测试代码
void QuickSortTest()
{
    int a[]={2,5,4,0,9,3,6,8,7,1};
	PrintArray(a,sizeof(a)/sizeof(a[0]));
	QuickSort1(a,0,(sizeof(a)/sizeof(a[0]))-1);
	PrintArray(a,sizeof(a)/sizeof(a[0]));
}
    方法二: 挖坑法

    算法代码:

//方法二:挖坑
int PartSort2(int* a,int left,int right)
{
	int key = a[right];
	while(left<right)
	{
		while(left<right && a[left]<=key)
		{
			++left;
		}
		a[right] = a[left];//左坑
		while(left<right && a[right]>=key)
		{
			--right;
		}
		a[left] = a[right];
	}
	a[left] = key;
	return a[left];
}
void QuickSort2(int* a,int left,int right)
{
	assert(a);
	if(left<right)
	{
		int div = PartSort2(a,left,right);
		QuickSort2(a,left,div-1);
		QuickSort2(a,div+1,right);
	}
}
//打印函数
void PrintArray(int* a,size_t n)
{
	for(size_t i=0;i<n;++i)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;
}
//测试代码
void QuickSortTest()
{
    int a[]={2,5,4,0,9,3,6,8,7,1};
	PrintArray(a,sizeof(a)/sizeof(a[0]));
	QuickSort2(a,0,(sizeof(a)/sizeof(a[0]))-1);
	PrintArray(a,sizeof(a)/sizeof(a[0]));
}
      方法三: 前后指针法

     算法代码:

//方法三:前后指针法??若有问题,请指出
int PartSort3(int* a,int left,int right)
{
	int cur = left;
	int prev = left-1;
	int key = a[right];
	while(cur<right);
	{
		if(a[cur]<key && ++prev!=cur)
		{
			swap(a[cur],a[prev]);
		}
		++cur;
	}
	swap(a[++prev],a[right]);
	return prev;
}

void QuickSort3(int* a,int left,int right)
{
	assert(a);
	if(left<right)
	{
		int div = PartSort3(a,left,right);
		QuickSort3(a,left,div-1);
		QuickSort3(a,div+1,right);
	}
}
//打印函数
void PrintArray(int* a,size_t n)
{
	for(size_t i=0;i<n;++i)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;
}
//测试代码
void QuickSortTest()
{
    int a[]={2,5,4,0,9,3,6,8,7,1};
	PrintArray(a,sizeof(a)/sizeof(a[0]));
	QuickSort3(a,0,(sizeof(a)/sizeof(a[0]))-1);
	PrintArray(a,sizeof(a)/sizeof(a[0]));
}
2.时间复杂度:

   最好情况:O(nlogn)

   最坏情况:O(n^2)

   平均情况:O(nlogn)

   空间复杂度:O(nlogn)

3.稳定性:不稳定









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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值