七种常见的排序算法--c++直接上代码,注释详细



七种常见的排序算法--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;
} 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值