【排序学习】

冒泡法

/*
1.冒泡排序:遍历一遍,将相临的两个元素进行比较,并将较大/小值放到一边,一直沿着序列进行重复操作,就像一个泡泡一样冒到最左/右边
循环法:
*/
 int bubble_sort(int *buf,int n)
 {
	 if(n<2)
		 return -1;
	 
	 int i=0,j=0,temp=0;
	 for(i=n-1;i>0;i--)//一共对比n-1轮
	 {
		 for(j=0;j<i;j++)//每一轮都有
		 {
			 if(buf[j]>buf[j+1])
			 {
				 temp = buf[j+1];
				 buf[j+1] = buf[j];
				 buf[j] = temp;
			 }
		 }
	 }
 }
 
 /*
 1.冒泡排序:
 递归法
 */
 int bubble_sort2(int *buf,int n)
 {
	 if(n<2)
		 return -1;
	 
	 int i=0,j=0,temp=0;

	 for(j=0;j<n-1;j++)//每一轮都有
	 {
		 if(buf[j]>buf[j+1])
		 {
			 temp = buf[j+1];
			 buf[j+1] = buf[j];
			 buf[j] = temp;
		 }
	 }
	 bubble_sort2(buf,--n);
 }

在这里插入图片描述

选择排序法

/*
1.选择排序:遍历一遍,找到最值,依次放到左\右侧
*/
 int select_sort(int *buf,int n)
 {
	 if(n<2)
		 return -1;
	 
	 int i=0,j=0,minpos=0;
	 for(i=0;i<n-1;i++)//一共对比n-1轮
	 {
		 minpos = i;
		 for(j=i+1;j<n;j++)//每一轮都有
		 {
			 if(buf[j]<buf[minpos])
			 {
				 minpos = j;
			 }
		 }
		 
		 if(minpos != i)//如果本轮查找到的最小的是首个元素,则不需要更改序列位置
		 {	 
			 swap(&buf[i],&buf[minpos]);
		 }
	 }
 }
 
 /*
 1.选择排序:
 递归法
 */
 int select_sort2(int *buf,int n)
 {
	 if(n<2)
		 return -1;
	 
	 int i=0,j=0,minpos=0;

	 for(j=0;j<n;j++)//每一轮都有
	 {
		 if(buf[j]<buf[minpos])
		 {
			 minpos = j;
		 }
	 }
	 
	 if(minpos != 0)//如果本轮查找到的最小的是首个元素,则不需要更改序列位置
	 {	 
		 swap(&buf[i],&buf[minpos]);
	 }
		 
	 select_sort2(buf+1,--n);
 }

