几种排序算法比较

几种排序算法的性能比较


1.      从计算复杂度角度:

排序数据量的大小为n


2.      从系统资源的占用角度:

大部分排序算法都只需要使用1个元素的存储单元用来交换数据。而合并排序算法需要使用与原始序列一样长的n个元素的存储单元来保存多遍合并操作。

3.      从是不是稳定排序算法角度:

稳定排序算法:对于两个有相等关键字的数据D1和D2,在待排序的数据中D1出现在D2之前,在排序后的数据中D1也在D2之前,那么这就是一个稳定的排序算法。

冒泡排序算法、插入排序算法和合并排序算法都是稳定排序算法。而选择排序、Shell排序、快速排序、和堆排序算法都是不稳定排序算法。

4.      使用场合

如果数据量n较小,可以采用插入排序或选择排序法;

当数据量n较大时,则采用时间复杂度为O(nlogn)的排序算法,如快速排序、堆排序、或合并排序;

如果待排序的原始数据呈随机分布,那么快速排序算法的平均时间最短。

 

代码实现:

1.冒泡排序

/*冒泡排序*/
public class P4_1 {
	static final int SIZE=10;
	public static void bubbleSort(int[] a) {
		 int temp;
		 for (int i = 1; i < a.length; i++) {
              //将相邻两个数进行比较,较大的数往后冒泡
        	  for (int j = 0; j < a.length - i; j++) {
        		  if (a[j] > a[j + 1]) {
                   //交换相邻两个数
        			  temp=a[j];
        			  a[j]=a[j+1];
        			  a[j+1]=temp;
        		  }
        	  }
        	  System.out.print("第"+i+"步排序结果:");			//输出每步排序的结果
        	  for(int k=0;k<a.length;k++)
        	  {
        		  System.out.print(" "+a[k]); // 输出
        	  }
        	  System.out.print("\n"); 
		 }
	 } 

	public static void main(String[] args) {
		int[] shuzu=new int[SIZE];
		int i;
		for(i=0;i<SIZE;i++)
		{
			shuzu[i]=(int)(100+Math.random()*(100+1));			//初始化数组
		}
		System.out.print("排序前的数组为:\n");				//输出排序前的数组
		for(i=0;i<SIZE;i++)
		{
			System.out.print(shuzu[i]+" ");
		}
		System.out.print("\n");
		bubbleSort(shuzu);					//排序操作
		System.out.print("排序后的数组为:\n");
		for(i=0;i<SIZE;i++)
		{
			System.out.print(shuzu[i]+" ");					//输出排序后的数组
		}
		System.out.print("\n");

	}

}
运行结果:

排序前的数组为:
175 179 101 141 126 148 166 129 179 189 
第1步排序结果: 175 101 141 126 148 166 129 179 179 189
第2步排序结果: 101 141 126 148 166 129 175 179 179 189
第3步排序结果: 101 126 141 148 129 166 175 179 179 189
第4步排序结果: 101 126 141 129 148 166 175 179 179 189
第5步排序结果: 101 126 129 141 148 166 175 179 179 189
第6步排序结果: 101 126 129 141 148 166 175 179 179 189
第7步排序结果: 101 126 129 141 148 166 175 179 179 189
第8步排序结果: 101 126 129 141 148 166 175 179 179 189
第9步排序结果: 101 126 129 141 148 166 175 179 179 189
排序后的数组为:
101 126 129 141 148 166 175 179 179 189 

2.选择排序

/*选择排序*/
public class P4_2 {
	static final int SIZE=10;
	public static void selectSort(int[] a) 
	{
		 int index,temp;
         for (int i = 0; i < a.length-1; i++) 
         {
        	index = i;
        	for (int j = i+1; j <a.length; j++) 
        	{
        		if (a[j] < a[index]) 
        		{
        			index = j;
        		}
        	}
        	//交换两个数
        	if(index!=i)
        	{
        	temp=a[i];
        	a[i]=a[index];
        	a[index]=temp;
        	}
        	System.out.print("第"+i+"步排序结果:");			//输出每步排序的结果
    		for(int h=0;h<a.length;h++)
    		{
    			System.out.print(" "+a[h]);				//输出
    		}
    		System.out.print("\n");
        }
	}

