java 排序算法 折半 堆 希尔 快速 整理

试题1:折半查找

折半查找是在有序表中,把待查找数据值与查找范围的中间元素值进行比较,会有三种情况出现:

1)待查找数据值与中间元素值正好相等,则放回中间元素值的索引。

2)待查找数据值比中间元素值小,则以整个查找范围的前半部分作为新的查找范围,执行1),直到找到相等的值。

3)待查找数据值比中间元素值大,则以整个查找范围的后半部分作为新的查找范围,执行1),直到找到相等的值

4)如果最后找不到相等的值,则返回不存储数据的备用单位0。

给你的问题是,标准输入一升序排列有序整数表,使用折半查找方法查找一个给定的整数值,查找中是通过使用表中的元素与给定的元素值进行比较完成查找,需要你依次输出在折半查找过程中使用过比较的元素值。

输入:标准输入,输入的第一行为一个正整数n,表示需要查找表的元素个数;第二行为具有升序序列的n个整数,两数之间为一个空格隔开;第三行为需要你查找的整数。

输出:标准输出,第一行依次输出在查找过程中进行比较的元素值,两数之间使用一个空格隔开。输出的第二行输出查找结果,如果查找元素在表中,输出该元素的序号(从1开始编号),如果查找元素不在表中,输出“NO"。

输入样例:

13

7 14 18 21 23 29 31 35 38 42 46 49 52

21

输出样例:

31 18 23 21

4

思路:用递归,实现起来比较简单。

import java.util.*;
public class Main {

	public static void main(String[] args) {
		int n, m;
		int[] s;
		Scanner in = new Scanner(System.in);
		n = in.nextInt();
		s = new int[n+1];
		for(int i = 1; i <= n; i++)
			s[i] = in.nextInt();
		m = in.nextInt();
		find(1, n, m, s);
		in.close();
	}

	public static void find(int s, int e, int m, int[] st){
		int index = (s + e) / 2;
		if(st[index] < m){
			System.out.printf(st[index] + " ");
			find(index+1, e, m, st);
		}else if(st[index] > m){
			System.out.printf(st[index] + " ");
			find(s, index-1, m, st);
		}else
			System.out.printf("%d\n%d\n", st[index], index);
	}
}

试题2:堆排序

堆排序的思想实际上利用完全二叉树存储在数组中,通过调整完全二叉树成为大顶堆获得一个排序表的最大值进行排序的方法,大顶堆满足根节点比子树旳节点大。堆排序主要是通过大顶堆旳根元素与未完成排序旳最后一个元素进行交换,将交换后旳完全二叉树不满足大顶堆要求调整到满足满足要求,调整通过如下方法完成:

void heapAdjust(int[] R,int s,int t);其中,数组R中存储旳二叉树,只有以R[s]为根子树,其左右子树之间可能不满足大顶堆特征。

调整堆旳操作难点为根子树节点编号为i,则左子树节点编号为2*i,右子树节点编号为2*i+1;通过比较子树旳大小选择大旳子树进行调整,一直调整到根节点比子节点大,再将根节点旳值插入到最后调整旳节点。要完成堆排序,在调整旳基础上可以通过从堆底往堆顶进行调整获得初始堆,然后通过N-1次调整完成排序,控制流程为:

void heapSort(int[] R){

int i;

int N=R.length-1;

for(i=N/2;i>0;i--){

heapAdjust(R,i,N);

}

for(i=N;i>1;i--){

R[0]=R[1];R[1]=R[i];R[i]=R[0];

heapAdjust(R,1,i-1);

}

}

给你旳问题是,将标准输入的n个整数采用堆排序,并需要显示建成旳初始堆,并完成该数据的排序。

输入:标准输入,输入的第一行为整数的个数n值,第二行为n个整数,每个整数之间为一个空格。

输出:标准输出,第一行依次输出排序过程中建成旳初始堆在数组中的存储值,每个输出数据之间使用一个空格隔开,第二行输出排序后的序列,每个输出数据之间使用一个空格隔开。

输入样例:

14

39 80 76 41 13 29 50 78 30 11 100 7 41 86

输出样例:

100 80 86 78 39 41 76 41 30 11 13 7 29 50

7 11 13 29 30 39 41 41 50 76 78 80 86 100

import java.util.Scanner;

