Java程序员面试笔记_第八章_数据结构和算法_排序

package Java_Interview_Book;

public class Order {
	//选择排序,选出最小的与第一个位置交换。。。。。。
	public static void selectSort(int[] a) {
		int temp;//临时变量
		int flag;//标记位置
		int length = a.length;//数组长度
		
		for(int i=0;i<length;i++) {
			temp = a[i];
			flag = i;
			for(int j=i+1;j<length;j++) {
				if(a[j] < temp) {
					temp =a[j];//存储当前最小位置值
					flag = j;//标记当前最小位置
				}
			}
			if (flag != i) {//将第i小位置进行数值交换
				a[flag] = a[i];
				a[i] = temp;
			}
		}
	}
	//插入排序,每次加入的数和当前值比较,如果小和当前位置交换
	public static void insertSort(int [] a) {
		for (int i = 1; i < a.length; i++) {
			int temp = a[i];
			int j =i;
			if(a[j-1] >  temp) {
				while(j >= 1 && a[j-1] > temp) {
					a[j]=a[j-1];
					j--;
				}
			}
			a[j] = temp;
		}
	}
	//(单向)冒泡排序,相邻两两比较,假设是小到大输出
	public static void bubbleSort(int [] a ) {
		int temp;
		for (int i = 0; i < a.length; i++) {
			for (int j = i+1; j < a.length; j++) {
				if(a[i]>a[j]) {
					temp  = a[j];
					a[j] = a[i];
					a[i] = temp;
				}
			}
		}
	}
	 //两路归并算法,两个排好序的子序列合并为一个子序列
    public static void merge(int []a,int left,int mid,int right){
        int []tmp=new int[a.length];//辅助数组
        int p1=left,p2=mid+1,k=left;//p1、p2是检测指针,k是存放指针

        while(p1<=mid && p2<=right){
            if(a[p1]<=a[p2])
                tmp[k++]=a[p1++];
            else
                tmp[k++]=a[p2++];
        }

        while(p1<=mid) tmp[k++]=a[p1++];//如果第一个序列未检测完,直接将后面所有元素加到合并的序列中
        while(p2<=right) tmp[k++]=a[p2++];//同上

        //复制回原数组
        for (int i = left; i <=right; i++) 
            a[i]=tmp[i];
    }

    public static void mergeSort(int [] a,int start,int end){
        if(start<end){//当子序列中只有一个元素时结束递归
            int mid=(start+end)/2;//划分子序列
            mergeSort(a, start, mid);//对左侧子序列进行递归排序
            mergeSort(a, mid+1, end);//对右侧子序列进行递归排序
            merge(a, start, mid, end);//合并
        }
    }
    //快排,以某个数作为基数,划分成数组,左边子数组每个元素都小于右边数组

    public static void quickSort(int[] arr,int low,int high){
        int i,j,temp,t;
        if(low>high){
            return;
        }
        i=low;
        j=high;    
        temp = arr[low];//temp就是基准位
        while (i<j) {
            //先看右边,依次往左递减
            while (temp<=arr[j]&&i<j) {
                j--;
            }
            //再看左边,依次往右递增
            while (temp>=arr[i]&&i<j) {
                i++;
            }
            //如果满足条件则交换
            if (i<j) {
                t = arr[j];
                arr[j] = arr[i];
                arr[i] = t;
            }
 
        }
        //最后将基准为与i和j相等位置的数字交换
         arr[low] = arr[j];
         arr[j] = temp;
        //递归调用左半数组
        quickSort(arr, low, j-1);
        //递归调用右半数组
        quickSort(arr, j+1, high);
		
	}
    //希尔排序(缩小增量排序),分成几个子序列,对各个子序列之间进行直接插入排序
    //设定一个增量,先从array[0]开始以为增量的进行直接插入排序,直到数组末尾..z直到array[n]
    //然后取一个小于上一步增量的新的增量,直到增量小于1
    public static void shellSort(int[] a){
        int length = a.length;
        int temp,j ;

        for (int increPara = length/2; increPara > 0 ; increPara/=2) {
            for (int i = increPara; i < length; i++) {
                temp = a[i];
                j = i -increPara;
                while (j >= 0 && a[j] >= temp){
                    a[j+increPara]=a[j];
                    j-= increPara;
                }
                a[j+increPara] =temp;
            }
        }
    }
    //堆排序,大顶堆(r[i]>=r[2i] && r[i]>=r[2i+1])
    //构建堆,将堆顶元素和最后一个元素位置进行交换
    public static void maxHeapSort(int [] a) {
        int arrayLength=a.length;
        //循环建堆
        for(int i=0;i<arrayLength-1;i++){
            //建堆
            buildMaxHeap(a,arrayLength-1-i);
            //交换堆顶和最后一个元素
            swap(a,0,arrayLength-1-i);
            
        }
    }
    public static void buildMaxHeap(int[] data, int lastIndex){

        for(int i=(lastIndex-1)/2;i>=0;i--){ //从最后一个非叶子结点开始建堆
            int k=i;  //k保存正在判断的节点
            while(k*2+1<=lastIndex){ //如果当前k节点的子节点存在
                int biggerIndex=2*k+1; //k节点的左子节点的索引
                if(biggerIndex<lastIndex){ //如果biggerIndex小于lastIndex
                    if(data[biggerIndex]<data[biggerIndex+1]){   //若果右子节点的值较大
                        biggerIndex++;   //biggerIndex总是记录较大子节点的索引
                    }
                }
                //如果k节点的值小于其较大的子节点的值
                if(data[k]<data[biggerIndex]){
                    //交换他们
                    swap(data,k,biggerIndex);
                    //将biggerIndex赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右子节点的值
                    k=biggerIndex;
                }else{
                    break;
                }
            }
        }
    }
    public static  void swap(int [] a ,int i ,int j) {
		a[i] = a[i] ^ a[j];	
		a[j] = a[i] ^ a[j];	
		a[i] = a[i] ^ a[j];
    }
	public static void main(String [] args) {
		int a[] = {5,7,6,0,1,3,2};
//		selectSort(a);
//		insertSort(a);
//		bubbleSort(a);
//		mergeSort(a,0,a.length-1);
//		quickSort(a,0,a.length-1);
//		shellSort(a);
//		maxHeapSort(a);
		for (int i = 0; i < a.length; i++) {
			System.out.print(a[i]+"  ");
		}
		System.out.println("\n");
	}
}

