排序目录
------1.冒泡排序
------2.选择排序
------3.直接插入排序
------4.希尔排序
------5.快速排序
------6.堆排序
------7.归并排序
一、冒泡排序法
public class Bubble{
public static void main(String[] args){
int a[] = {3,1,10,8,100,89,181,120};
bubbleSort(a);
//排序后输出
for(int i = 0;i < a.length;i++){
System.out.print(a[i]+" ");
}
}
public static void bubbleSort(int arr[]){
int len = arr.length;
//冒泡排序两层循环,第一次是表明排序的次数,应该是长度减1次
//第二次是表示进行比较的两个数,终止条件是长度减1减i
for(int i = 0;i < len-1;i++){
for(int j = 0;j < len-1-i;j++){
if(arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
}
思想:
每次取一个数,不断与其他数进行比较,交换;依次循环。
辅助空间o(1)
稳定性:稳定
时间复杂度 :最好:o(n), 最坏:o(n*n),平均:o(n*n)
备注:n小时较好
二、选择排序
public class selectSort{
public static void main(String[] args){
int a[] = {21,1,12,9};
System.out.println(" ");
selSort(a);
//排序后输出
for(int i = 0;i<a.length;i++){
System.out.print(a[i]+" ");
}
}
public static void selSort(int arr[]){
int i,j;
int len = arr.length;
for(i = 0;i < len;i++){
int min = arr[i];
int flag = i;//最小值的下标
for(j = i+1;j < len;j++){
if(arr[j] < min){//找出最小数
min = arr[j];
flag = j;
}
}
arr[flag] = arr[i];
arr[i] = min;
}
}
}
思想:
与冒泡的区别,只比较不交换。定义一个临时标量存储当前最小,并设置标记位。
辅助空间o(1)
稳定性:不稳定
时间复杂度:最好:o(n*n),最坏:o(n*n), 平均:o(n*n)
备注:n小时较好
三、直接插入排序
public class Insert {
public static void main(String[] args){
int a[] = {2,1,90,5};
//排序后进行输出打印
insertSort(a);
for (int i = 0;i < a.length;i++){
System.out.print(a[i]+" ");
}
}
public static void insertSort(int array[]){
for(int i = 1;i < array.length;i++){ //待插入元素,从1位置开始递增
int temp = array[i];
int j;
for (j = i-1;j >= 0;j--){
//将插入元素之前的元素与之比较,小则右移否则跳出, 注意这里是>=
if (array[j] > temp){
array[j+1] = array[j];
}
else
break; //跳出用break,因为前面都是有序的,一旦小于都小于
}
array[j+1] = temp;
}
}
}
思想:
两层循环,第一层表示的是待插入的元素,第二层表示的是待插入之前的元素;依次进行比较,右移,找到合适的位置放入待插入元素。
辅助空间o(1)
稳定性:稳定
时间复杂度 :最好:o(n),最坏:o(n*n), 平均:o(n*n)
备注:大部分已有序时较好
四、希尔排序,缩小增量排序
public class Test{
public static void main(String[] args){
int a[] = {2,12,1,0,9};
shellSort(a);
//排序后输出
for(int i = 0;i < a.length;i++){
System.out.print(a[i]+" ");
}
}
public static void shellSort(int arr[]){
int i,j;
int len = arr.length;
int temp;
int h; //步长因子
//第一层循环,步长因子的递减
for (h = len/2;h>0;h=h/2){
//第二层循环,就是按照直接插入排序的思路了
for(i = h;i<len;i++){
temp = arr[i];
//第三层循环,注意初始条件(可认为,直接插入是h=1的情况)
for(j = i-h;j>=0;j-=h){
if(arr[j]>temp){
arr[j+h] = arr[j];
}
else
break;
}
arr[j+h] = temp;
}
}
}
}
思想:
希尔排序建立在直接插入排序的基础上,直接插入可看作是希尔排序中步长因子为1 的特殊情况;
三层循环,第一层首先确定步长因子,后两层就是直接插入的思路,将增量1 改为步长h即可。
辅助空间o(1)
稳定性:不稳定
时间复杂度 : 最好:o(n),最坏:o(n*s),1
public class Quick{
public static void main(String[] args){
int a[]={49,38,65,97,76,13,27,4918,23,34,15,35,25,53,51};
quickSort(a,0,a.length-1);
//排序后输出
for(int i = 0;i < a.length;i++){
System.out.print(a[i]+" ");
}
}
public static void quickSort(int arr[],int low,int high){
if(low < high){//这的判决条件不能丢
int middle = getMiddle(arr,low,high);
quickSort (arr, low, middle - 1); //对低字表进行递归排序
quickSort (arr,middle + 1, high); //对高字表进行递归排序
}
}
public static int getMiddle(int[] arr,int low,int high){
int temp = arr[low];//将第一个数low作为中轴
while(low < high){
while(low < high && arr[high] >= temp){
high--;
}
arr[low] = arr[high];//比中轴小的记录移到低端
while(low < high && arr[low] <= temp){
low++;
}
arr[high] = arr[low];//比中轴大的记录移到高端
}
arr[low] = temp; //此时temp左边比他小,右边大
return low; //返回中轴的位置
}
}
思想:
快速排序是重点!!!
整体思路是定义low和high的标志位,每次选取low位置元素,通过getMiddle函数,将其移动到数组中间,保证其左边元素比它小,右边比它大。不断递归,实现排序。
辅助空间o(logn)
稳定性:不稳定
时间复杂度:最好:o(nlogn)、 最坏:o(n*n)、平均:o(nlogn)
备注:n大时较好
六、堆排序
public class Heap{
public static void main(String[] args){ inta[]={49,38,65,97,76,13,27,49,78,34,12,68,54,56,17,18,23,34,15,35,25,53,51};
heapSort(a);
for (int i = 0;i < a.length;i++)
{
System.out.print(a[i]+" ");
}
}
public static void heapSort(int arr[]){
int len = arr.length;
//循环建堆,这一层表示需要建几次堆
for(int i = 0;i < len-1;i++){
buildMaxHeap(arr,len-1-i);//建堆,最后一个元素
swap(arr,0,len-1-i);//交换堆顶和最后一个元素
}
}
private static void swap(int data[],int i,int j){
int temp = data[i];
data[i] = data[j];
data[j] = temp;
}
思想:
堆排序首先一个大for循环,表示需要建几次堆,其中调用建堆的函数,调用交换函数(交换第一个元素和最后一个元素);重点是关于建堆函数的实现,首先从最后一个节点的父亲开始,判断是否有孩子,是否有有孩子,并将最大值给了父亲。
辅助空间o(1)
稳定性:不稳定
时间复杂度:最好:o(nlogn),最坏:o(nlogn), 平均:o(nlogn)
备注:n大时较好
七、归并排序
public class Merge{
public static void main(String[] args){
int a[]={49,38,65,97,76,13,27,4918,23,34,15,35,25,53,51};
mergingSort(a);
for (int i = 0;i < a.length;i++)
{
System.out.print(a[i]+" ");
}
}
public static void mergingSort(int arr[]){
sort(arr,0,arr.length-1);
}
public static void sort(int data[],int left,int right){
if (left<right){
//找出中间索引
int center = (left+right)/2;
//对左边数组进行递归
sort(data,left,center);
//对右边数组进行递归
sort(data,center+1,right);
//合并
merge(data,left,center,right);
}
}
public static void merge(int data[],int left,int center,int right){
int tmpArr[] = new int[data.length];
int third=left;
int mid = center+1;
int tmp=left;
while(left<=center&&mid<=right){
if(data[left]<=data[mid]){
tmpArr[third++]=data[left++];
}
else{
tmpArr[third++]=data[mid++];
}
}
while(mid<=right){
tmpArr[third++]=data[mid++];
}
while(left<=center){
tmpArr[third++]=data[left++];
}
while(tmp<=right){
data[tmp]=tmpArr[tmp++];
}
}
}
思路:
归并排序分为两部分:首先是归,运用递归的思想,将数组分半在分半,直至每一组都成为一个元素;然后进行并的操作,创建一个新的数组(注意用到的额外的存储空间),将左右两个数组元素分别比较,按顺序放入新数组中,然后将剩余元素放到新数组,最后将新数组中元素复制到原来的数组中。
辅助空间o(n)
稳定性:稳定
时间复杂度:最好:o(nlogn),最坏:o(nlogn),平均:o(nlogn)
备注:n大时较好
简单的总结整理,希望对大家有所帮助如有错误欢迎大家批评指教!