首页 > 编程语言 >排序算法(实践篇)

排序算法(实践篇)

时间:2022-11-22 11:34:05浏览次数:44  
标签:sort int void 实践 算法 swap 排序 hp

排序算法(实践篇)

插入排序

  • 直接插入

    void insert_sort(int q[],int n)
    {
    	int i,j;
    	for(i=2;i<=n;i++) 
    	{
    		if(q[i]<q[i-1]) //q[i]<q[i-1]说明要将q[i]插入前面的有序表
    		{
    			q[0]=q[i];//哨兵=q[i]记录下这个要插入的数值,q[i]比q[i-1]小,要把它放前面
    			
    			for(j=i-1;q[0]<q[j];j--)  //只要当前这个待插入数比q[j]小,就继续往前找
    				q[j+1]=q[j];  //遍历的同时不断地后移数组,为q[i]让出位置
    				
    			q[j+1]=q[0];  //把q[i]插入到合适的位置
    		}
    	}
    }
    
  • 折半插入

    void insert_sort(int q[],int n)
    {
    	int l,r,mid;
    	for(int i=2;i<=n;i++)
    	{
    		if(q[i]<q[i-1])
    		{
    			q[0]=q[i];
    			
    			l=1,r=i-1;
    			while(l<=r)
    			{
    				mid=(l+r)/2;
    				if(q[mid]>q[0]) r=mid-1;
    				else l=mid+1;
    			}
    			//二分查找到q[i]应该插入的位置
    			
    			for(int j=i-1;j>=r+1;j--)
    				q[j+1]=q[j];
    			//从后往前将数组往后移动,直到j遇到那个q[i]预插入的位置
    			
    			q[j+1]=q[0];
    		}
    	}
    }
    

交换排序

  • 冒泡排序

    • 从前往后扫描

      void bubble_sort(int q[],int n)
      { 
      	for(int i=0;i<n-1;i++)  //最多进行n-1趟排序,每次把最小的数冒泡上浮到0,1,2…
      	{
      		bool flag=false;
      		for(int j=0;j<n-i-1;j--)  //j<n-i-1是因为q[n-i-1]到q[n-1]是已确定最终位置的元素
      		{
      			if(q[j+1]>q[j])
      			{
      				swap(q[j+1],q[j]);
      				flag=true;
      			}
      		}
      		if(!flag) return; //如果flag==false,说明本趟没有发生排序,排序完成
      	}
      }
      
    • 从后往前扫描

      void bubble_sort(int q[],int n)
      { 
      	for(int i=0;i<n-1;i++)  //最多进行n-1趟排序,每次把最小的数冒泡上浮到0,1,2…
      	{
      		bool flag=false;
      		for(int j=n-1;j>=i;j--)  //j>=i是因为q[0]到q[i]是经确定最终位置的元素
      		{
      			if(q[j-1]>q[j])
      			{
      				swap(q[j-1],q[j]);
      				flag=true;
      			}
      		}
      		if(!flag) return; //如果flag==false,说明本趟没有发生排序,排序完成
      	}
      }
      
    • PS:从前往后扫描k遍和从后往前扫描k遍的结果是不一样的,不要用从前往后的逻辑写从后往前

  • 快速排序

    • void quick_sort(int q[],int l,int r)
      {
          if(l>=r) return;
          
          //step1:选择一个基准x,将数组分成两边,一边的数全小于x,一边的数全大于x
          int i=l-1,j=r+1,x=q[(l+r)/2];
          while(i<j)
          {
              do i++;while(q[i]<x);
              do j--;while(q[j]>x);
              if(i<j) swap(q[i],q[j]);
          }
          
          //step2:对数组分成的两边子数组,递归地进行第一步的操作
          quick_sort(q,l,j),quick_sort(q,j+1,r);
      }
      