public class Main {   

	public static void main(String args[]) {
		Scanner in=new Scanner(System.in);
		int n = in.nextInt();
		int[] array = new int[n + 1];

		for(int i = 1; i <= n; i++)
			array[i] = in.nextInt();

		adjust(array);
		print(array);
		heapSort(array);
		print(array);
		in.close();
	}  

	//输出
	public static void print(int[] list) {
		System.out.print(list[1]);
		for (int i = 2; i < list.length; i++) {
			System.out.print(" " + list[i]);
		}
		System.out.println();
	}   

	//交换
	public static void swap(int[] heap, int a, int b) {
		int temp = heap[a];
		heap[a] = heap[b];
		heap[b] = temp;
	}   

	//根据定义,树节点前一半是有孩子的,所以,从这里开始调整
	public static void adjust(int[] heap){
		for (int i = heap.length / 2; i > 0; i--)
			adjust(heap, i, heap.length - 1);
	}  

	public static void adjust(int[] heap,int i, int n) {
		int child;
		while (i <= n / 2) {
			child = i * 2;
			if(child + 1 <= n && heap[child] < heap[child + 1])
				child += 1;//使child指向值较大的孩子
			if(heap[i] < heap[child]){
				swap(heap, i, child);
				//交换后,以child为根的子树不一定满足堆定义,所以从child处开始调整
				i = child;
			}  else break;
		}
	}

	//对一个最大堆heap排序
	public static void heapSort(int[] heap) {
		for (int i = heap.length - 1; i > 0; i--) {
			//把根节点跟最后一个元素交换位置,调整剩下的n-1个节点,即可
			swap(heap,1, i);
			adjust(heap,1, i - 1);
		}
	}
}   

试题3:快速排序

快速排序的核心操作是划分,通过某个数据将原来排序表分成两部分,前面部分比该数小,后面数据比该数据大或相等,该数据就为排序后的位置,即该数据完成排序。如果定义一个排序表的划分方法为:      int
partition(int[] R,int low,int high);     其中,low,high表示将数据R的第low个数据到high个数据进行划分,返回到整数为划分后到支点记录位置;     定义完成划分方法后,通过如下调用完成快速排序:     void QuickSort(int[] R,int s,int t){           if(s<t){              i=partition(R,s,t);              QuickSort(R,s,i-1);              
QuickSort(R,i+1,t);          }     }     建议每次划分选择第一个元素为支点记录进行编程。给你到问题是,将标准输入的n个整数采用快速排序,并需要显示出每次划分所使用到分支点记录,并完成该数据的排序。输入:标准输入,输入的第一行为整数的个数n值,第二行为n个整数,每个整数之间为一个空格。输出:标准输出,输出的第一行依次输出排序过程中使用的支点记录,每个输出数据之间使用一个空格隔开,第二行输出排序后的序列,每个输出数据之间使用一个空格隔开。输入样例:1439 80 76 41
13 29 50 78 30 11 100 7 41 86输出样例:39 7 11 30 13 50 41 76 100 86 78 7 11 13 29 30 39 41 41 50 76 78 80 86 100

import java.util.*;

public class Main {
	//用于保存使用的支点记录
	private static List<Integer> ans;

	public static void main(String[] args) {
		ans = new ArrayList<Integer>();
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int[] a = new int[n + 1];
		for(int i = 1; i <= n; i++){
			a[i] = in.nextInt();
		}
		QuickSort(a, 1, n);
		//输出使用的支点记录
		print_ans();
		//输出排序后的值
		print(a);
		in.close();
	}

	public static void QuickSort(int[] R, int s, int t){
		if(s < t){
			int i = partition(R, s, t);
			ans.add(R[i]);
			QuickSort(R, s, i-1);
			QuickSort(R, i+1, t);
		}
	}

	public static int partition(int[] R, int s, int t){
		int i = s, j = t;
		int x = R[s];
		while(i < j){
			//从右向左找小于x的数来填R[i]
			while(i < j && R[j] >= x)
				j--;
			if(i < j){
				R[i] = R[j];
				i++;
			}
			//从左向右找大于或等于x的数来填R[j]
			while(i < j && R[i] < x)
				i++;
			if(i < j){
				R[j] = R[i];
				j--;
			}
		}
		R[i] = x;
		return i;
	}

