1. 快速排序
//快速排序
public class AlgorithmQuickSort {
public int partition(Integer[] list, int low, int high) {
int par = list[low]; //数组的第一个作为中轴
while (low < high) {
while (low < high && list[high] >= par) {
--high;
}
list[low] = list[high]; //比中轴小的记录移到低端
while (low < high && list[low] <= par) {
++low;
}
list[high] = list[low]; //比中轴大的记录移到高端
}
list[low] = par; //中轴记录到尾
return low; //返回中轴的位置
}
public void QSort(Integer[] list, int low, int high) {
if (low < high) {
int middle = partition(list, low, high); //将list数组进行一分为二
QSort(list, low, middle - 1); //对低字表进行递归排序
QSort(list, middle + 1, high); //对高字表进行递归排序
}
}
public void QuickSort(Integer[]list){
if(list.length > 0){
QSort(list,0,list.length-1);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Integer[] list={34,3,53,2,23,7,14,10};
new AlgorithmQuickSort().QuickSort(list);
for(int i=0;i<list.length;i++){
System.out.print(list[i]+" ");
}
System.out.println();
}
}
2. 找出数组中出现次数超过一半的数字(全部为正数)-快速排序的变形
package com.zhou.algorithm;
//找出数组中出现次数超过一半的数字(全部为正数)
public class AlgorithmQuickSortDeformation01 {
public int partition(Integer[] list, int low, int high) {
int par = list[low]; //数组的第一个作为中轴
while (low < high) {
while (low < high && list[high] >= par) {
--high;
}
list[low] = list[high]; //比中轴小的记录移到低端
while (low < high && list[low] <= par) {
++low;
}
list[high] = list[low]; //比中轴大的记录移到高端
}
list[low] = par; //中轴记录到尾
return low; //返回中轴的位置
}
public int numMoreThanHalf(Integer[] list){
if (list.length<1){
return -1;//全部为正数
}
int len = list.length ;
int middle = len>>1;
int low=0;
int high=len-1;
int index = partition(list,low,high);
while(index!=middle){
if(index>middle){
high=index-1;
index=partition(list,low,high);
}
else{
low=index+1;
index=partition(list,low,high);
}
}
int result = list[middle];
if(!isTrueMoreThanHalf(list,result))
result=-1;
return result;
}
public boolean isTrueMoreThanHalf(Integer[]list, int result){
boolean valid=true;
int times=0;
for (int i=0;i<list.length;++i){
if (result == list[i])
++times;
}
if(times <=(list.length>>1))
valid=false;
return valid;
}
public static void main(String[] args) {
Integer[] list={1,2,3,2,2,2,6,4,2,2};
System.out.println(new AlgorithmQuickSortDeformation01().numMoreThanHalf(list));
}
}
3. 找出最小的k个数
方法一:输入数组可以修改(快速排序的变形)
package com.zhou.algorithm;
import java.util.Arrays;
//找出最小的k个数
public class AlgorithmQuickSortDeformation02 {
public int partition(Integer[] list, int low, int high) {
int par = list[low]; //数组的第一个作为中轴
while (low < high) {
while (low < high && list[high] >= par) {
--high;
}
list[low] = list[high]; //比中轴小的记录移到低端
while (low < high && list[low] <= par) {
++low;
}
list[high] = list[low]; //比中轴大的记录移到高端
}
list[low] = par; //中轴记录到尾
return low; //返回中轴的位置
}
//基于函数Partition的第一种解法的平均时间复杂度是O(n)
public int[] getLeastNumbers(Integer[] input,int k){
if(input.length == 0 || k<= 0)
return null;
int[] output = new int[k];
int start = 0;
int end = input.length-1;
int index = partition(input,start,end);
while(index != k-1){
if(index > k-1){
end = index -1;
index = partition(input,start ,end);
}
else{
start = index+1;
index = partition(input,start ,end);
}
}
for(int i = 0;i<k;i++){
output[i] = input[i];
System.out.println(output[i]);
}
return output;
}
方法二:
//新建大顶堆
//第二种解法虽然要慢一点,但它有两个明显的优点。一是没有修改输入的数据。二是该算法适合海量数据的输入
public void buildMaxHeap(Integer[] arr,int lastIndex){
for(int i = (lastIndex-1)/2;i>=0;i--){
int k = i;
while(2*k+1 <= lastIndex){
int biggerIndex = 2*k+1;
if(biggerIndex <lastIndex){
if(arr[biggerIndex]< arr[biggerIndex+1])
biggerIndex++;
}
if(arr[k] < arr[biggerIndex]){ swap(arr,k,biggerIndex); k = biggerIndex; }
else break;
}
}
}
public static void swap(Integer[] arr,int i ,int j){
int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp;
}
public void heapSort(Integer[] arr){
for(int i = 0;i<arr.length-1;i++){
buildMaxHeap(arr,arr.length-i-1);
swap(arr,0,arr.length-i-1);
}
}
public void getLeastNumbers02(Integer[] arr,int k){
if(arr == null || k<0 || k>arr.length) return;
//根据输入数组前k个数最大堆
//从k+1个数开始与根节点比较
//大于根节点,舍去
//小于,取代根节点,重建最大堆
Integer[] kArray = Arrays.copyOfRange(arr, 0, k);
heapSort(kArray);
for(int i = k;i<arr.length;i++){
if(arr[i]<kArray[k-1]){ kArray[k-1] = arr[i]; heapSort(kArray); }
}
for(int i:kArray) System.out.print(i); }
测试:
Integer[] list={1,2,3,2,2,2,6,4,2,2};
new AlgorithmQuickSortDeformation02().getLeastNumbers02(list,5);
4. 折半查找
//查询成功返回该对象的下标序号,失败时返回-1
package com.zhou.algorithm;
//查询成功返回该对象的下标序号,失败时返回-1
public class BiSearch {
public int biSearchAlgorithm(int []list,int wordToSearch){
int low = 0;
int high=list.length-1;
if (high <0)
return -1;
while(low<=high){
int middle=(low+high)>>1;
if(list[middle]==wordToSearch)
return middle;
else if(list[middle]< wordToSearch)
low=middle+1;
else
high=middle-1;
}
return -1;
}
public int biSearchAlgorithm02(int []list,int low, int high,int wordToSearch){
if(low > high)
return -1;
int middle=(low+high)>>1;
if(list[middle]==wordToSearch)
return middle;
else if (list[middle] < wordToSearch)
return biSearchAlgorithm02(list,middle+1,high,wordToSearch);
else
return biSearchAlgorithm02(list,low,middle-1,wordToSearch);
}
public static void main(String[] args) {
int[] list={3,4,5,6,7,8,9};
System.out.println(new BiSearch().biSearchAlgorithm(list, 7));
System.out.println(new BiSearch().biSearchAlgorithm02(list,0,list.length-1, 7));
}
}