1、排序算法
1)快速排序
public void qsout(int[] arr,int l,int r){if(l >= r)return;int i,j,temp,t;i = l;j = r;temp = arr[l];while(i != j){while(arr[j] >= temp && i < j) j--;while(arr[i] <= temp && i < j) i++;if(i < j){t = arr[i];arr[i] = arr[j];arr[j] = t;}}arr[l] = arr[i];arr[i] = temp;qsort(arr,l,i-1);qsout(arr,i+1,r);
}
2)归并排序
- 正常归并排序
public void merge_sort(int[] arr,int l,int r,int[] temp){ //这里的temp数组是与原数组的长度一样的空数组if(l >= r)return;int mid = l + r >> 1;merge_sort(arr,l,mid,temp);merge_sort(arr,mid+1,r,temp);int i = l,j = mid+1,k = 0;while(i <= mid && j <= r){if(a[i] <= a[j]) temp[k++] = a[i++];else temp[k++] = a[j++];}while(i <= mid) temp[k++] = a[i++];while(j <= r) temp[k++] = a[j++];for(i = l,j=0;i <= r;i++,j++) a[i] = temp[j];
}
- 利用归并排序的特点求逆序对
//求逆序对public void merge_sort(int[] a,int l,int r,int[] temp){if(l >= r)return;int mid = l + r >> 1;merge_sort(a,l,mid,temp);merge_sort(a,mid+1,r,temp);int k = 0,i = l,j = mid + 1; //两个指针,和一个k用于储存结果while(i <= mid && j <= r){if(a[i] <= a[j])temp[k ++] = a[i ++];else {//体现分治思想//就是:当进入这个条件时,说明,右侧的 < 左侧,符合逆序的条件 因此,右侧的这个数,与左侧剩余数构成逆序数对//经验:分析分治时,直接用随机的数据来判断//eg: 1 2 3 5 6 78 9 与 4 67 879 889 999count += mid - i + 1;temp[k++] = a[j++];}}while(i <= mid)temp[k ++] = a[i ++];while(j <= r)temp[k ++] = a[j ++];for(i = l,j = 0;i <= r;i++,j++)a[i] = temp[j];}
2、查找算法
1)二分查找
- 简单二分查找
public int findIndex(int[] arr,int x){int l = 0,r = arr.length-1;while(l < r){int mid = l + r >> 1;if(arr[mid] >= x) r = mid;else l = mid + 1;}return arr[r] == x ? r : -1;
}
2)二分查找第一个或最后一个出现的目标值
- 查找目标值出现的第一个位置
//二分查找第一次出现的目标数字public static int FindF(int x,int[] a){if(a.length == 0)return -1; //数组为空int l = 0,r = a.length-1;while(l < r){int mid = l + r >> 1;if(a[mid] > x)r = mid - 1; //不包含左端点 因为将a[mid] = x 单独拉出来了,可以判断左端点(保证 r与l相等)else if(a[mid] == x)r = mid;elsel = mid + 1;}return a[l] == x ? l : -1; //如果数组只有两个元素,则 r 与 l 不同,此时 r 是正确的值,r 是 -1,因此用 l//如果数组元素大于两个元素,则 l == r}
- 查找目标值出现的最后一个位置
//二分查找最后一次出现的目标数字public static int FindL(int x,int[] a){if(a.length == 0)return -1; //数组为空int l = 0,r = a.length-1;while(l < r){int mid = l + r + 1 >> 1; //由于的当r=mid-1时,r与l的值不相等,因此在这里 + 1 保证l与r的值相等if(a[mid] > x)r = mid - 1; //不包含左端点 因为将a[mid] = x 单独拉出来了,可以判断左端点(保证 r与l相等)else if(a[mid] == x)l = mid;elsel = mid + 1;}return a[r] == x ? r : -1; //如果数组只有两个元素,则 r 与 l 不同,此时 r 是正确的值,l 是 -1,因此用 r//如果数组元素大于两个元素,则 l == r}
- 查找出现的峰值
public static int FindMax(int[] a){ //查的是其中一个最大值 1,2,1 是 2 的索引 ,1,2,3 是 3 的索引int l = 0, r = a.length-1;while(l < r){int mid = l + r >> 1;if(a[mid] > a[mid + 1] && mid != 0 && a[mid] > a[mid - 1] )return mid;else if (a[mid] > a[mid + 1]) {r = mid;} else if (mid != 0 && a[mid] > a[mid - 1]) {l = mid+1;} else {r = mid;}}if(a.length == 1)return 0;if(a[0] > a[1])return 0;return a.length-1;}