	public static void print(int[] R){
		System.out.print(R[1]);
		for(int i = 2; i < R.length; i++){
			System.out.print(" " + R[i]);
		}
		System.out.println();
	}

	public static void print_ans(){
		if(!ans.isEmpty()){
			System.out.print(ans.get(0));
			for(int i = 1; i < ans.size(); i++){
				System.out.print(" " + ans.get(i));
			}
			System.out.println();
		}
	}

}

试题4:希尔排序

希尔排序的思想是:先选择一个小于排序数据个数n的整数di(称为步长,一般为小于n的质数),将间隔di的数为一组,对每组的元素进行直接插入排序,即将需要排序的数据插入到已经排序好拢到序列中。当步长为1时,完成整个数据的排序。排序的流程为:

1、根据步长的个数,对于每个步长进行分组;

2、对每组进行插入排序,主要操作如下:

1)如果未有存在未有序的数据,将该数据存储到临时遍历R[0]中;

2)将前面比他大的数据全部向后移动一位;

3)再将R[0]的数据插入到最后移动到数据位置;

给你到问题是,将标准输入的n个整数采用希尔排序,步长取5,3,1,并需要显示出每次需要插入的数,并完成该数据的排序。

输入:标准输入,输入的第一行为整数的个数n值,第二行为n个整数,每个整数之       间为一个空格。

输出:标准输出,输出第一行依次输出排序过程中需要插入的数,每个输出数据之间使用一个空格隔开,第二行输出排序后的序列,每个输出数据之间使用一个空格隔开。

输入样例:

14

39 80 76 41 13 29 50 78 30 11 100 7 41 86

输出样例:

29 50 30 11 7 41 39 13 86 7 29 11 30 41 50 80 78

7 11 13 29 30 39 41 41 50 76 78 80 86 100

import java.util.*;

public class Main {

	//用于保存每次需要插入的数
	private static List<Integer> ans;

	public static void main(String[] args) {
		ans = new ArrayList<Integer>();
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int[] a = new int[n];
		for(int i = 0; i < n; i++){
			a[i] = in.nextInt();
		}
		shellsort(a);
		//输出每次需要插入的数
		print_ans();
		//输出排序后的结果
		print(a);
		in.close();
	}

	public static void shellsort(int[] data) {
		int j = 0;
		int temp = 0;
		for (int increment = 5; increment > 0; increment -= 2) {
			for (int i = increment; i < data.length; i++) {
				temp = data[i];
				boolean flag = true;
				for (j = i; j >= increment; j -= increment) {
					if(temp < data[j - increment]){
						data[j] = data[j - increment];
						if(flag) {
							ans.add(temp);
							flag = false;
						}
					}else break;
				}
				data[j] = temp;
			}
		}
	} 

	public static void print(int[] R){
		System.out.print(R[0]);
		for(int i = 1; i < R.length; i++){
			System.out.print(" " + R[i]);
		}
		System.out.println();
	}

	public static void print_ans(){
		if(!ans.isEmpty()){
			System.out.print(ans.get(0));
			for(int i = 1; i < ans.size(); i++){
				System.out.print(" " + ans.get(i));
			}
			System.out.println();
		}
	}
}
时间: 2024-10-12 23:56:22

java 排序算法 折半 堆 希尔 快速 整理的相关文章

Java排序算法(四):希尔排序

