排序汇总(冒泡、插入、希尔排序、堆排序、归并排序)(java)

7-12 排序(25 分)

给定N个(长整型范围内的)整数,要求输出从小到大排序后的结果。

本题旨在测试各种不同的排序算法在各种数据情况下的表现。各组测试数据特点如下:

 

  • 数据1:只有1个元素;
  • 数据2:11个不相同的整数,测试基本正确性;
  • 数据3:103个随机整数;
  • 数据4:104个随机整数;
  • 数据5:105个随机整数;
  • 数据6:105个顺序整数;
  • 数据7:105个逆序整数;
  • 数据8:105个基本有序的整数;
  • 数据9:105个随机正整数,每个数字不超过1000。

     

  • 输入格式:

    输入第一行给出正整数N(≤10​5​​),随后一行给出N个(长整型范围内的)整数,其间以空格分隔。

    输出格式:

    在一行中输出从小到大排序后的结果,数字间以1个空格分隔,行末不得有多余空格。

    输入样例:

    11
    4 981 10 -17 0 -20 29 50 8 43 -5
    

    输出样例:

    -20 -17 -5 0 4 8 10 29 43 50 981

 思路:

1、各种排序算法适用的场景不同,但是优化后的排序明显比简单排序快的多。堆排序和归并排序好就好在,受数据的影响很小,即使在最差的情况下,时间也差不多。

2、堆排序,特别适用于从一个大量数据中找出顺序找出最大(小)的一部分。例如,从10000个数中按从小到大找出最大的100个数。

3、这里补充一点建堆的结论。自顶向下建堆,时间复杂度是O(NlogN),自下向上(每个节点向下过滤)建堆时间复杂度是O(N).

单位/ms

冒泡排序

插入排序

希尔排序sedgewick

堆排序

归并排序

只有一个元素

155

103

102

93

95

11个不相同整数

161

99

94

92

90

10^3个随机整数

200

162

141

140

136

10^4个随机整数

647

384

401

377

375

10^5个随机整数

超时

2639

1081

999

958

10^5个顺序整数

1464

1024

1096

1022

1010

10^5个逆序整数

超时

3843

959

1042

1024

10^5个基本有序的整数

2090

1081

898

1057

1045

10^5个随机正整数,每个数字不超过1000

超时

2388

957

997

978

 时间复杂度

O(N^2)

O(N^2)

O(N^3/2)

O(NlogN)

O(NlogN)

是否需要额外空间

N

稳定性

稳定

稳定

不稳定

不稳定

稳定

 

import java.io.IOException;
import java.io.StreamTokenizer;
import java.io.InputStreamReader;
import java.io.BufferedReader;

public class Main {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		
		in.nextToken();
		int n = (int) in.nval;
		int a [] = new int[n];
		for(int i = 0;i<n;i++) {
			in.nextToken();
			a[i] = (int) in.nval;
		}
//		bubble_sort(a,n);
//		insert_sort(a,n);
//		shell_sort(a,n);
		heap_sort(a, n);
//		merge_sort(a,n);
		print(a,n);
	}


	private static void print(int[] a,int n ) {			//打印结果
		// TODO Auto-generated method stub
		int flag=0;
		for(int i =0;i<n;i++) {
			if(flag !=0)
				System.out.print(" ");
			System.out.print(a[i]);
			flag =1;
		}
		
	}

	private static void bubble_sort(int[] a, int n) {	//冒泡排序
		// TODO Auto-generated method stub
		int temp;
		int flag =0;
		for(int i = 0;i<n-1;i++) {
			for(int j = 0;j<n-i-1;j++) {
				if(a[j]>a[j+1]) {
				temp = a[j];
				a[j] = a[j+1];
				a[j+1] = temp;
				flag =1;
				}
			}
			if(flag ==0)
				break;
			flag =0;
		}
	}

	private static void insert_sort(int a[],int n) {	//插入排序
		int j;
		for(int i =1;i<n;i++) {
			int tmp = a[i];
			for( j =i-1;j>=0&&a[j]>tmp;j--) {
					a[j+1]=a[j];
			}
			a[j+1] = tmp;
		}
	}
	
	private static void shell_sort(int[] a, int n) { // 希尔排序
		// TODO Auto-generated method stub
		Stack<Integer> st = sedgewick(n);
		while (!st.isEmpty()) {
			int i = st.pop();
//			System.out.println(i);
			for (int j = 0; j < i; j++) {
				for (int k = j + i; k < n; k += i) {
					int temp = a[k], p;
					for (p = k - i; p >= 0 && a[p] > temp; p -= i)
						a[p + i] = a[p];
					a[p + i] = temp;
				}
			}
		}
	}

	private static Stack<Integer> sedgewick(int n) {
		// TODO Auto-generated method stub
		Stack<Integer> st = new Stack<>();
		int i = 0, j = 2, s;
		do {
			int s1 = (int) (9 * Math.pow(4, i) - 9 * Math.pow(2, i)) + 1;
			int s2 = (int) (Math.pow(4, j) - 3 * Math.pow(2, j) + 1);
			if (s1 > s2) {
				s = s2;
				j++;
			} else {
				s = s1;
				i++;
			}
			st.push(s);
		} while (st.peek() < n);
		st.pop();
		return st;
	}
	private static void heap_sort(int[] a, int n) {		//堆排序
		int tmp,child,parent;
		for(int i = n/2-1;i>=0;i--) {
			tmp =a[i];
			for(parent =i;2*parent+1<n;parent =child) {
				child = 2*parent+1;
				if(child<n-1&&a[child]<a[child+1])
					child++;
				if(tmp>=a[child])
					break;
				else
					a[parent] = a[child];
			}
			a[parent] = tmp;
		}
		
		for(int i=n-1;i>0;i--) {
			tmp =a[0];
			a[0] = a[i];
			a[i] = tmp;
			
			tmp =a[0];
			for(parent =0;2*parent+1<i;parent =child) {
				child =2*parent+1;
				if(child<i-1&&a[child]<a[child+1]) 
					child++;
				if(tmp>a[child])
					break;
				else
					a[parent] = a[child];
			}
			a[parent] = tmp;
		}
	}
	
	private static void merge_sort(int a[],int n) {	//归并排序
		int temp [] = new int[n];
		int length=1;
		while(length<n) {
			merge_pass(a,temp,length,n);
			length*=2;
			merge_pass(temp,a,length,n);
			length*=2;
		}
	}


	private static void merge_pass(int[] a, int temp[],int length, int n) {
		int i;
		// TODO Auto-generated method stub
		for( i =0;i<=n-2*length;i+=2*length) {
			merge(a,temp,i,i+length,i+2*length-1);
		}
		
		if(n-i>length)
			merge(a,temp,i,i+length,n-1);
		else
			for(int k =i;k<n;k++) {
				temp[k] =a[k];
			}
		
		
	}


	private static void merge(int[] a, int[] temp, int L, int R, int right_end) {
		// TODO Auto-generated method stub
		int left_end =R-1;
		int k =L ;
		int num = right_end-L+1;
		while(L<=left_end&&R<=right_end) {
			if(a[L]<=a[R]) {
				temp[k] = a[L];
				k++;L++;
			}
			else {
				temp[k] = a[R];
				k++;R++;
			}
		}
		
		while(L<=left_end) {
			temp[k] =a[L];
			k++;
			L++;
		}
		
		while(R<=right_end) {
			temp[k] =a[R];
			k++;
			R++;
		}
		
		for(int i =k-1,j =0 ;j<num;j++,i--) {
			a[i] = temp[i];
		}
	}

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值