七种常见的排序算法--c++直接上代码,注释详细
class Solution { //常见7种排序算法
public:
Solution(){
}
//************************************
// 函数名称: bubbleSort
// 函数全称: Solution::bubbleSort
// 函数说明: 冒泡排序
// 函数属性: public
// 函数参数: vector<int> & a
// 返回值 : void
// Qualifier:
// 函数作者: Medal
// 编写时间: 2016/08/10 17:53:36
// 是否调试: Y
//************************************
void bubbleSort(vector<int> &a){ //冒泡排序算法
if(a.empty() || 1 == a.size()) return;
int aszie = (int)a.size();
for (int i = 0; i < aszie; ++i)
{
for (int j = aszie - 2; j >= i; --j )
{
if (a[j+1] < a[j]) //依次与相邻的元素比较,满足条件则交换
{
swap(a[j+1], a[j]);
}
}
}
}
//************************************
// 函数名称: bubbleSort2
// 函数全称: Solution::bubbleSort2
// 函数说明: 优化之后的冒泡排序,避免对已经有序的部分进行对于的比较操作
// 函数属性: public
// 函数参数: vector<int> & a
// 返回值 : void
// Qualifier:
// 函数作者: Medal
// 编写时间: 2016/08/10 17:54:17
// 是否调试: Y
//************************************
void bubbleSort2(vector<int> &a){ //优化的冒泡排序算法
if(a.empty() || 1 == a.size()) return;
int aszie = (int)a.size();
bool flag = true; //用于标记此次循环有没有交换元素,避免前面序列已经有序,还要继续比较的情况
for (int i = 0; i < aszie && flag; ++i)
{
flag = false;
for (int j = aszie - 2; j >= i; --j )
{
if (a[j+1] < a[j])
{
swap(a[j+1], a[j]);
flag = true;
}
}
}
}
//************************************
// 函数名称: selectSort
// 函数全称: Solution::selectSort
// 函数说明: 简单选择排序,从第一个元素开始,每次从未排序的部分序曲
// 第一个元素作为基准元素,并从剩余未排序的元素中找出最小的元素,如果满足条件就交换
// 函数属性: public
// 函数参数: vector<int> & a
// 返回值 : void
// Qualifier:
// 函数作者: Medal
// 编写时间: 2016/08/10 17:56:26
// 是否调试: Y
//************************************
void selectSort(vector<int> &a){//简单选择排序算法
if(a.empty() || 1 == a.size()) return;
int aszie = (int)a.size();
for (int i = 0; i < aszie; ++i)
{
//寻找第i个元素之后的小于第i元素的最小的元素
int minj = i;
for (int j = i + 1; j < aszie ; ++j)
{
if (a[minj] > a[j])
{
minj = j;
}
}
if (i != minj)
{
swap(a[i],a[minj]);
}
}
}
//************************************
// 函数名称: insertSort
// 函数全称: Solution::insertSort
// 函数说明: 简单插入排序,类比抓取扑克牌,从第一个元素i开始,后一个元素i+1与前一个元素比较,如果【i】>【i+1】
// 则从i向前搜索至小于【i+1】的元素j,依次将这之间的元素向后移位,将元素i+1放在j+1的位置,如此循环执行到最后一个元素即可
// 函数属性: public
// 函数参数: vector<int> & a
// 返回值 : void
// Qualifier:
// 函数作者: Medal
// 编写时间: 2016/08/10 17:59:24
// 是否调试: Y
//************************************
void insertSort(vector<int> &a){ //简单插入排序
if(a.empty() || 1 == a.size()) return;
int aszie = (int)a.size();
int mypos = a[0];
for (int i = 1; i< aszie; ++i)
{
mypos = a[i];
if (a[i] < a[i-1])
{
int j;
for (j = i-1; j>=0 && a[j] > mypos; --j) //将当前i位置之前大于i号元素的元素全部整体后移以为,然后插入i号元素
{
a[j+1] = a[j];
}
a[++j] = mypos;
}
}
}
//************************************
// 函数名称: shellSort
// 函数全称: Solution::shellSort
// 函数说明: 希尔排序,选取小于总长度的一个步长inc,从第一个元素i开始,与i+inc元素比较,满足条件则交换,并向前跳相同间隔的元素比较,若满足,也交换;依次循环至i+inc等于最后一个元素,即一遍
// 然后第二、三。。遍依次按照比例减小步长,重复操作,直至步长不大于1,停止
// 函数属性: public
// 函数参数: vector<int> & a
// 返回值 : void
// Qualifier:
// 函数作者: Medal
// 编写时间: 2016/08/10 18:06:58
// 是否调试: Y/N
//************************************
void shellSort(vector<int> &a){ //希尔排序---间隔相等点比较交换
if(a.empty() || 1 == a.size()) return;
int aszie = (int)a.size();
int inc = aszie;
do
{
inc = inc/6 + 1;
for (int i = inc; i < aszie; ++i)
{
if (a[i] < a[i-inc])
{
int mypos = a[i];
for (int j = i; j-inc >= 0 && a[j-inc]>a[j]; j-=inc) //依次循环前跳,交换前面所有间隔点上大于该元素的元素
{
swap(a[j],a[j-inc]);
}
}
}
} while (inc > 1); //最后的间隔必须大于1
}
//************************************
// 函数名称: heapSort
// 函数全称: Solution::heapSort
// 函数说明: 堆排序,先通过元素对半原则,从中间元素mid开始到第0个元素,依次比较其左右孩子节点,若孩子节点大于根节点,则交换,并以该孩子节点为
// 根节点依次做比较;然后对mid-1~0重复上述操作,从而形成大顶堆。形成大顶堆后,将最顶端元素(即最大元素)与最末尾元素对调,
// 并从顶端元素开始,调整除末尾元素外的堆元素,重新调整为大顶堆;循环至第1个节点,则停止;排序完成。
// 函数属性: public
// 函数参数: vector<int> & a
// 返回值 : void
// Qualifier:
// 函数作者: Medal
// 编写时间: 2016/08/10 21:38:53
// 是否调试: Y
//************************************
void heapSort(vector<int> &a){ //堆排序
if(a.empty() || 1 == a.size()) return;
int aszie = (int)a.size();
for (int i = aszie/2-1; i >=0; --i)
{
heapAdjust(a,i,(int)a.size()); //调整为大顶堆,最大的元素始终在堆顶;
}
for (int i = aszie-1; i > 0 ; --i)
{
swap(a[0],a[i]); //将堆顶元素,即最大的元素调换至堆尾,依次将次大元素调整到堆次尾
heapAdjust(a,0,i); //重新调整为大顶堆,将最大元素放到堆顶,以便下一次调至目前未排序的堆尾
}
}
//************************************
// 函数名称: mergeSort
// 函数全称: Solution::mergeSort
// 函数说明: 归并排序,对所有元素对半分组,标注每个分组的起始、中点、终点,分别对左右半组数据递归调用,至起点等于终点,则将该元素
// 存入输出数组;递归调用完毕后,按照从小到大合并两个半数组,至输出数组,即可。
// 函数属性: public
// 函数参数: vector<int> & a
// 返回值 : void
// Qualifier:
// 函数作者: Medal
// 编写时间: 2016/08/10 21:45:11
// 是否调试: Y
//************************************
void mergeSort(vector<int> &a){ //归并排序
if(a.empty() || 1 == a.size()) return;
int aszie = (int)a.size();
mSort(a,a,0,aszie-1); //归并排序核心程序
}
//************************************
// 函数名称: quickSort
// 函数全称: Solution::quickSort
// 函数说明: 快速排序
// 函数属性: public
// 函数参数: int a[]
// 函数参数: int n
// 返回值 : void
// Qualifier:
// 函数作者: Medal
// 编写时间: 2016/08/10 22:20:35
// 是否调试: Y
//************************************
void quickSort(int a[],int n){ //快速排序
if(n == 0 || 1 > n) return;
int *pos1 =a,*pos2 = a+n-1;
while(pos1 < pos2){
while(pos1< pos2 && *pos2 >= a[0]){--pos2;}
while(pos1< pos2 && *pos1 <= a[0]){++pos1;}
if (pos1<pos2)
{
swap(*pos1,*pos2);
}
}
swap(a[0],*pos1);
quickSort(a,pos1-a);
quickSort(pos1+1,n-(pos1-a)-1);
}
private:
//************************************
// 函数名称: heapAdjust
// 函数全称: Solution::heapAdjust
// 函数说明: 堆排序调整大顶堆函数,依次比较待调整元素pos的左右孩子,寻找大于pos节点的孩子,替换,并以该孩子为pos,循环调用至最后元素
// 函数属性: private
// 函数参数: vector<int> & a
// 函数参数: int pos //待调整元素在堆中的序号,序号从0开始编号
// 函数参数: int n //需要调整的元素的最大序号,此序号之后的元素不作调整(主要是在后面排序时起作用)
// 返回值 : void
// Qualifier:
// 函数作者: Medal
// 编写时间: 2016/08/10 22:14:06
// 是否调试: Y
//************************************
void heapAdjust(vector<int> &a,int pos,int n){
int leftpos = 2*pos+1;
int rightpos = 2*pos+2; //由于堆为完全二叉树,根据性质,可知pos号节点的左孩子和右孩子的编号
if (rightpos < n) //判断是否含有右孩子,如果有,则表明左右孩子均有
{
int nextpos = a[leftpos] > a[rightpos] ? leftpos : rightpos; //选取左右孩子中最大的孩子,作为比较节点
if (a[pos] < a[nextpos]) //如果比较节点的值大于根节点,则互换位置
{
swap(a[pos], a[nextpos] ); //互换位置
heapAdjust(a,nextpos,n); //并调整互换位置后的比较节点开始调整堆为大顶堆
}
}else if (leftpos < n ) //如果只是有左孩子,则只对左孩子进行上述操作
{
if ( a[pos] < a[leftpos] )
{
int nextpos = leftpos;
swap( a[pos], a[nextpos] );
heapAdjust(a,nextpos,n);
}
}
}
//************************************
// 函数名称: mSort
// 函数全称: Solution::mSort
// 函数说明: 归并排序核心程序,把数组分解成只有一个元素的子数组
// 函数属性: private
// 函数参数: vector<int>src 输入数组
// 函数参数: vector<int> & dst 排序输出数组
// 函数参数: int sta 数组起始点
// 函数参数: int ed 数组终止点
// 返回值 : void
// Qualifier:
// 函数作者: Medal
// 编写时间: 2016/08/10 22:17:48
// 是否调试: Y
//************************************
void mSort(vector<int>src,vector<int> &dst,int sta,int ed){
if (sta == ed)
{
dst[sta] = src[sta];
}else{
//vector<int> tep = src;
int mid = (sta+ed)/2;
mSort(src,dst,sta,mid);
mSort(src,dst,mid+1,ed);
myMerge(dst,dst,sta,mid,ed);
}
}
//************************************
// 函数名称: myMerge
// 函数全称: Solution::myMerge
// 函数说明: 合并排序
// 函数属性: private
// 函数参数: vector<int>src
// 函数参数: vector<int> & dst
// 函数参数: int sta 起点
// 函数参数: int mid 中点
// 函数参数: int ed 终点
// 返回值 : void
// Qualifier:
// 函数作者: Medal
// 编写时间: 2016/08/10 22:19:47
// 是否调试: Y
//************************************
void myMerge(vector<int>src,vector<int>&dst,int sta,int mid,int ed){
int i,j,k;
for (i = sta,j = mid +1,k=i; i <= mid && j <= ed;++k) //按照从小到大顺序放入目标数组
{
if (src[i] > src[j])
{
dst[k] = src[j++];
}else{
dst[k] = src[i++];
}
}
if (i <= mid) //存入剩下部分的元素至输出数组
{
for ( ; i <= mid; ++i)
{
dst[k++] = src[i];
}
}
if (j<=ed) //存入剩下部分的元素至输出数组
{
for (; j <= ed;++j )
{
dst[k++] = src[j];
}
}
}
};
int main()
{
Solution ss;
int a[]={50,10,90,30,70,40,80,60,20};
vector<int> va(a,a+sizeof(a)/sizeof(int));
string str("abca");
//print_vector(va);
//ss.bubbleSort(va);
//ss.bubbleSort2(va);
//ss.selectSort(va);
//ss.insertSort(va);
//ss.shellSort(va);
//ss.heapSort(va);
ss.mergeSort(va);
//ss.quickSort(a,sizeof(a)/sizeof(int));
//print_vector(va);
system("pause");
return 0;
}