从头学算法之-分治法-快速排序

上一篇博客写了归并排序,作为一个程序员必要掌握的排序算法,有冒泡排序,选择排序,快速排序等,而这其中,快速排序几乎是最爱被涉及的,以前学习算法时,没有注重具体的方法,比如分治法,关于分治法的概念,上一篇博客已经写了,不再赘述,有一次上课,我们的算法老师,老战,问了我们大家一个问题,说大家有没有人能在15分钟内写出,冒泡排序,选择排序,快速排序,那时大家基本都沉默了,不想说中国教育的不是,主要的原因是,我自己平时没有打下很好的基础,没有多下功夫打好这些根基,所以才有了今天的冲动,来写这些博客,说实话,一方面,是写给自己看的,另一方面,是想存储下自己的所学,尽管年纪稍大,尽管还在为未来苦苦挣扎,下好每一分功夫,重头再来,终会有一点效果,废话不多说,来实惠的。

下面简介一下快速排序(当然,借用一下百度百科的智慧)

快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

为了使得说明更具体举一个例子:3,2,1,8,4,9,5,6

我们选择第一个数字3作为被比较的数字,每次默认被划分区域的第一个数字为被比较的数字

假设开始时i指向3,j指向5,各趟划分如下

                               (2, 1) 3 ( 8 , 4,9 , 5, 6)

                               /                    \

                           (1)2          ( 5 ,4, 6) 8 ( 9 )

                                                /           

                                          (4) 5 (6)

最终排序结果 1 2 3 4 5 6 8 9

#include <iostream>
#include <stdlib.h>

using namespace std;
void swap(int a[],int b[])
{
	int temp=*a;
	*a=*b;
	*b=temp;
}

/*第一种分割函数写法*/
int Partition(int a[],int first,int end)
{
	int i=first;
	int j=end;              //确定左右边界(有的人会使j=end+1,使得j成为一个哨兵结点,防止越界) 
	int pivot = a[first];   //与第二种分割函数不同处,这里指定了一个比较数,相当于分割的标记,这个数的左边小于等于它,数的右边大于等于它 
	while(i<j)              //大前提是i<j,否则一趟分割结束 
	{
		if(a[i]<=pivot) i++;
		if(a[j]>=pivot) j--;
		if(i<j)
	    swap(a[i],a[j]);    //指针左右移动,并进行比较,交换 
	}
	swap(a[first],a[j]);    //一趟分割结束,给指定那个数找到了最终的位置,我们可以形象地理解为插了一面旗帜,划定了左右界限 
	return j;
}


/*第二种分割函数写法*/ 
int partition(int a[],int first,int end)//与第一种不同,第二种没有指定一个数进行比较,其实综合理解后,发现默认第一个数或最后一个数就是被比较的,而是前后比较 
{
	int i=first;
	int j=end;
	while(i<j)
	{
		while(i<j&&a[i]<a[j]) j--;//从右边开始扫描,当i<j,a[i]<a[j],右边指针向左移动,j-- 
		if(i<j)  
		{
			swap(a[i],a[j]);
			i++;
		}                             //当i<j条件满足,但出现a[i]>=a[j]情况,左边指针向右移动i++, 
		while(i<j&&a[i]<a[j]) i++;   //从左边开始扫描  当i<j,a[i]<a[j],左边指针向左移动,i++
		if(i<j)                      
		{
			swap(a[i],a[j]);
			j--;
		}                            //当i<j条件满足,但出现a[i]>=a[j]情况,右边指针向左移动,j-- 
	}
	return i;                        //左右指针相遇或错过,最终定位 
	
}

int QuickSort(int a[],int first,int end) 
{
if(first<end)
{
	int pivot = Partition(a,first,end);   
	//int pivot = partition(a,first,end);
	QuickSort(a,first,pivot-1);
	QuickSort(a,pivot+1,end);
	
}
}

int main()
{
	int a[8]={3,2,1,8,4,9,5,6};
	for(int i=0;i<8;i++)
	cout<<a[i]<<" ";
	cout<<endl;
	
	QuickSort(a,0,7);
	for(int i=0;i<8;i++)
	cout<<a[i]<<" ";
	cout<<endl;
	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值