选择排序

  • 简单选择排序

    //第i趟从L[i~n]选择关键字最小的元素和L[i]交换,每趟排序确定一个最终位置
    void SelectSort(int q[],int n)
    {
    	for(int i=0;i<n-1;i++)
    	{
    		int min=i;
    		for(int j=i+1;j<n;j++)
    	    	if(q[j]<q[min]) min=j;
    	    
    	    swap(q[i],q[min]);
    	}
    }
    
  • 堆排序

    #include<bits/stdc++.h>
    using namespace std;
    const int N=100010;
    
    int h[N],size;
    int ph[N],hp[N];
    //ph数组存储:第i个插入的数在h数组中的下标
    //hp数组存储:h数组中的某个下标是第几个插入的
    //实现的功能是:任意检索、删除第k个插入的数
    //h[ph[k]]就是第k个插入的数,ph[k]就是第k个插入的数下标
    //至于hp数组是heap_swap()中的辅助数组
    
    void heap_swap(int a,int b)
    {
    	swap(ph[hp[a]],ph[hp[b]]);
    	swap(hp[a],hp[b]);
    	swap(h[a],h[b]);
    }
    
    void up(int k)
    {
    	while(u/2&&h[u/2]>h[u])
    	{
    		heap_swap(u/2,u);
    		u/=2;
    	}
    }
    //把下标为k的结点向上调整
    
    void down(int k)
    {
    	int t=k;
    	if(k*2<=size&&h[k*2]<h[t]) t=k*2;
    	if(k*2+1<=size&&h[k*2+1]<h[t]) t=k*2+1;
    	//让t等于k以及k左右儿子中的最小值
    	
    	if(k!=t)
    	{
    		heap_swap(k,t);
    		down(t);
    	}
    	//如果k(父节点)不是三个结点中的最小值,则交换,递归往下
    }
    //把下标为k的结点向下调整
    
    void insert(int x)
    {
    	size++;
    	m++;
    	ph[m]=size,hp[size]=m;
    	h[size]=x;
    	up(x);
    }
    //插入一个数
    
    int getmin()
    {
    	return h[1];
    }
    //返回堆顶元素
    
    void popmin()
    {
    	heap_swap(1,size);
    	size--;
    	down(1);
    }
    //弹出堆顶元素
    
    void popk(int k)
    {
    	k=ph[k];
    	heap_swap(k,size);
    	size--;
    	down(k),up(k);
    }
    //弹出第k个插入的数
    

其他排序

  • 归并排序

    void merge_sort(int q[],int l,int r)
    {
    	if(l>=r) return;
    	
    	//step1:分别对左右两侧子序列进行递归排序
    	int mid=(l+r)/2;
    	merge_sort(q,l,mid);
    	merge_sort(q,mid+1,r);
    	
    	//step2:将两个分别有序的子序列合并成一个有序序列
    	int k=0,i=1,j=mid+1;
    	while(i<=mid&&j<=r)
    		if(q[i]<=q[j]) tmp[k++]=q[i++];
    		else tmp[k++]=q[j++];
    	
    	while(i<=mid) tmp[k++]=q[i++];
    	while(j<=r) tmp[k++]=q[j++];
    	
    	//step3:将辅助数组里的有序序列写回q[]数组中
    	for(int i=0,j=0;i<=r;i++,j++) q[i]=tmp[j];
    }
    

标签:sort,int,void,实践,算法,swap,排序,hp
From: https://www.cnblogs.com/pinoky/p/16914599.html

相关文章

  • 排序算法(理论篇)
    排序算法(理论篇)插入排序直接插入:时间:O(n2);空间:O(1)比较次数分析最好情况(全正序):n-1次最坏情况(全逆序):n(n-1)/2次一般情况分析举例:对于21,32,46,40的序列从小......
  • go模拟实现反向代理各种算法
    packageutiltypeHttpServerstruct{HoststringWeightint}typeLoadBalancestruct{Server[]*HttpServerCurrentIndexint}varMapWeight[]intfunc......
  • 二叉排序树(BST树)
    二叉排序树(BST树)一、介绍二叉排序树:所有叶子结点都要求左子结点比当前结点小,右子结点比当前结点大。优点:查询速度,新增结点速度都会更快。每判断一个结点,都会选择去往......
  • 算法2:Hanoi塔
    汉诺(Hanoi)塔一、背景介绍在印度,有这么一个古老的传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针......
  • 24.基于数据结构和算法的深入【双元】(1)
                                                         ......
  • 每日算法之二叉树中和为某一值的路径(一)
    JZ82二叉树中和为某一值的路径(一)代码packageesay.JZ82二叉树中和为某一值的路径1;importjava.util.*;classTreeNode{intval=0;TreeNodeleft=......
  • 数组部分基础&冒泡排序
    数组基础知识 1.数组的创建格式:变量(数组)类型变量(数组)名=变量(数组)值int[]nums;//声明一个数组nums=newint[10];//创建一个数组int[]nums=new......
  • 冒泡排序法
    voidBubbleSort(ints[],intn){//函数参数:数组与数组大小 inti,j,temp; for(i=0;i<n-1;i++)//从0开始进行n-1轮排序 {......
  • 代码随想录算法训练营Day05|242. 有效的字母异位词、349. 两个数组的交集、202. 快乐
    代码随想录算法训练营Day05|242.有效的字母异位词、349.两个数组的交集、202.快乐数、1.两数之和242.有效的字母异位词题目链接:242.有效的字母异位词题干要求两字......
  • 服饰3D柔性渲染调研及实践
    服饰3D柔性渲染调研及实践调研背景 当前全球服装制造的产业链中,我国的中小企业的难以参与到其中利润最高的环节比如产品的设计和研发,主要原因就是服装设计的难度......