程序员必须掌握的排序算法
在这里我只放代码作为参考,默认大家对各大排序算法的思路都是清楚的,若不清楚可参考:http://www.imooc.com/article/8633
//交换两个数
public static void swap(int[] arr,int i,int j){
arr[i]=arr[i]^arr[j];
arr[j]=arr[i]^arr[j];
arr[i]=arr[i]^arr[j];
arr[i]=arr[i]^arr[j];
arr[j]=arr[i]^arr[j];
arr[i]=arr[i]^arr[j];
}
//冒泡排序
public static void bubbleSort(int[] arr){
if (arr == null || arr.length == 0) {
return;
}
for (int i=0;i<arr.length;i++){
for (int j=0;j<arr.length-i-1;j++){
if (arr[j]>arr[j+1])
swap(arr,j,j+1);
}
}
public static void bubbleSort(int[] arr){
if (arr == null || arr.length == 0) {
return;
}
for (int i=0;i<arr.length;i++){
for (int j=0;j<arr.length-i-1;j++){
if (arr[j]>arr[j+1])
swap(arr,j,j+1);
}
}
}
//选择排序
public static void selectSort(int[] arr){
if (arr == null || arr.length == 0) {
return;
}
for (int i=0;i<arr.length-1;i++){
int index=i;
for (int j=i+1;j<arr.length;j++){
if (arr[j]<arr[index])
index=j;
}
if (index!=i)
swap(arr,i,index);
}
}
//插入排序
public static void insertSort(int[] arr){
if (arr == null || arr.length == 0) {
return;
}
for (int i=0;i<arr.length;i++){
int tmp=arr[i],j;
for (j = i-1 ; j >= 0 && arr[j] > tmp ; j--){
arr[j+1]=arr[j];
}
arr[j+1]=tmp;
}
}
//快速排序:礼尚往来
public static void quickSort(int[] arr,int low,int high){
if (arr == null || arr.length == 0) {
return;
}
int start=low;
int end=high;
int key=arr[low];
while (end > start) {
//从后往前比较
while (end > start && arr[end] >= key)
end--;
if (arr[end] < key)
swap(arr,start,end);
//从前往后比较
while (end > start && arr[start] <= key)
start++;
if (arr[start] > key)
swap(arr,start,end);
}
//递归
if (start > low)
quickSort(arr,low,start-1);
if (end < high)
quickSort(arr,end+1,high);
}
//堆排序
if (arr == null || arr.length == 0) {
return;
}
for (int i=0;i<arr.length-1;i++){
int index=i;
for (int j=i+1;j<arr.length;j++){
if (arr[j]<arr[index])
index=j;
}
if (index!=i)
swap(arr,i,index);
}
}
//插入排序
public static void insertSort(int[] arr){
if (arr == null || arr.length == 0) {
return;
}
for (int i=0;i<arr.length;i++){
int tmp=arr[i],j;
for (j = i-1 ; j >= 0 && arr[j] > tmp ; j--){
arr[j+1]=arr[j];
}
arr[j+1]=tmp;
}
}
//快速排序:礼尚往来
public static void quickSort(int[] arr,int low,int high){
if (arr == null || arr.length == 0) {
return;
}
int start=low;
int end=high;
int key=arr[low];
while (end > start) {
//从后往前比较
while (end > start && arr[end] >= key)
end--;
if (arr[end] < key)
swap(arr,start,end);
//从前往后比较
while (end > start && arr[start] <= key)
start++;
if (arr[start] > key)
swap(arr,start,end);
}
//递归
if (start > low)
quickSort(arr,low,start-1);
if (end < high)
quickSort(arr,end+1,high);
}
//堆排序
//构建大根堆:将arr看成完全二叉树的顺序存储结构
private static int[] buildMaxHeap(int[] arr){
//从最后一个节点arr.length-1的父节点(arr.length-1-1)/2开始,开始知道根节点,反复调整堆
for(int i=(arr.length-2)/2;i>=0;i--){
adjustDownToUp(arr,i,arr.length);
}
return arr;
}
//将元素arr[k]自下往上逐步调整树形结构
private static void adjustDownToUp(int[] arr,int k,int length){
int tmp=arr[k];
for (int i=2*k+1;i<=length-1;i=2*i+1){ //i为初始化为节点k的左孩子,沿节点较大的子节点向下调整
if (i<length-1 && arr[i]<arr[i+1]) //取节点较大的子节点的下标
i++; //如果节点的右孩子>左孩子,则取右孩子节点的下标
if (tmp>=arr[i]) //根节点 >=左右子女中关键字较大者,调整结束
break;
else { //根节点 <左右子女中关键字较大者
arr[k]=arr[i]; //将左右子结点中较大值array[i]调整到双亲节点上
k=i; //【关键】修改k值,以便继续向下调整
}
}
arr[k]=tmp; //被调整的结点的值放人最终位置
}
//堆排序
public static void heapSort(int[] arr){
if (arr == null || arr.length == 0) {
return;
}
arr=buildMaxHeap(arr); //初始建堆,array[0]为第一趟值最大的元素
for (int i=arr.length-1;i>=1;i--){
swap(arr,0,i);
adjustDownToUp(arr,0,i);
}
}
//希尔排序
public static void shellSort(int arr[]){
if (arr == null || arr.length == 0) {
return;
}
//设置增量
int increment=arr.length/2;
while (increment >= 1) {
for (int i=0;i<arr.length;i++){
//进行插入排序
for (int j=i;j<arr.length-increment;j+=increment){
if (arr[j]>arr[j+increment])
swap(arr,j,j+increment);
}
}
//设置新的增量
increment/=2;
}
}
//归并排序
public static void mergeSort(int[] arr,int low,int high){
int mid=(low+high)>>1;
if (low < high) {
//左边
mergeSort(arr,low,mid);
//右边
mergeSort(arr,mid+1,high);
//左右归并
merge(arr,low,mid,high);
}
}
public static void merge(int[] arr,int low,int mid,int high){
int[] tmpArr=new int[high-low+1];
int i=low; //左指针
int j=mid+1; //右指针
int k=0;
//把较小的数先移到新数组中
while (i <= mid && j <= high) {
if (arr[i]<arr[j])
tmpArr[k++]=arr[i++];
else
tmpArr[k++]=arr[j++];
}
//把左边剩余的数移入数组
while (i <= mid)
tmpArr[k++]=arr[i++];
//把右边剩余的数移入数组
while (j <= high)
tmpArr[k++]=arr[j++];
//把新数组中的数覆盖到原数组
for (int k2=0;k2<tmpArr.length;k2++)
arr[k2+low]=tmpArr[k2];
for(int i=(arr.length-2)/2;i>=0;i--){
adjustDownToUp(arr,i,arr.length);
}
return arr;
}
//将元素arr[k]自下往上逐步调整树形结构
private static void adjustDownToUp(int[] arr,int k,int length){
int tmp=arr[k];
for (int i=2*k+1;i<=length-1;i=2*i+1){ //i为初始化为节点k的左孩子,沿节点较大的子节点向下调整
if (i<length-1 && arr[i]<arr[i+1]) //取节点较大的子节点的下标
i++; //如果节点的右孩子>左孩子,则取右孩子节点的下标
if (tmp>=arr[i]) //根节点 >=左右子女中关键字较大者,调整结束
break;
else { //根节点 <左右子女中关键字较大者
arr[k]=arr[i]; //将左右子结点中较大值array[i]调整到双亲节点上
k=i; //【关键】修改k值,以便继续向下调整
}
}
arr[k]=tmp; //被调整的结点的值放人最终位置
}
//堆排序
public static void heapSort(int[] arr){
if (arr == null || arr.length == 0) {
return;
}
arr=buildMaxHeap(arr); //初始建堆,array[0]为第一趟值最大的元素
for (int i=arr.length-1;i>=1;i--){
swap(arr,0,i);
adjustDownToUp(arr,0,i);
}
}
//希尔排序
public static void shellSort(int arr[]){
if (arr == null || arr.length == 0) {
return;
}
//设置增量
int increment=arr.length/2;
while (increment >= 1) {
for (int i=0;i<arr.length;i++){
//进行插入排序
for (int j=i;j<arr.length-increment;j+=increment){
if (arr[j]>arr[j+increment])
swap(arr,j,j+increment);
}
}
//设置新的增量
increment/=2;
}
}
//归并排序
public static void mergeSort(int[] arr,int low,int high){
int mid=(low+high)>>1;
if (low < high) {
//左边
mergeSort(arr,low,mid);
//右边
mergeSort(arr,mid+1,high);
//左右归并
merge(arr,low,mid,high);
}
}
public static void merge(int[] arr,int low,int mid,int high){
int[] tmpArr=new int[high-low+1];
int i=low; //左指针
int j=mid+1; //右指针
int k=0;
//把较小的数先移到新数组中
while (i <= mid && j <= high) {
if (arr[i]<arr[j])
tmpArr[k++]=arr[i++];
else
tmpArr[k++]=arr[j++];
}
//把左边剩余的数移入数组
while (i <= mid)
tmpArr[k++]=arr[i++];
//把右边剩余的数移入数组
while (j <= high)
tmpArr[k++]=arr[j++];
//把新数组中的数覆盖到原数组
for (int k2=0;k2<tmpArr.length;k2++)
arr[k2+low]=tmpArr[k2];
}