	public static void main(String[] args) 
	{
		int[] shuzu=new int[SIZE];
		int i;
		
		for(i=0;i<SIZE;i++)
		{
			shuzu[i]=(int)(100+Math.random()*(100+1));			//初始化数组
		}
		
		System.out.print("排序前的数组为:\n");				//输出排序前的数组
		for(i=0;i<SIZE;i++)
		{
			System.out.print(shuzu[i]+" ");
		}
		
		System.out.print("\n");
		
		selectSort(shuzu);					//排序操作
		
		System.out.print("排序后的数组为:\n");
		for(i=0;i<SIZE;i++)
		{
			System.out.print(shuzu[i]+" ");					//输出排序后的数组
		}
		System.out.print("\n");

	}

}
运行结果:

排序前的数组为:
185 109 113 132 186 176 103 190 114 180 
第0步排序结果: 103 109 113 132 186 176 185 190 114 180
第1步排序结果: 103 109 113 132 186 176 185 190 114 180
第2步排序结果: 103 109 113 132 186 176 185 190 114 180
第3步排序结果: 103 109 113 114 186 176 185 190 132 180
第4步排序结果: 103 109 113 114 132 176 185 190 186 180
第5步排序结果: 103 109 113 114 132 176 185 190 186 180
第6步排序结果: 103 109 113 114 132 176 180 190 186 185
第7步排序结果: 103 109 113 114 132 176 180 185 186 190
第8步排序结果: 103 109 113 114 132 176 180 185 186 190
排序后的数组为:
103 109 113 114 132 176 180 185 186 190 

3.插入排序

/*插入排序*/
public class P4_3 
{
	static final int SIZE=10;
	static void insertionSort(int[] a)  				//插入排序
	{
	    int i,j,t,h;
	    for (i=1;i<a.length;i++)
	    {
			t=a[i];
			j=i-1;
			while(j>=0 && t<a[j])
			{
				a[j+1]=a[j];
				j--;
			}
			a[j+1]=t;

			System.out.print("第"+i+"步排序结果:");			//输出每步排序的结果
			for(h=0;h<a.length;h++)
			{
				System.out.print(" "+a[h]);				//输出
			}
			System.out.print("\n");
		}
	}
	public static void main(String[] args) 
	{
		int[] shuzu=new int[SIZE];
		int i;
		
		for(i=0;i<SIZE;i++)
		{
			shuzu[i]=(int)(100+Math.random()*(100+1));			//初始化数组
		}
		System.out.print("排序前的数组为:\n");				//输出排序前的数组
		for(i=0;i<SIZE;i++)
		{
			System.out.print(shuzu[i]+" ");
		}
		System.out.print("\n");
		
		insertionSort(shuzu);					//排序操作
		
		System.out.print("排序后的数组为:\n");
		for(i=0;i<SIZE;i++)
		{
			System.out.print(shuzu[i]+" ");					//输出排序后的数组
		}
		System.out.print("\n");

	}

}
运行结果:

排序前的数组为:
152 109 126 135 189 157 134 166 192 178 
第1步排序结果: 109 152 126 135 189 157 134 166 192 178
第2步排序结果: 109 126 152 135 189 157 134 166 192 178
第3步排序结果: 109 126 135 152 189 157 134 166 192 178
第4步排序结果: 109 126 135 152 189 157 134 166 192 178
第5步排序结果: 109 126 135 152 157 189 134 166 192 178
第6步排序结果: 109 126 134 135 152 157 189 166 192 178
第7步排序结果: 109 126 134 135 152 157 166 189 192 178
第8步排序结果: 109 126 134 135 152 157 166 189 192 178
第9步排序结果: 109 126 134 135 152 157 166 178 189 192
排序后的数组为:
109 126 134 135 152 157 166 178 189 192 