一、二分查找

package com.basic.order;

/**
 * 又叫折半查找,要求待查找的序列有序。每次取中间位置的值与待查关键字比较,如果中间位置
 * 的值比待查关键字大,则在前半部分循环这个查找的过程,如果中间位置的值比待查关键字小,
 * 则在后半部分循环这个查找的过程。直到查找到了为止,否则序列中没有待查的关键字。
 * 
 * @author hexiaoli
 *
 */
public class BinarySearch {
	public static int biSearch(int[] array, int a) {
		int lo = 0;
		int hi = array.length - 1;
		int mid;
		while (lo <= hi) {
			mid = (lo + hi) >> 1;// 中间位置
			if (array[mid] == a) {
				return mid + 1;
			} else if (array[mid] < a) { // 向右查找
				lo = mid + 1;
			} else { // 向左查找
				hi = mid - 1;
			}
		}
		return -1;
	}

	public static void main(String[] args) {
		int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
		System.out.println(biSearch(array, 2));
	}

}

二、捅排序

package com.basic.order;

import java.util.ArrayList;
import java.util.Collections;

/**
 * 桶排序的基本思想是: 把数组 arr 划分为 n 个大小相同子区间(桶),每个子区间各自排序,最 后合并 。
 * 计数排序是桶排序的一种特殊情况,可以把计数排序当成每个桶里只有一个元素的情况。 
 * 1.找出待排序数组中的最大值 max、最小值 min 
 * 2.我们使用 动态数组 ArrayList 作为桶,桶里放的元素也用 ArrayList 存储。桶的数量为(maxmin)/arr.length+1 
 * 3.遍历数组:arr,计算每个元素 arr[i] 放的桶 4.每个桶各自排序
 * 
 * @author hexiaoli
 *
 */

public class BucketSort {
	public static ArrayList<ArrayList<Integer>> bucketSort(int[] arr) {
		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 bucketNum = (max - min) / arr.length + 1;
		ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum);
		for (int i = 0; i < bucketNum; i++) {
			bucketArr.add(new ArrayList<Integer>());
		}
		// 将每个元素放入桶
		for (int i = 0; i < arr.length; i++) {
			int num = (arr[i] - min) / (arr.length);
			bucketArr.get(num).add(arr[i]);
		}
		// 对每个桶进行排序
		for (int i = 0; i < bucketArr.size(); i++) {
			Collections.sort(bucketArr.get(i));
		}
		int index = 0;
		for (ArrayList<Integer> bucket : bucketArr) {
			for (Integer i : bucket) {
				arr[index++] = i;
			}
		}
		return bucketArr;
	}

	public static void main(String[] args) {
		int[] array = { 1, 4, 5, 9, 8, 7, 5, 3, 2 };
		bucketSort(array);
		for (int i = 0; i < array.length; i++) {
			System.out.print(array[i] + " ");
		}

	}

}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值