排序算法

一、排序算法汇总(插入排序、交换排序、选择排序、合并排序、基数排序)

1.插入排序

    1.1直接插入排序(思想:依次将待排序序列中的每一个记录插入到一个已排好序的序列中,直到全部记录都排好序)

package edu.tcu.soft.insert;

public class DirectInsertSort {
    /*直接插入排序*/
	public int[] insertSort(int a[],int n){
		
		// a[0]作为临时一个存储单位和
		int i,j;
		for(i=2;i<=n;i++){
			a[0]=a[i];
			for(j=i-1;a[0]<a[j];j--){
				a[j+1]=a[j];
			}
			a[j+1]=a[0];
		}
		return a;
	}
}

    1.2希尔排序(插入排序的一种改进,思想:先将整个待排序记录序列分割成若干个子序列,在子序列内分别进行直接插入排序,待整个序列基本有序时,再对全体记录进行一次直接插入排序)

package edu.tcu.soft.insert;

public class ShellSort {
   /*希尔排序*/
	public int[] shellSort(int a[],int n){
		
		int d,i,j;
		for(d=n/2;d>=1;d=d/2){
          for(i=d+1;i<=n;i++){
        	  a[0]=a[i];
        	  for(j=i-d;j>0&&a[0]<a[j];j=j-d){
        		  a[j+d]=a[j];
        	  }
        	  a[j+d]=a[0];
          }
		}
		return a;
	}
}

2.交换排序

     2.1冒泡排序(思想:两两比较相邻记录的关键码,如果反序则交换,直到没有反序的记录为止)

package edu.tcu.soft.exchange;

public class BubbleSort {
	/*冒泡排序*/
    public int[] sort(int a[],int n){
    	int exchange=n;
    	while(exchange!=0){
    		int bound=exchange;
    		exchange=0;
    		for(int i=1;i<bound;i++){
    			if(a[i]>a[i+1]){
    				a[0]=a[i+1];
    				a[i+1]=a[i];
    				a[i]=a[0];
    				exchange=i;
    			}
    		}
    	}
    	return a;
    }
}

     2.2快速排序(分区交换排序,思想:首先选一个轴值,将待排序记录划分成独立的两部分,左侧记录的关键码均小于或等于轴值,右侧记录的关键码均大于或等于轴值)

package edu.tcu.soft.exchange;

public class QuickSort {
	/*快速排序*/
    public void sort(int a[],int first,int end){
    	if(first<end){
    		int m=parttition(a,first,end);
    		sort(a,first,m-1);
    		sort(a,m+1,end);
    	}
    }

	private int parttition(int[] a, int first, int end) {
        
		while(first<end){
			
			while(first<end&&a[end]>a[first])
				end--;
			if(a[end]<a[first]){
				int b=a[first];
				a[first]=a[end];
				a[end]=b;
				first++;
			}
			while(first<end&&a[first]<a[end])
				first++;
			if(a[first]>a[end]){
				int b=a[first];
				a[first]=a[end];
				a[end]=b;
				end--;
			}
		}
		return end;
	}
}