4.Shell排序

/*Shell排序*/
public class P4_4 
{
	static final int SIZE=10;
	static void shellSort(int[] a)  //Shell排序
	{
	    int i,j,h;
	    int r,temp;
		int x=0;

	    for(r=a.length/2;r>=1;r/= 2)						//划组排序
		{
	    	for(i=r;i<a.length;i++)
	    	{
				temp=a[i];
				j=i-r;
				while(j>=0 && temp<a[j])
				{
					a[j+r]=a[j];
					j-=r;
				}
				a[j+r]=temp;
			}

			x++;
			System.out.print("第"+x+"步排序结果:");			//输出每步排序的结果
			for(h=0;h<a.length;h++)
			{
				System.out.print(" "+a[h]);				//输出
			}
			System.out.print("\n");
		}
	}
	public static void main(String[] args)
	{
		int[] shuzu=new int[SIZE];
		int i;
		for(i=0;i<SIZE;i++)
		{
			shuzu[i]=(int)(100+Math.random()*(100+1));			//初始化数组
		}
		System.out.print("排序前的数组为:\n");				//输出排序前的数组
		for(i=0;i<SIZE;i++)
		{
			System.out.print(shuzu[i]+" ");
		}
		System.out.print("\n");
		
		shellSort(shuzu);					//排序操作
		
		System.out.print("排序后的数组为:\n");
		for(i=0;i<SIZE;i++)
		{
			System.out.print(shuzu[i]+" ");					//输出排序后的数组
		}
		System.out.print("\n");

	}

}
运行结果:

排序前的数组为:
112 176 110 109 182 149 134 184 199 168 
第1步排序结果: 112 134 110 109 168 149 176 184 199 182
第2步排序结果: 110 109 112 134 168 149 176 182 199 184
第3步排序结果: 109 110 112 134 149 168 176 182 184 199
排序后的数组为:
109 110 112 134 149 168 176 182 184 199 

5.快速排序

/*快速排序*/
public class P4_5 {
	static final int SIZE=18;
	static void quickSort(int[] arr,int left,int right)			//快速排序算法
	{
	    int f,t;
		int rtemp,ltemp;

	    ltemp=left;
	    rtemp=right;
	    f=arr[(left+right)/2];						//分界值
		while(ltemp<rtemp)
		{
	        while(arr[ltemp]<f)
			{
				++ltemp;
			}
	        while(arr[rtemp]>f) 
			{
				--rtemp;
			}
	        if(ltemp<=rtemp)
	        {
				t=arr[ltemp];
		        arr[ltemp]=arr[rtemp];
	    	    arr[rtemp]=t;
				--rtemp;
	        	++ltemp;
			}
	    }
	    if(ltemp==rtemp) 
		{
			ltemp++;
		}

	    if(left<rtemp) 
		{
			quickSort(arr,left,ltemp-1);			//递归调用
		}
	    if(ltemp<right) 
		{
			quickSort(arr,rtemp+1,right);			//递归调用
		}
	}
	public static void main(String[] args) 
	{
		int[] shuzu=new int[SIZE];
		int i;
		
		for(i=0;i<SIZE;i++)
		{
			shuzu[i]=(int)(100+Math.random()*(100+1));			//初始化数组
		}
		
		System.out.print("排序前的数组为:\n");				//输出排序前的数组
		for(i=0;i<SIZE;i++)
		{
			System.out.print(shuzu[i]+" ");
		}
		System.out.print("\n");
		
		quickSort(shuzu,0,SIZE-1);					//排序操作
		
		System.out.print("排序后的数组为:\n");
		for(i=0;i<SIZE;i++)
		{
			System.out.print(shuzu[i]+" ");					//输出排序后的数组
		}
		System.out.print("\n");

	}

}
运行结果:

排序前的数组为:
131 157 132 167 109 153 150 107 111 127 127 175 129 167 109 199 104 118 
排序后的数组为:
104 107 109 109 111 118 127 127 132 129 131 150 153 157 167 167 175 199 

