Java六种排序算法

本文详细介绍了Java中常见的六种排序算法,包括冒泡排序、选择排序,并重点讲解了快速排序的基本思想和实现过程,旨在帮助读者深入理解排序算法的原理与应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、建立顺序表节点的类

package sorts;

public class RecordNode {
     private Comparable key;  //关键字
     private Object element;  //数据元素
     public Comparable getKey() {
		return key;
	}
	public void setKey(Comparable key) {
		this.key = key;
	}
	public Object getElement() {
		return element;
	}
	public void setElement(Object element) {
		this.element = element;
	}
	public RecordNode(Comparable key){
		this.key=key;
	}
	
	public RecordNode(Comparable key,Object element){
		this.key=key;
		this.element=element;
	}
}

二、构建顺序表

public class SeqList {
      private RecordNode[] r;  //顺序表记录结点数组
      private int curlen;  //顺序表长度,即记录个数
      //顺序表的构造方法,构造一个存储空间容量为maxSize的顺序表
      public SeqList(int maxSize){
    	  this.r=new RecordNode[maxSize];   //为顺序表分配maxSize个存储单元
    	  this.curlen=0;                   //置顺序表的当前长度为0
      }
     public RecordNode[] getRecord(){
    	 return r;
     }
     public void setRecord(RecordNode[] r){
    	 this.r=r;
     }
     public int getCurlen(){
    	 return curlen;
     }
}

三、冒泡排序

基本思想:每两个相邻的数相互比较,如果前一个数比后一个数大就交换位置,第一轮可以得出最大数,第二轮可以得出第二大的数,以此类推。

 public void bubbleSort(){
  	   RecordNode temp;             //辅助结点
  	   boolean flag=true;
  	   for(int i=1;i<this.curlen&&flag;i++){
  		   flag=false;
  		   for(int j=0;j<this.curlen-i;j++){
  			   if(r[j].getKey().compareTo(r[j+1].getKey())>0){
  				   temp=r[j];
  				   r[j]=r[j+1];
  				   r[j+1]=temp;
  				   flag=true;
  			   }
  		   }
  	   }
     }

四、快速排序

基本思想:一般选用第一个数作为支点。先从最后一个开始和支点比较,如果比支点大,则继续j--和支点比较,如果比支点小就和r[i]交换。交换后,就从左边第一个起,与支点比较,如果比支点小,则i++继续和支点比较,如果比支点大,就和r[j]相交换。一轮结束后,递归继续。

//1.一趟快速排序
     public int Partition(int i,int j){
    	 RecordNode pivot=r[i];             //第i个记录作为支点记录
    	 while(i<j){
    		 while(i<j&&pivot.getKey().compareTo(r[j].getKey())<=0){
    			 j--;
    		 }
    		 if(i<j){
    			 r[i]=r[j];                //将比支点记录关键字值小的记录向前移动
    			 i++;
    		 }
    		 while(i<j&&pivot.getKey().compareTo(r[i].getKey())>0){
    			 i++;
    		 }
    		 if(i<j){
    			 r[j]=r[i];              //将比支点记录关键字值大的记录向后 移动
    			 j--;
    		 }
    	 }
    	 r[i]=pivot;
    	 return i;
     }
     //2.采用递归形式进行快速排序
     public void qSort(int low,int high){
    	 if(low<high){
    		 int pivotloc=Partition(low,high);
    		 qSort(low,pivotloc-1);
    		 qSort(pivotloc+1,high);
    	 }
     }
     public void quickSort(){
    	 qSort(0,this.curlen-1);
     }

五、选择排序

基本思想:把最左边第一个的元素和右边的元素比较,左边的元素若较大,就相互交换位置。

//直接选择排序
     public void selectSort(){
    	 RecordNode temp;               //辅助结点
    	 for(int i=0;i<this.curlen-1;i++){             //n-1趟排序
    		 int min=i;
    		 for(int j=i+1;j<this.curlen;j++){
    			 if(r[j].getKey().compareTo(r[min].getKey())<0){
    				 min=j;
    			 }
    		 }
    		 if(min!=i){
    			 temp=r[i];
    			 r[i]=r[min];
    			 r[min]=temp;
    		 }
    	 }
     }

六、堆排序

//1.创建初始堆
     public void sift(int low,int high){
    	 int i=low;                          //子树的根节点
    	 int j=2*i+1;                        //j为i结点的左孩子
    	 RecordNode temp=r[i];
    	 while(j<high){                      //沿较小值孩子结点向下筛选
    		 if(j<high-1&&r[j].getKey().compareTo(r[j+1].getKey())>0){
    			 j++;                        //j为左右孩子的较小者
    		 }
    		 if(temp.getKey().compareTo(r[j].getKey())>0){  //若父母结点值较大,孩子结点中较小的值向上移
    			 r[i]=r[j];
    			 i=j;
    			 j=2*i+1;
    		 }
    		 else{
    			 j=high+1;                                 //退出循环
    		 }
    	 }
    	 r[i]=temp;
     }
     //2.堆排序
     public void heapSort(){
    	 int n=this.curlen;
    	 RecordNode temp;
    	 for(int i=n/2-1;i>=0;i--){                        //创建堆
    		 sift(i,n);
    	 }
    	 for(int i=n-1;i>0;i--){                           //每趟将最小关键字值交换到后面,再调整成堆
    		  temp=r[0];
    		  r[0]=r[i];
    		  r[i]=temp;
    		  sift(0,i);
    	 }
     }

