目录
试题1:快速排序
快速排序的核心操作是划分,通过某个数据将原来排序表分成两部分,前面部分比该数小,后面数据比该数据大或相等,该位置就为某数据排序后的位置,即该数据完成排序。如果定义一个排序表的划分方法为:
int partition(int[] R,int low,int high); 其中,low,high表示将数据R的第low个数据到high个数据进行划分,返回到整数为划分后到支点存储的位置;快速排序在查找分支点位置的方法有多种,本题目的排序过程中,首先从右向左移动,搜索小于分支记录的第一个元素,再从左向右移动,搜索大于分支记录的第一个元素,交互该两个记录值,继续搜索,直到两个搜索点交汇,如果交汇点记录与分支记录相等,分支记录与交汇点数据不交换,分支位置为交汇位置; 完成划分方法后,通过递归调用完成快速排序:
void QuickSort(int[] R,int s,int t){
if(s<t){
int i=partition(R,s,t);
QuickSort(R,s,i-1);
QuickSort(R,i+1,t);
}
}
建议每次划分选择第一个元素为支点记录进行编程。给你到问题是,将标准输入的n个整数采用快速排序,并需要显示出每次划分分支点存储的位置,第一个数为0,分支点的输出顺序按照程序递归产生的分支点的先后进行输出,并完成该数据的排序。
输入:标准输入,输入的第一行为整数的个数n值,第二行为n个整数,每个整数之间为一个空格。
输出:标准输出,输出的第一行依次输出排序过程中使用的支点位置,每个输出数据之间使用一个空格隔开,第二行输出排序后的序列,每个输出数据之间使用一个空格隔开。
输入样例:
14
39 80 76 41 13 29 50 78 30 11 100 7 41 86
输出样例:
5 3 2 1 8 6 9 13 12 10
7 11 13 29 30 39 41 41 50 76 78 80 86 100
类别:[ 程序类 ] 难度:[ 中等 ] 入库时间:2016-6-6 [ 在线测试 ]
import java.util.Scanner;
//????????
public class TestQuickSort {
public static void main(String[] args) {
//????????
int n;int[] data;
Scanner in=new Scanner(System.in);
n=in.nextInt();
data=new int[n];
for(int i=0;i<n;i++)
data[i]=in.nextInt();
//????????
quicksort(data,0,data.length-1);
//???????????
System.out.println();
for(int i=0;i<n;i++)
System.out.print(data[i]+" ");
}
public static void quicksort(int[] data, int low, int high) {
if(low<high)
{
//????????
int i=partition(data,low,high);
System.out.print(i+" ");
//???????????????
quicksort(data,low, i-1);
//???????????????
quicksort(data,i+1, high);
}
}
private static int partition(int[] data, int low, int high) {
//??????????????
int i=low;
int j=high;
int temp;
//????????????????
int base=data[low];
//????????????????
while(i<j){
//1.???????????j,????????С?????????
while(i<j&&data[j]>=base)
j--;
//2.???????????i,??????????????????????data[i]
while(i<j&&data[i]<=base)
i++;
//3.???????????????
if(i<j)
{temp=data[i];
data[i]=data[j];
data[j]=temp;
}
}
//4.????????????λ??
if(data[j]<data[low])
{temp=data[low];
data[low]=data[j];
data[j]=temp;
}
return i;
}
}
试题2:希尔排序
希尔排序的思想是:先选择一个小于排序数据个数n的整数di(称为步长,一般为小于n的质数),将间隔di的数为一组,对每组的元素进行直接插入排序,即将需要排序的数据插入到已经排序好的序列中。当步长为1时,完成整个数据的排序。排序的流程为:
1、根据步长的个数,对于每个步长进行分组;
2、对每组进行插入排序,主要操作如下:
1)如果待插入数据比前一个数据小,将该数据存储到临时遍历temp中;
2)将前面比他大的数据全部向后移动一位;
3)再将temp的数据插入到最后移动的数据位置;
给你到问题是,将标准输入的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
类别:[ 程序类 ] 难度:[ 中等 ] 入库时间:2016-6-6 [ 在线测试 ]
import java.util.Scanner;
//???????
public class Shellsort {
public static void main(String[] args) {
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);
System.out.println();
print(a);
in.close();
}
public static void shellsort(int[] data) {
int j = 0;
int temp = 0;
for (int d = 5; d > 0; d -= 2) {
for (int i = d; i < data.length; i++) {
temp = data[i];
boolean flag = true;
for (j = i; j >= d; j -= d) {
if(temp < data[j - d]){
data[j] = data[j - d];
if(flag) {
System.out.print(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();
}
}
试题3:折半查找
折半查找是在有序表中,把待查找数据值与查找范围的中间元素值进行比较,会有三种情况出现:
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
类别:[ 程序类 ] 难度:[ 中等 ] 入库时间:2016-6-6 [ 在线测试 ]
import java.util.ArrayList;
import java.util.Scanner;
class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] a = new int[n + 1];
for (int i = 1; i <= n; i++) {
a[i] = sc.nextInt();
}
ArrayList arr = new ArrayList<>();
int x = sc.nextInt();
// 二分查找
int l = 1, r = n;
while (l <= r) {
int mid = (l + r) >> 1;
arr.add(a[mid]);
if (x > a[mid]) {
l = mid + 1;
} else if (x < a[mid]) {
r = mid - 1;
} else {
break;
}
}
for (int i = 0; i < arr.size(); i++) {
if (i > 0) System.out.print(" ");
System.out.print(arr.get(i));
}
System.out.println();
if (l <= r) {
System.out.println((l + r) >> 1);
} else {
System.out.println("NO");
}
}
}
试题4:堆排序
堆排序的思想实际上利用完全二叉树存储在数组中,通过调整完全二叉树成为大顶堆获得一个排序表的最大值进行排序的方法,大顶堆满足根节点比子树旳节点大。堆排序主要是通过大顶堆旳根元素与未完成排序旳最后一个元素进行交换,将交换后旳完全二叉树不满足大顶堆要求调整到满足满足要求,调整通过如下方法完成:
void heapAdjust(int[] R,int s,int t);其中,数组R中存储旳二叉树,只有以R[s]为根子树,其左右子树之间可能不满足大顶堆特征。
调整堆旳操作难点为根子树节点编号为i,则左子树节点编号为2*i,右子树节点编号为2*i+1;通过比较子树旳大小选择大旳子树进行调整,一直调整到根节点比子节点大,再将根节点旳值插入到最后调整旳节点。要完成堆排序,在调整旳基础上可以通过从堆底往堆顶进行调整获得初始堆,然后通过N-1次调整完成排序,控制流程为:
void heapSort(in