6.堆排序

/*堆排序*/
public class P4_6 {
	static final int SIZE=10;
	static void heapSort(int a[],int n)					//堆排序
	{
	    int i,j,h,k;
	    int t;

	    for(i=n/2-1;i>=0;i--)    				//将a[0,n-1]建成大根堆
		{
			while(2*i+1<n) 					//第i个结点有右子树 
			{
				j=2*i+1 ;
				if((j+1)<n)
				{            
				    if(a[j]<a[j+1])			//右左子树小于右子树,则需要比较右子树
				        j++; 				//序号增加1,指向右子树 
				}
				if(a[i]<a[j])					//比较i与j为序号的数据
				{            
				    t=a[i];  				//交换数据 
					a[i]=a[j];
					a[j]=t;            
					i=j ;					//堆被破坏,需要重新调整
				}
				else 					//比较左右子结点均大则堆未破坏,不再需要调整
				{
					break;
				}
			}
		}
		//输出构成的堆
		System.out.print("原数据构成的堆:");		
		for(h=0;h<n;h++)
		{
			System.out.print(" "+a[h]);				//输出
		}
		System.out.print("\n");

	    for(i=n-1;i>0;i--)
	    {
	        t=a[0];							//与第i个记录交换
	        a[0] =a[i];
	        a[i] =t;
			k=0;
			while(2*k+1<i) 					//第i个结点有右子树 
			{
				j=2*k+1 ;
				if((j+1)<i)
				{            
				    if(a[j]<a[j+1])			//右左子树小于右子树,则需要比较右子树
					{
				        j++; 				//序号增加1,指向右子树 
					}
				}
				if(a[k]<a[j])				//比较i与j为序号的数据
				{            
				    t=a[k];  				//交换数据 
					a[k]=a[j];
					a[j]=t;            
					k=j ;					//堆被破坏,需要重新调整
				}
				else 					//比较左右子结点均大则堆未破坏,不再需要调整
				{
					break;
				}
			}

			System.out.print("第"+(n-i)+"步排序结果:");		//输出每步排序的结果
			for(h=0;h<n;h++)
			{
				System.out.print(" "+a[h]);			//输出
			}
			System.out.print("\n");
	    }  
	}
	public static void main(String[] args)
	{
		int[] shuzu=new int[SIZE];
		int i;
		
		for(i=0;i<SIZE;i++)
		{
			shuzu[i]=(int)(100+Math.random()*(100+1));			//初始化数组
		}
		
		System.out.print("排序前的数组为:\n");				//输出排序前的数组
		for(i=0;i<SIZE;i++)
		{
			System.out.print(shuzu[i]+" ");
		}
		System.out.print("\n");
		
		heapSort(shuzu,SIZE);					//排序操作
		
		System.out.print("排序后的数组为:\n");
		for(i=0;i<SIZE;i++)
		{
			System.out.print(shuzu[i]+" ");					//输出排序后的数组
		}
		System.out.print("\n");

	}

}
运行结果:

排序前的数组为:
181 106 184 144 122 139 161 136 173 161 
原数据构成的堆: 184 173 181 144 161 139 161 136 106 122
第1步排序结果: 181 173 161 144 161 139 122 136 106 184
第2步排序结果: 173 161 161 144 106 139 122 136 181 184
第3步排序结果: 161 144 161 136 106 139 122 173 181 184
第4步排序结果: 161 144 139 136 106 122 161 173 181 184
第5步排序结果: 144 136 139 122 106 161 161 173 181 184
第6步排序结果: 139 136 106 122 144 161 161 173 181 184
第7步排序结果: 136 122 106 139 144 161 161 173 181 184
第8步排序结果: 122 106 136 139 144 161 161 173 181 184
第9步排序结果: 106 122 136 139 144 161 161 173 181 184
排序后的数组为:
106 122 136 139 144 161 161 173 181 184 