七、归并排序

//1.两个相邻有序序列的归并
     public void merge(RecordNode[] r,RecordNode[] order,int h,int m,int t){
    	 int i=h,j=m+1,k=h;
    	 while(i<=m&&j<=t){                       //将r中两个相邻子序列归并到order中
    		 if(r[i].getKey().compareTo(r[j].getKey())<=0){            //较小值复制到order中
    			 order[k++]=r[i++];
    		 }
    		 else{
    			 order[k++]=r[j++];
    		 }
    	 }
    	 while(i<=m){                      //将前一个子序列剩余元素复制到order中
    		 order[k++]=r[i++];
    	 }
    	 while(j<=t){                     //将后一个子序列剩余元素复制到order中
    		 order[k++]=r[j++];
    	 }
     }
     //2.一趟归并排序算法
     public void mergepass(RecordNode[] r,RecordNode[] order,int s,int n){
    	 int p=0;        //p为每一对待组合并表的第一个元素的下标,初始值为0
    	 while(p+2*s-1<=n-1){            //两两归并长度均为s的有序表
    		    merge(r,order,p,p+s-1,p+2*s-1);
    		    p+=2*s;
    	 }
    	 if(p+s-1<n-1){                   //归并最后两个长度不等的有序表
    		 merge(r,order,p,p+s-1,n-1);
    	 }
    	 else{
    		 for(int i=p;i<=n-1;i++){     //将剩余的有序表复制到order中
    			 order[i]=r[i];
    		 }
    	 }
     }
     //3.2-路归并排序
     public void mergeSort(){
    	 int s=1;                     //s为已排序的子序列长度,初始值为1
    	 int n=this.curlen;
    	 RecordNode[] temp=new  RecordNode[n]; //定义长度为n的辅助数组temp
    	 while(s<n){
    		 mergepass(r,temp,s,n);    //一趟归并,将r数组中各子序列归并到temp中
    		 s*=2;                     //子序列长度加倍
    		 mergepass(temp,r,s,n);    //将temp数组中各子序列再归并到r中
    		 s*=2;   
    	 }
     }

八、插入排序

public void insertSort(){
    	 RecordNode temp;
    	 int i,j;
    	 for(i=1;i<this.curlen;i++){     //n-1趟扫描
    		 temp=r[i];                  //将待插入的第i条记录暂存在temp中
    		 for(j=i-1;j>=0&&temp.getKey().compareTo(r[j].getKey())<0;j--){
    			 r[j+1]=r[j];
    		 }
    		 r[j+1]=temp;
    	 } 
     }

九、实例

package sorts;

public class test {
	public static void main(String[] args) throws Exception{
		SeqList SL=new SeqList(20);
		RecordNode[] rd=new RecordNode[20];
		for(int i=0;i<rd.length;i++){
			rd[i]=new RecordNode((int)(Math.random() * 100));
		}
		SL.setRecord(rd);
		for(int j=0;j<rd.length;j++){
		    SL.insert(j,rd[j]);
		}
		//System.out.println("curlen="+SL.getCurlen());
		System.out.println("排序前:");
		for(int i=0;i<rd.length;i++){
			System.out.print(rd[i].getKey()+" ");
		}
		SL.bubbleSort();
		System.out.println(" ");
		System.out.println("冒泡排序后:");
		for(int i=0;i<rd.length;i++){
			System.out.print(rd[i].getKey()+" ");
		}
		SL.quickSort();
		System.out.println(" ");
		System.out.println("快速排序后:");
		for(int i=0;i<rd.length;i++){
			System.out.print(rd[i].getKey()+" ");
		}
		SL.selectSort();
		System.out.println(" ");
		System.out.println("选择排序后:");
		for(int i=0;i<rd.length;i++){
			System.out.print(rd[i].getKey()+" ");
		}
		SL.heapSort();
		System.out.println(" ");
		System.out.println("堆排序后:");
		for(int i=0;i<rd.length;i++){
			System.out.print(rd[i].getKey()+" ");
		}
		SL.mergeSort();
		System.out.println(" ");
		System.out.println("归并排序后:");
		for(int i=0;i<rd.length;i++){
			System.out.print(rd[i].getKey()+" ");
		}
		SL.insertSort();
		System.out.println(" ");
		System.out.println("插入排序后:");
		for(int i=0;i<rd.length;i++){
			System.out.print(rd[i].getKey()+" ");
		}
	}

}
十、运行结果





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值