[基本思想] 将原本有大量记录数的记录进行分组,分割成若干个子序列,此时每个子序列待排序的记录个数就比较少了,然后在这些子序列内分别进行直接插入排序,当整个序列都基本有序时,再对全体记录进行一次直接插入排序. 所谓的基本有序,就是小的关键字基本在前面,大的基本在后面,不大不小的基本在中间,像{2, 1, 3, 6, 4, 7, 5, 8, 9}这样可以称为基本有序了. [java实现] public class ShellSort { public static void main(String

Java排序算法-Java入门|Java基础课程

Java 排序算法 1. 课程目标 排序是任何语言都会使用到的功能之一,然成果排序的算法有很多,对空间的要求及其时间效率也不尽相同. 本文章以Java语言示例,通过对空间要求.时间效率要求,来对比各种排序算法的使用场景 2.适用对象 Java语言初学者 Java算法爱好者 3.相关概念 3.1 排序概念 排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作. 3.2 排序算法 排序算法,就是如何使得记录按照要求排列的方法. 排序算法在很多领域得到相当地重视,尤其是在

Java排序算法(一)

Java排序算法(一) 一.排序的基本概念和分类 1.1排序的定义 在<大话数据结构>中,排序定义为,假设含有n个记录的序列为{r1,r2,...,rn},其相应的关键字{k1,k2,...,kn},需确定1,2...n的一种排列p1,p2...pn,是其相应的关键字满足Kp1<=Kp2<=...<=Kpn(非递减或非递增)关键,即使得序列称为一个按关键字有序的序列{rp1,rp2...rp3},这样的操作称为排序. 1.2排序的稳定性 假设ki=kj(1<=i<

java排序算法(六):直接插入排序

java排序算法(六):直接插入排序 直接插入排序的基本操作就是将待的数据元素按其关键字的大小插入到前面的有序序列中 直接插入排序时间效率并不高,如果在最坏的情况下,所有元素的比较次数的总和为(0+1..n-1)= o(n^2).其他情况下也要考虑移动元素的次数.故时间复杂度是o(n^2) 直接插入空间效率很好,只需要一个缓存数据单元,也就是说空间复杂度是o(1) 直接插入排序是稳定的 直接插入排序在数据以有一定顺序的情况下,效率较好.但如果数据无规则,则需要移动大量的数据.其效率就和冒泡排序和

Java排序算法 - 堆排序的代码

把内容过程中比较重要的一些内容片段做个备份,如下的资料是关于Java排序算法 - 堆排序的内容. import java.util.Arrays; public class HeapSort { int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51}; public HeapSort(){ heapSort(a); } public void heapSort(int[

java排序算法之希尔排序

希尔排序是冲破二次时间屏障的第一批算法之一. 它是通过比较相距一定间隔的元素来工作,各趟比较所用的距离随着算法的进行而减小,直到最后一趟(比较相邻元素)为止.因此希尔排序也叫缩减增量排序. 希尔排序使用一个序列h1,h2,h3...hk来排序. 具体的意思是 第一趟排序比较的是相隔为hk的元素,也就是比较a[i]与a[i+hk],保证a[i]<=a[i+hk]. 第二次比较的是相隔为hk-1的元素,也就是比较a[i]与a[i+hk-1],保证a[i]<=a[i+hk-1]. 直到最后比较的是相

js排序算法总结——冒泡,快速,选择,插入,希尔,归并

相信排序是任何一个程序猿都会用到的东西,今天简单总结记录下常见的排序算法. 一.冒泡排序 说起冒泡排序,可能每个人都不会陌生,实现思路相当简单明了,就是不停的对数组进行两两比较,将较大(较小)的一项放在前面: 如 var arr = [7, 3, 10, 1, 8, 4, 2, 4, 4, 3] 进行升序排列,排序过程如下 第一次 [3, 7, 1, 8, 4, 2, 4, 4, 3, 10] 第二次 [3, 1, 7, 4, 2, 4, 4, 3, 8, 10] 以此类推 .... 结果 [1

(转)java 排序算法

排序算法汇总(java实现,附源代码) 整理系统的时候发现了原来写的各种算法的总结,看了一下,大吃一惊,那时候的我还如此用心,具体的算法,有的已经模糊甚至忘记了,看的时候就把内容整理出来,顺便在熟悉一下,以后需要的时候就可以直接过来摘抄了.下面是总结的几个常用的排序算法: 插入排序 快速排序 冒泡排序 堆排序 计数排序 桶排序 可能大家对插入排序,快速排序,冒泡排序比较常用,在满足需求的时候也简单一些,下面逐一说一下每个算法的实现方式,不保证是写的最有效率的,但是能保证的是,各种算法的中心思想是

Java排序算法总结

稳定排序:* 泡沫排序(bubble sort) — O(n²)* 插入排序 (insertion sort)— O(n²)* 桶排序 (bucket sort)— O(n); 需要 O(k) 额外空间* 计数排序 (counting sort) — O(n+k); 需要 O(n+k) 额外空间* 合并排序 (merge sort)— O(n log n); 需要 O(n) 额外空间* 二叉排序树排序 (Binary tree sort) — O(n log n)期望时间; O(n²)最坏时间;