7.合并排序

/*合并排序*/
public class P4_7 {
	static final int SIZE=15;
	static void mergeOne(int a[],int b[],int n,int len) 		//完成一遍合并的函数 
	{
	    int i,j,k,s,e;

	    s=0;
	    while(s+len<n)  
	    {
	        e=s+2*len-1;
	        if(e>=n) 						//最后一段可能少于len个结点 
			{
	            e=n-1;
			}
			//相邻有序段合并
			k=s;
			i=s;
			j=s+len;
			while(i<s+len && j<=e) 			//如果两个有序表都未结束时,循环比较 
			{
				if(a[i]<=a[j])				//如果较小的元素复制到数组b中 
				{
				   b[k++]=a[i++];
				}
				else
				{
					b[k++]=a[j++];
				}
			}
			while(i<s+len)					//未合并的部分复制到数组b中 
			{
				b[k++]=a[i++];
			}
			while(j<=e)
			{
			   b[k++]=a[j++]; 				//未合并的部分复制到数组b中 
			}

	        s=e+1; 						//下一对有序段中左段的开始下标 
	    }
	    if(s<n) 							//将剩余的一个有序段从数组A中复制到数组b中
		{
	        for(;s<n;s++)
			{
	            b[s]=a[s];
			}
		}
	}
	static void mergeSort(int a[],int n)				//合并排序
	{
//	    int *p;
		int h,count,len,f;

		count=0;							//排序步骤
	    len=1;     						//有序序列的长度 
	    f=0;								//变量f作标志
//	    if(!(p=(int *)malloc(sizeof(int)*n)))		//分配内存空间
//	    {
//	        printf("内存分配失败!\n");
//	        exit(0); 
//	    }
	    int[] p=new int[n];
	    while(len<n)
	    {
	        if(f==1)   						//交替在A和P之间合并 
			{
	            mergeOne(p,a,n,len);			//p合并到a
			}
	        else
			{
	            mergeOne(a,p,n,len);			//a合并到p
			}
	        len=len*2;						//增加有序序列长度
	        f=1-f; 							//使f值在0和1之间切换 

			count++;
			System.out.printf("第"+count+"步排序结果:");	//输出每步排序的结果
			for(h=0;h<SIZE;h++)
			{
				System.out.printf(" "+a[h]);			//输出
			}
			System.out.print("\n");

	    }
	    if(f==1)								//如果进行了排序
		{
	        for(h=0;h<n;h++)					//将内存p中的数据复制回数组a
			{
	            a[h]=p[h];
			}
		}
//	    free(p); 							//释放内存 
	}
	public static void main(String[] args) 
	{
		int[] shuzu=new int[SIZE];
		int i;
		
		for(i=0;i<SIZE;i++)
		{
			shuzu[i]=(int)(100+Math.random()*(100+1));			//初始化数组
		}
		
		System.out.print("排序前的数组为:\n");				//输出排序前的数组
		for(i=0;i<SIZE;i++)
		{
			System.out.print(shuzu[i]+" ");
		}
		System.out.print("\n");
		
		mergeSort(shuzu,SIZE);					//排序操作
		
		System.out.print("排序后的数组为:\n");
		for(i=0;i<SIZE;i++)
		{
			System.out.print(shuzu[i]+" ");					//输出排序后的数组
		}
		System.out.print("\n");

	}

}
运行结果:

排序前的数组为:
133 120 148 135 106 125 122 172 199 108 112 151 168 107 194 
第1步排序结果: 133 120 148 135 106 125 122 172 199 108 112 151 168 107 194
第2步排序结果: 120 133 135 148 106 122 125 172 108 112 151 199 107 168 194
第3步排序结果: 120 133 135 148 106 122 125 172 108 112 151 199 107 168 194
第4步排序结果: 106 107 108 112 120 122 125 133 135 148 151 168 172 194 199
排序后的数组为:
106 107 108 112 120 122 125 133 135 148 151 168 172 194 199 












评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值