C++数据结构--快速排序
2013-08-09 18:43
211 查看
1.对向量数组v{800,150,300,650,550,500,400,350,450,900}进行快速排序,索引[first,last)=[0,10)
*将v的元素划分为两个子表s1和S2,子表S1的元素都<=中心值,子表S2的元素都>=中心值
step1:取pivot=v[mid]=v[5]=500,作为中心值,并与v[first]交换,其中mid=(first+last)/2
整数指针scnUP从first+1开始往右扫描,scanDown从last-1开始往左扫描
step2:当scanUp,scanDown都找到不符合条件的元素时,交换它们,再继续扫描
step3:继续step2的步骤
step4:当scanUp>=scanDown时,停止划分子表,scanDown指向的就是俩个子表的分界点,同时也是存放v[0]的中心值的最终位置。
step5:对子表s1,s2重复step1-step4
step6:对子表s1
step7:当子表为空或只有一个元素时,停止递归
step8:对子表s2
step9:继续对更小的子表进行划分
step10:处理更小的子表
最终结果:
实现代码:
#include<iostream>
#include<vector>
using namespace std;
template<typename T>
//交换两个元素
void mySwap(T &v1,T &v2)
{
T temp;
temp=v1;
v1=v2;
v2=temp;
}
template<typename T>
/*返回向量数组分界点的下标
*在[first,last)范围内,把比v[(first+last)/2]
*小的元素放左边,比v[(first+last)/2]大的元素
*放右边,
*/
int pivotIndex(vector<T> &v,int first,int last)
{
int mid=(first+last)/2; //中间元素下标索引
T pivot=v[mid];//记录中间元素的值
mySwap(v[first],v[mid]);//把中间元素和第一个元素交换位置
int scanUp=first+1; //向右扫描的索引
int scanDown=last-1; //向左扫描的索引
while(true)
{
while(scanUp<=scanDown&&v[scanUp]<=pivot)
scanUp++;
while(scanUp<=scanDown&&v[scanDown]>=pivot)
scanDown--;
if(scanUp>=scanDown)//到达分界点,跳出循环
break;
mySwap(v[scanUp++],v[scanDown--]);
}
mySwap(v[first],v[scanDown]); //交换第一个元素(保存中间元素的值)和临界点索引处的元素
return scanDown;
}
template<typename T>
//在向量数组[first,last)范围内进行快速排序
void quickSort(vector<T> &v,int first,int last)
{
if(last-1<=first) //当子表为空或只有一个元素时,停止递归
return;
if(first==last-2) //当只有两个元素时,判断是否需要交换,以提高效率
{
if(v[first]>v[last-1])
{
mySwap(v[first],v[last-1]);
}
return;
}
else
{
int mid=pivotIndex(v,first,last);
quickSort(v,first,mid); //对左子表递归
quickSort(v,mid+1,last); //对右子表递归
}
}
测试代码
int main ()
{
vector<int> vec{800,150,300,650,550,500,400,350,450,900};
quickSort(vec,0,vec.size());
for(int x:vec)
cout<<x<<ends;
return 0;
}
运行结果:
以上的划分找中值和递归感觉比较繁琐,个人认为另一种划分方法更为简便,详见
*将v的元素划分为两个子表s1和S2,子表S1的元素都<=中心值,子表S2的元素都>=中心值
step1:取pivot=v[mid]=v[5]=500,作为中心值,并与v[first]交换,其中mid=(first+last)/2
整数指针scnUP从first+1开始往右扫描,scanDown从last-1开始往左扫描
step2:当scanUp,scanDown都找到不符合条件的元素时,交换它们,再继续扫描
step3:继续step2的步骤
step4:当scanUp>=scanDown时,停止划分子表,scanDown指向的就是俩个子表的分界点,同时也是存放v[0]的中心值的最终位置。
step5:对子表s1,s2重复step1-step4
step6:对子表s1
step7:当子表为空或只有一个元素时,停止递归
step8:对子表s2
step9:继续对更小的子表进行划分
step10:处理更小的子表
最终结果:
实现代码:
#include<iostream>
#include<vector>
using namespace std;
template<typename T>
//交换两个元素
void mySwap(T &v1,T &v2)
{
T temp;
temp=v1;
v1=v2;
v2=temp;
}
template<typename T>
/*返回向量数组分界点的下标
*在[first,last)范围内,把比v[(first+last)/2]
*小的元素放左边,比v[(first+last)/2]大的元素
*放右边,
*/
int pivotIndex(vector<T> &v,int first,int last)
{
int mid=(first+last)/2; //中间元素下标索引
T pivot=v[mid];//记录中间元素的值
mySwap(v[first],v[mid]);//把中间元素和第一个元素交换位置
int scanUp=first+1; //向右扫描的索引
int scanDown=last-1; //向左扫描的索引
while(true)
{
while(scanUp<=scanDown&&v[scanUp]<=pivot)
scanUp++;
while(scanUp<=scanDown&&v[scanDown]>=pivot)
scanDown--;
if(scanUp>=scanDown)//到达分界点,跳出循环
break;
mySwap(v[scanUp++],v[scanDown--]);
}
mySwap(v[first],v[scanDown]); //交换第一个元素(保存中间元素的值)和临界点索引处的元素
return scanDown;
}
template<typename T>
//在向量数组[first,last)范围内进行快速排序
void quickSort(vector<T> &v,int first,int last)
{
if(last-1<=first) //当子表为空或只有一个元素时,停止递归
return;
if(first==last-2) //当只有两个元素时,判断是否需要交换,以提高效率
{
if(v[first]>v[last-1])
{
mySwap(v[first],v[last-1]);
}
return;
}
else
{
int mid=pivotIndex(v,first,last);
quickSort(v,first,mid); //对左子表递归
quickSort(v,mid+1,last); //对右子表递归
}
}
测试代码
int main ()
{
vector<int> vec{800,150,300,650,550,500,400,350,450,900};
quickSort(vec,0,vec.size());
for(int x:vec)
cout<<x<<ends;
return 0;
}
运行结果:
以上的划分找中值和递归感觉比较繁琐,个人认为另一种划分方法更为简便,详见
C++数据结构--快速排序
相关文章推荐
- 数据结构---快速排序---java与c++实现
- c++实现数据结构中的各种排序方法:直接插入、选择,归并、冒泡、快速、堆排序、shell排序
- C++代码,数据结构-内部排序-交换排序-快速排序
- 数据结构与算法:C++实现快速排序
- 数据结构 - 2-路插入排序 具体解释 及 代码(C++)
- 数据结构与算法之---快速排序
- 【python】python数据结构(七)——排序:快速排序
- 数据结构-排序算法详解(插入排序,希尔排序,堆排序,归并排序,快速排序,桶式排序)
- C/C++ 库函数快速排序 qsort
- 快速排序C++实现
- C++ 快速排序
- 快速排序的c++代码实现
- 【东东学数据结构】快速排序
- 快速排序C++实现
- 数据结构:快速排序
- c++ 快速排序
- 快速排序C++
- C++三种排序,快速排序、选择排序、冒泡排序----简单代码
- 快速排序c++和python对比分析
- 快速排序:Sort:QuickSort using C++