java 排序算法练习一组



/*
* 代码注释写的不是太完全 重点的地方在这里总结一下:
* 选择和冒泡比较简单 其中选择排序二层循环从一层的i值开始就可以 这样是从前向后排序
* 如果从后向前 就是说外层i值递减 这样j值从i值初始化就可以
* 选择排序的index要指向未排序部分的最大值 这样每一轮选择过后要将index指向一个为排序位置
*
* 冒泡排序可以采用一个flag位置标志是否出现交换 未出现则排序提前结束
*
* 归并排序的几个步骤;
*
* 开辟临时空间供排序使用 大小于待排序数组相同
* 指出待排序空间的下标 从0 到 最后一个 即 length - 1 因为是下标的最后一个
* 调用排序函数
* 判断递归结束条件: 数组中只有一个元素
* 递归调用函数 起始 = 起始 终点 = 中点
* 递归调用函数 起始 = 中点+1 终点 = 终点
* 合并两个有序数组
* 从低位向高位读取 选择较低的位置读
* while(i<=mid && j <= end ){
* if(arr[i]<arr[j])temp[point++] = arr[i]
* else temp[point++] = arr[j++]
* }
* 如果某一端未能读取结束 则复制全部内容到 temp数组中 注意边界下标
* mid i j point 均为下标
*
* 归并排序需要对递归有很好的理解
*
*
* 快速排序 核心在于理解划分
* 划分: 将数组中的第一个数字移动到排序后的位置
* 即:前面的数字均小于他 后面的均大于他
* 划分采用最小移动的办法 如何能划分是效率最高 ? 当然是尽量少的交换数据
* 原则是持有原来数据端不移动 兑端指针想中心靠拢
* 算法描述:
* 排序数组 起始位置 终点位置
* 递归终止条件: 起始位置>=终点位置
* int pivot = 划分函数
* 递归调用 起始=起始 终点=pivot-1
* 递归调用 起始=终点+1 终点 = 终点
*
* 划分实现:
* 指针left right
* 当left < right
* while(arr[left]<arr[right] && left < right)right--
* 交换arr[left] arr[right]
* whiel(arr[left]<arr[right] && left < right)left++
* 交换arr[left] arr[right]
*
* 返回left
*/
import java.util.Random;

/**
* 整形数组排序练习
*
* @author inky
*
*/
public class Sort {

/**
* toString() 方法 方便输出
*/
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i : arr) {
sb.append(i + "\t");
}
return sb.toString();

}

/**
* 需要排序的数组
*/
static int[] arr;

/**
* 构造器 构造一个含有l个整形数字的数组
* @param l 数组长度
*/
Sort(int l) {
arr = new int[l];
Random random = new Random();
for (int i = 0; i < l; i++) {
arr[i] = random.nextInt(100);
}
}

/**
* 归并排序
* 这个名字有点悲剧了 呵呵~
*/
void sort() {
int l = arr.length;
int[] temp = new int[l];
//调用归并排序函数
//0 到 l - 1 进行排序
mergeSort(arr, temp, 0, l - 1);
}

/**
* 归并排序 递归函数
*
* @param arr
* 排序数组
* @param arrCopy
* 排序空间
* @param start
* 起事位置
* @param end
* 结束位置
*/
private void mergeSort(int[] arr, int[] arrCopy, int start, int end) {
if (start < end) {

//计算中间点
int middle = (start + end) / 2;
mergeSort(arr, arrCopy, start, middle); //递归调用
mergeSort(arr, arrCopy, middle + 1, end);
// 合并已排序的两个数组算法
{
//i表示
int i = start, j = middle + 1, pointer = start;
for (; i <= middle && j <= end;) {
if (arr[i] < arr[j]) {
arrCopy[pointer++] = arr[i++];
} else {
arrCopy[pointer++] = arr[j++];
}
}
if (i > middle) {
System.arraycopy(arr, j, arrCopy, pointer, end - j + 1);
} else {
System.arraycopy(arr, i, arrCopy, pointer, middle - i + 1);
}
}

// 反Copy已排序的临时数组到源数组
System.arraycopy(arrCopy, start, arr, start, end - start + 1);
}
}

/**
* 选择排序
*/
private void selectSort() {
int maxIndex = 0;
int unsorted = arr.length;
for (int j = 0; j < unsorted; j++) {
maxIndex = j;
for (int i = j; i < unsorted; i++) {

if (arr[maxIndex] < arr[i]) {
maxIndex = i;
}
}
int temp = arr[j];
arr[j] = arr[maxIndex];
arr[maxIndex] = temp;

}
}

/**
* 选择排序 大头在后面
*/
private void selectSort2(){
int index = 0 ;
for(int i = arr.length-1 ; i >= 0 ; i--){
index = 0;
for(int j = 0 ; j <= i ; j++){
if(arr[index] < arr[j])index = j;
}
int temp = arr[i];
arr[i] = arr[index];
arr[index] = temp;
}
}

/**
* 冒泡排序
*/
private void upSort(){
for(int i = 0 ; i < arr.length ; i++){
boolean flag = false;
for(int j = 1 ; j < (arr.length - i) ; j++){
if(arr[j] < arr[j-1]){
flag = true;
int temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
}
}
if(!flag){
System.out.println(i);
return;
}
}
}


private void mymerger(){
int[] temp = new int[arr.length];
mergerSort2(arr,temp,0,arr.length-1);

}
private void mergerSort2(int[] arr2, int[] temp, int start, int end) {
if(start >= end) return;
int mid = (start + end)/2;
mergerSort2(arr2,temp,start,mid);
mergerSort2(arr2,temp,mid+1,end);
int i = start , j = mid +1, point = start;
while( i<=mid && j<= end ){
if(arr[i]<arr[j])temp[point++] = arr[j++];
else
temp[point++] = arr[i++];
}
if(i <= mid)System.arraycopy(arr, i, temp, point, mid- i +1);
else System.arraycopy(arr, j, temp, point, end - j +1);

System.arraycopy(temp, start, arr, start, end - start + 1);
}

private void myquitSort(){
quikSort(arr,0,arr.length-1);
}

private void quikSort(int[] data,int left,int right){
int pivot;
if(left >= right) return;
pivot = divid(data,left,right);
quikSort(data,left,pivot-1);
quikSort(data,pivot+1,right);

}
/**
* 划分 算法 将data 数组从left 到 right 划分
* 就是把left指向的数字移动到该数组从left到right中排序后应该到达的位置
* @param data 要排序数组
* @param left 排序起始位置
* @param right 排序结束位置
* @return 排序后数字的位置
*/
private int divid(int[] data,int left,int right){
while(left<right){
while(data[left]<=data[right] && left < right)right--;
int temp = arr[right];
data[right] = data[left];
data[left] = temp;
while(data[right]>=data[left] && left< right)left++;
temp = data[right];
data[right] = data[left];
data[left] = temp;
}
return left;
}
public static void main(String args[]) {
Sort g = new Sort(10);
System.out.println(g.toString());

//g.mymerger();
g.myquitSort();
//Arrays.sort(arr);
System.out.println(g.toString());
}
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值