使用最大最小值来优化,空间换时间

 int select_sort(int *buf,int n)
 {
	 if(n<2)
		 return -1;
	 
	 int i=0,j=0,left,right,maxpos,minpos=0;
	 left = 0;
	 right = n-1;
	 
	 while(left<right)
	 {
		 minpos = maxpos = left;
		for(j=left;j<=right;j++)//每一轮都有
	  {
		 if(buf[j]<buf[minpos])
		 {
			 minpos = j;
		 }
		 
		 if(buf[j]>buf[maxpos])
		 {
			 maxpos = j;
		 }	 
	  }
		
		if(minpos != left)//如果本轮查找到的最小的是首个元素,则不需要更改序列位置
		{	 
			swap(&buf[left],&buf[minpos]);
		}
		
		if(minpos != right)//如果本轮查找到的最小的是首个元素,则不需要更改序列位置
		{	 
			swap(&buf[right],&buf[maxpos]);
		}
		
		left++;
		right--;
	 }

插入排序

/*
1.选择排序:遍历一遍,找到最值,依次放到左\右侧
*/
 int insert_sort(int *buf,int n)
 {
	 if(n<2)
		 return -1;
	 
	 int i=0,j=0,min=0,minpos=0;
	 
	 for(i=1;i<n;i++)
	 {
			min = buf[i];
			for(j=i-1;j>=0;j--)
			{
				if(buf[j]<=min)
					{break;}
				
				buf[j+1]=buf[j];
			}
			buf[j+1] = min;
	 }	 
 }

插入排序的缺陷:
1.要寻找插入的合适位置
2.要移动元素

优化方案:
1.对于已经排好序的序列,采用二分法查找
2.一次携带多个元素进行查找,找到合适的就插入一个
3.数据链表化
4.希尔排序

希尔排序

希尔排序是插入排序的一种,它是将一列数据,每次取长度的一半,规划为多个小组,然后小组内进行一次插入排序。然后重复执行步骤直到一个小组内只有一个元素。最后进行一次插入排序。它的优点是,可以快速让大量数列整体大致排列有序,减少查找次数,减少元素移动次数。
在这里插入图片描述

代码

/*对一个小组的数据进行插入排序*/
 int group_sort(int *buf,int n,int pos,int step)
 {
	if(n<2)
	 return -1;
	int i=0,j=0,min=0,minpos=0;

	for(i=pos+step;i<n;i=i+step)
	{
		min = buf[i];
		for(j=i-step;j>=0;j-=step)
		{
			if(buf[j]<=min)
				{break;}
			
			buf[j+step]=buf[j];
		}
		buf[j+step] = min;
	}	 
 }
 
 /*按组划分,依次将步长、位置传输过去,进行一个小组的插入排序*/
 void shell_sort(int *buf,int n)
 {
	 int step=0,i=0;
	 for(step=(n/2);step>0;step/=2)
	 {
		 for(i=0;i<step;i++)
		 {
			 group_sort(buf,n,i,step);
		 }
	 }
 }

快速排序

/*快速排序算法
第一种思路:抽空插入算法,就是先将一个数据提取出来作为标准,然后将找到的比它的小放到左边,大的放到右边。
取出一个值作为标准,取最左边为左下标,最右边为右下标,先移动右下标,找到第一个比它小的值放到空槽,然后再以这个取出来的值的空位,再起左右下标,移动左下标
找到第一个比它大的值放到空槽,一直重复到左右下标重合。
*/
 int quicksort(int *buf,int n)
 {
  if(n<2)
	  return -1;
	
	int temp = buf[0];
	int left = 0;
	int right = n-1;
	int moving = 2;
	
	while(left<right)
	{
		//buf[left];
		if(moving==1)//移动的是左下标
		{
			if(buf[left]<=temp)
			{
				left++;
				continue;
			}
			buf[right] = buf[left];
			right--;
			moving = 2;
			continue;
		}
		
		
		if(moving==2)//移动的是右下标
		{
			if(buf[right]>=temp)
			{
				right--;
				continue;
			}
			buf[left] = buf[right];
			left++;
			moving = 1;
			continue;
		}
			
	}
	
	/*当左右坐标值重合时,循环结束,就需要将中心轴的值填进去*/
	buf[left] = temp;
	quicksort(buf,left);
	quicksort(buf+left+1,n-left-1);
	
 }

第二种思路:
将最左一个作为标准,然后依次往后查看,如果小于标准值就换到左边来,大于它就逐渐挤在一块排到右边去了。然后再找下一位作为标准。
在这里插入图片描述

归并排序

/*归并排序:本质上是,先以二分形式,依次将它们分成一半一半的,最后分成一个为一组,再进行组合,
 每次组合进行比较,比较后再重新放入暂存的数组中去。最后将暂存数组的数据导出到原数组中。*/
 void mergesort(int *buf,int *temp_buf,int start,int end)
 {
	if(start>=end)
			return -1;
	
	int mid = (start + end)/2;
	
	//递归部分
	mergesort(buf,temp_buf,start,mid);//将中心轴左边的拆分
	mergesort(buf,temp_buf,mid + 1,end);//将中心轴右边的拆分
	
	int left = start;
	int right = mid + 1;
	int temp = left;
	
	//把对比后的放入暂时存放的数组中
	while(left<=mid&&end>=right)
	{
			if(buf[left]>buf[right])
				temp_buf[temp++] = buf[right++];
			else
				temp[temp++] = buf[left++];
	}
	
	while(right<=end)
	{
		temp_buf[temp++] = buf[right++];
	}
	
	while(left<=mid)
	{
		temp_buf[temp++] = buf[left++];
	}
	
	while(left<=right)
	{
		buf[left] = temp_buf[left];
		left++;
	}
	
 }

堆排序

本质上是将数据以完全二叉树的形式,做成大顶堆,然后再依次以最后一个节点与最顶端的父节点交换,交换完之后,与自己最大的子节点对比是否比它小,如果小就与调换顺序,当子节点再和之前的孙子节点对比。。。
在这里插入图片描述
在这里插入图片描述

//start:节点下标,end:最后一个元素的下标
void heapify(int *buf,int start,int end)
{
	int dad = start;
	int son = dad * 2 + 1;//公式得出
	
	//遍历完所有元素
	while(son<=end)
	{
		//子节点与另一个节点对比,找到最大的一个
		if((son+1<=end)&&(buf[son]<buf[son+1]))
			son++;
		
		//如果父节点比最大子节点都大,就不需要继续找下去了
		if(buf[dad]>buf[son])
			return ;
		
		//如果父节点比最大子节点小,就交换,然后还需要父节点继续作为子节点与孙子节点比较
		swap(&buf[dad],&buf[son]);
		dad = son;
		son = dad*2+1;
	}
}

void heapsort(int *buf,int len)
 {
	int i = 0;
	
	//取最后一个父节点,重新规划
	for(i=(len-1)/2;i>;i--)
		heapify(buf,i,len-1);
	
	for(i=len-1;i>0;i--)
	{
		swap(&buf[0],&buf[i]);
		heapify(buf,0,i-1);	
	}
	
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值