20162328蔡文琛 实验三 查找与排序
20162328蔡文琛 大二 实验三 查找与排序
实验三(1)
这个实验要求我们对之前实现的查找类以及排序类进行测试,并实现排序类的正序和逆序的实现。
实验三(2)
实验要求对(1)中的代码进行重构,并使用bash编译并运行代码。
实验三(3)
实验要求实现:插值查找,斐波那契查找,数值查找,分块查找,哈希查找。
插值查找
public static int interpolationSearch(int[] a, int key) {
int low, mid, high;
low = 0;// 最小下标
high = a.length - 1;// 最大小标
while (low < high) {
mid = low + (high - low) * (key - a[low]) / (a[high] - a[low]);
if (key > a[mid]) {
low = mid + 1;
} else if (key < a[mid]) {
high = mid - 1;
} else {
return mid;
}
}
return -1;
}
斐波那契查找
public static int fibonacci_search(int[] a, int key, int n){
int low = 0, high = n-1;
int mid = 0;
int k = 0;
int[] F = new int[MAXSIZE];
fibonacci(F);
while( n > F[k]-1){ //确保fibonacci数列中的值可以表示整个待搜索数组中的位置
++k;
}
//将待搜索数组的规模扩展为F[k]-1;原来不足的部分用a[high]填充
int[] tempArray = new int[F[k]-1];
for (int i = n; i < F[k]-1; i++) {
tempArray[i] = a[high];
}
for (int i = 0; i < n; i++) {
tempArray[i] = a[i];
}
a = tempArray;
//对于规模为F[k]-1的数组
//黄金分割搜索, 每次将数组分为三部分,
//第一部分为从low(包含)开始的F[k-1]-1个元素,到mid-1(包含)为止;
//第二部分即为单个的a[mid],其中 mid = low+F[k-1]-1;
//第三部分为 从啊mid+1 (包含)开始的F[k-2]-1个元素,到high为止
//每次循环均遵循这一规律
while(low <= high){
mid = low + F[k-1] -1;
if (a[mid] > key) {
high = mid -1;
k = k - 1;
}else if (a[mid] < key){
low = mid + 1;
k = k - 2;
}else{
if (mid <= high) {
return mid;
}else {
return -1;
}
}
}
return -1;
}
哈希查找
public static int searchHash(int[] hash, int hashLength, int key) {
// 哈希函数
int hashAddress = key % hashLength;
// 指定hashAdrress对应值存在但不是关键值,则用开放寻址法解决
while (hash[hashAddress] != 0 && hash[hashAddress] != key) {
hashAddress = (++hashAddress) % hashLength;
}
// 查找到了开放单元,表示查找失败
if (hash[hashAddress] == 0)
return -1;
return hashAddress;
}
public static void insertHash(int[] hash, int hashLength, int data) {
// 哈希函数
int hashAddress = data % hashLength;
// 如果key存在,则说明已经被别人占用,此时必须解决冲突
while (hash[hashAddress] != 0) {
// 用开放寻址法找到
hashAddress = (++hashAddress) % hashLength;
}
// 将data存入字典中
hash[hashAddress] = data;
}
实验三(4)
实验要求实现希尔排序,堆排序,桶排序,二叉树排序。
桶排序
public static int[] countSort1(int[] arr){
if (arr == null || arr.length == 0) {
return null;
}
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
//找出数组中的最大最小值
for(int i = 0; i < arr.length; i++){
max = Math.max(max, arr[i]);
min = Math.min(min, arr[i]);
}
int help[] = new int[max];
//找出每个数字出现的次数
for(int i = 0; i < arr.length; i++){
int mapPos = arr[i] - min;
help[mapPos]++;
}
int index = 0;
for(int i = 0; i < help.length; i++){
while(help[i]-- > 0){
arr[index++] = i+min;
}
}
return arr;
希尔排序
public static void shellSortSmallToBig(int[] data) {
int j = 0;
int temp = 0;
for (int increment = data.length / 2; increment > 0; increment /= 2) {
System.out.println("increment:" + increment);
for (int i = increment; i < data.length; i++) {
// System.out.println("i:" + i);
temp = data[i];
for (j = i - increment; j >= 0; j -= increment) {
// System.out.println("j:" + j);
// System.out.println("temp:" + temp);
// System.out.println("data[" + j + "]:" + data[j]);
if (temp < data[j]) {
data[j + increment] = data[j];
} else {
break;
}
}
data[j + increment] = temp;
}
for (int i = 0; i < data.length; i++)
System.out.print(data[i] + " ");
}
}
堆排序
public static void adjustHeap(int[] a, int i, int len) {
int temp, j;
temp = a[i];
for (j = 2 * i; j < len; j *= 2) {// 沿关键字较大的孩子结点向下筛选
if (j < len && a[j] < a[j + 1])
++j; // j为关键字中较大记录的下标
if (temp >= a[j])
break;
a[i] = a[j];
i = j;
}
a[i] = temp;
}
public static void heapSort(int[] a) {
int i;
for (i = a.length / 2 - 1; i >= 0; i--) {// 构建一个大顶堆
adjustHeap(a, i, a.length - 1);
}
for (i = a.length - 1; i >= 0; i--) {// 将堆顶记录和当前未经排序子序列的最后一个记录交换
int temp = a[0];
a[0] = a[i];
a[i] = temp;
adjustHeap(a, 0, i - 1);// 将a中前i-1个记录重新调整为大顶堆
}
}
代码参考
http://blog.csdn.net/vmxplus/article/details/45845451
http://blog.csdn.net/xiaoping8411/article/details/7706376
http://blog.csdn.net/l294265421/article/details/45848677
http://blog.csdn.net/jianyuerensheng/article/details/51258460
https://www.cnblogs.com/developerY/p/3319618.html