3.选择排序

     3.1直接选择排序(第i趟排序在待排序序列r[i]~r[n](1<=i<=n-1中选取关键码最小的记录,并和第i个记录交换作为有序序列的第i个记录)

package edu.tcu.soft.select;

public class SelectSort {
	/*直接选择排序*/
    public void select(int a[],int n){
    	int i,j;
    	for(i=1;i<=n;i++){
    		int index=i;
    		for(j=i+1;j<=n;j++){
    			if(a[index]>a[j])
    				index=j;
    		}
    		if(index!=i){
    			a[0]=a[i];
    			a[i]=a[index];
    			a[index]=a[0];
    			
    		}
    	}
    }
}

     3.2堆排序(利用堆(假设利用大根堆)的特性进行排序的方法,思想:首先将待排序的记录序列构造成一个堆,此时,选出了堆中所有的记录的最大者为堆顶记录。然后将堆顶记录移走,并将剩余的记录在调整成堆,这样又找出来次大的记录)

package edu.tcu.soft.select;

public class HeapSort {
	/*堆排序*/
	public void sort(int a[], int n)//0号单元用作交换操作的暂存单元 
	{
		for (int i = n / 2; i >= 1; i--)//初始建堆,从最后一个分支节点到根节点
			sift(a, i, n); // 初始建堆
		for (int i = 1; i<n; i++) { // 重复执行移走堆顶及重建堆的操作
			a[0] = a[1];
			a[1] = a[n-i+1];
			a[n-i+1] = a[0];
			sift(a,1,n-i);       //重建堆
		}
	}
    
	private void sift(int[] a, int k, int m)//0号单元用作交换操作的暂存单元 
	{
		int i = k;//i指向被筛选的节点,j指向结点i的左孩子
		int j = 2 * i;
		while (j <= m) //筛选还没有进行到叶子
		{
			if (j < m && a[j] < a[j + 1])//比较i的左右孩子,j指向较大者
				j++;  
			if (a[i] > a[j])//根节点已经大于左右孩子中的较大者
				break;
			else {
				//将根节点与结点j交换
				a[0] = a[i];
				a[i] = a[j];
				a[j] = a[0];
				//被筛选结点位于原来结点j的位置
				i=j;
				j=2*i;
			}
		}
	}
}

4.合并排序

     4.1合并排序(归并排序,思想:将若干有序序列逐步归并,最终归并成为一个有序序列)

 package edu.tcu.soft.merge;

/**
 *    合并排序
 */
public class MergeSort {
    //1.非递归实现
	public int[] mergeSortNonRecursion(int r[],int r1[],int n){
		int h=1;//初始时子序列长度为1
		while(h<n){
			mergePass(r,r1,n,h);//将待排序序列从数组r中传到数组r1中
			h=2*h;//更新子序列长度
			mergePass(r1,r,n,h);//将待排序序列从数组r1中传到数组r中
			h=2*h;//更新子序列长度
		}
		return r;
	}
    
	//递归实现
	public int[] mergeSortRecursion(int r[],int r1[],int s,int t){
		int m;
		if(s==t){
			return r;
		}else{
			m=(s+t)/2;
			mergeSortRecursion(r, r1, s, m);
			mergeSortRecursion(r, r1, m+1, t);
			merge(r, r1, s, m, t);
			return r;
		}
	}
	
	
	//一趟归并
	public void mergePass(int r[],int r1[],int n,int h){
		//从下标1开始存放待排序序列
		int i=0;
		//待归并记录至少有两个长度为h的子序列
		while(i<=n-2*h+1){
			merge(r,r1,i,i+h-1,i+2*h-1);
			i=i+2*h;
		}
		//待归并序列中有一个长度小于h
		if(i<n-h+1){
			merge(r,r1,i,i+h-1,n);
		}else{//待归并序列中只剩下一个子序列
			for(int k=i;k<=n;k++)
				r1[k]=r[k];
		}
			
	}
    
	//一次归并
	public void merge(int[] r, int[] r1, int s, int m, int t) {

       int i=s;
	   int j=m+1;
	   int k=s;
	   while(i<=m&&j<=t){
		   if(r[i]<=r[j])   //取r[i]和r[j]中的较小者放入r1[k]
			   r1[k++]=r[i++];
		   else
			   r1[k++]=r[j++];
	   }
	   if(i<=m){            //若第一个子序列没处理完,则进行收尾处理
		   while(i<=m)
			   r1[k++]=r[i++];
	   }else{              //若第二个子序列没处理完,则进行收尾处理
		   while(j<=t)
			   r1[k++]=r[j++];
	   }
	}
}

5.基数排序

     5.1基数排序



总结:

各种排序算法比较




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值