标签:
数据结构中常见的内部排序算法:
插入排序:直接插入排序、折半插入排序、希尔排序
交换排序:冒泡排序、快速排序
选择排序:简单选择排序、堆排序
归并排序、基数排序、计数排序
直接插入排序:
思想:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中,直到全部记录插入完成。
性能:时间复杂度:最好o(n):有序,最坏o(n^2):逆序,平均o(n^2);空间复杂度o(1);稳定
1 public int[] straightInsertSort(int array[]){ 2 int temp; 3 for(int i=1; i<array.length; i++){ //依次对1到array.length-1个元素进行处理 4 temp = array[i]; 5 for(int j=0; j<i; j++){ //已排好序的0到i-1个元素 6 if(temp < array[j]){ //插入位置j 7 for(int k=i-1;k>=j;k--){ //将j到i-1个元素向后移一个位置 8 array[k+1]=array[k]; //此时array[i]为已排好序的子数组中的最大值 9 } 10 array[j] = temp; //将第i个元素插入到位置j上 11 break; 12 } 13 } 14 } 15 return array; 16 }
折半插入排序:
思想:利用折半查找的方法找出元素的待插入位置,然后再统一移动待插入位置之后的所有元素,最后将待插入元素插入到相应位置。
性能:平均情况下,比较次数o(nlogn),移动次数o(n^2)
时间复杂度:最好o(n):有序,最坏o(n^2):逆序,平均o(n^2);空间复杂度o(1);稳定
1 public int[] binaryInsertSort(int[] array){ 2 int temp,low,high; 3 for(int i=1; i<array.length; i++){ 4 temp = array[i]; 5 //从已排好序的0到i-1个元素中,折半查找出元素的待插入位置 6 low = 0; 7 high = i-1; 8 while(low <= high){ 9 if(array[(low+high)/2] <= array[i]){ 10 low = (low+high)/2 + 1; 11 }else{ 12 high = (low+high)/2 - 1; 13 } 14 } 15 //移动待插入位置low到i-1间的所有元素 16 for(int j=i-1; j>=low; j-- ){ 17 array[j+1] = array[j]; 18 } 19 array[low] = temp; 20 } 21 return array; 22 }
希尔排序:
思想:将排序表分割成若干个形如L[i,i+d,i+2d,...,i+kd]的“特殊”子表,分别进行直接插入排序,当整个表中元素已呈现“基本有序”时,再对全体记录进行一次直接插入排序(d=1时)。
步长设置:d1=array.length/2;di=di/2,最后一个增量为1;
性能:时间复杂度:最坏o(n^2),平均o(n^1.3),空间复杂度o(1),不稳定
1 public int[] shellSort(int[] array){ 2 for(int d=array.length/2; d>=1; d=d/2){ //用步长值来控制循环次数 3 for(int i=d;i<array.length;i++){ 4 int temp = array[i]; 5 if(temp < array[i-d]){ //将array[i]插入到有序增量子表中 6 int j; 7 for(j=i-d;j>=0 && temp<array[j];j-=d){ 8 array[j+d]=array[j]; //记录后移,寻找插入位置 9 } 10 array[j+d] = temp; 11 } 12 } 13 } 14 return array; 15 }
冒泡排序:
思想:对于待排序表,从前往后两两比较相邻元素的值,若为逆序,则交换,直到序列比较完成。如此,每次冒泡即可得到当前待排表中的最大元素,并已放置在相应的位置。
性能:时间复杂度:最好o(n)有序,最坏o(n^2)逆序,平均o(n^2),空间复杂度o(1),稳定
1 public int[] bubbleSort(int[] array){ 2 boolean flag = false; //用来标记该序列是否已是有序 3 for(int i=0;i<array.length-1;i++){ //做n-1趟冒泡 4 for(int j=0;j<array.length-i-1;j++){ 5 if(array[j]>array[j+1]){ 6 int temp = array[j]; 7 array[j] = array[j+1]; 8 array[j+1] = temp; 9 flag = true; //有元素交换,则该序列初始状况不是有序的 10 } 11 } 12 if(flag == false){ //本趟遍历后没有发生交换,说明表已经有序 13 return array; 14 } 15 } 16 return array; 17 }
快速排序:
思想:基于分治的思想:在待排序表中任取一个元素pivot作为基准,通过一趟排序将待排序表划分为独立的两部分,使得一部分中所有元素小于pivot,另一部分中所有元素大于或等于pivot,则pivot放在了其最终位置上,这个过程称为一趟快速排序。而后递归地对两个子表重复上述过程,直到每部分内只有一个元素或空为止。
性能: 空间复杂度:需要递归工作栈:最坏o(n),平均o(logn)
时间复杂度:最坏:o(n^2)初始表基本有序或基本逆序,平均o(n*logn)
不稳定
1 public int[] quickSort(int[] array,int low,int high){ 2 if(low<high){ //递归跳出的条件 3 int mid= partition(array, low, high); //划分,得到枢值所在的下表 4 quickSort(array,low,mid-1); //依次对两个子表进行递归排序 5 quickSort(array,mid+1,high); 6 } 7 return array; 8 } 9 //快速排序的划分函数 10 public int partition(int[] array,int low, int high){ 11 int pivot = array[low]; //每次取数组中的第一个元素为基准 12 while(low < high){ //跳出循环的条件 13 while(low<high && array[high] > pivot){ //从右边开始找到第一个小于或等于pivot的值 14 high--; 15 } 16 while(low<high && array[low] < pivot){ //从左边开始找到第一个大于或等于pivot的值 17 low++; 18 } 19 int temp = array[low]; //交换 20 array[low] = array[high]; 21 array[high] = temp; 22 if(low<high && array[low] == pivot && array[high] == pivot){ //特殊情况 23 low++; 24 } 25 } 26 return low; 27 }
简单选择排序:
思想:
性能:时间复杂度:o(n^2),空间复杂度o(1),不稳定
public int[] simpleSelectSort(int[] array){ for(int i=0;i<array.length -1;i++){ //一共进行n-1趟 int min = i; //记录最小元素位置 for(int j=i+1;j<array.length;j++){ //在array[i,...,n-1]中选择最小的元素 if(array[j] < array[min]){ min = j; //更新最小元素的位置 } } int temp = array[i]; //将最小元素与第i个位置交换 array[i] = array[min]; array[min] = temp; } return array; }
归并排序:
思想:
性能:空间复杂度:o(n);时间复杂度:o(nlogn);稳定
1 public int[] mergeSort(int[] array,int low, int high){ 2 if(low < high){ //递归结束的条件 3 int mid = (low + high)/2; //二路归并排序,从中间划分两个子序列 4 mergeSort(array, low, mid); //对左侧子序列进行递归排序 5 mergeSort(array, mid+1, high); //对右侧子序列进行递归排序 6 merge(array,low,mid,high); //归并 7 } 8 return array; 9 } 10 11 //将前后相邻的两个有序表归并为一个有序表 12 private void merge(int[] array,int low, int mid, int high){ 13 int[] tempArray = new int[array.length]; //辅助数组tempArray 14 for(int i=low;i<=high;i++){ //将array数组中[low...high]复制到辅助数组tempArray中 15 tempArray[i] = array[i]; 16 } 17 int i,j,k; 18 for(i=low,j=mid+1,k=i;i<=mid && j<=high;k++){ 19 if(tempArray[i]>tempArray[j]){ //比较tempArray的左右两端中的元素 20 array[k] = tempArray[j++]; //将较小值复制到array中 21 }else{ 22 array[k] = tempArray[i++]; 23 } 24 } 25 while(i<=mid){ //若第一个表未检测完,复制 26 array[k++] = tempArray[i++]; 27 } 28 while(j<=high){ //若第二个表未检测完,复制 29 array[k++] = tempArray[j++]; 30 } 31 }
计数排序:
思想:
性能:
1 public int[] countSort(int[] array){ 2 int[] tempArray = new int[array.length]; 3 for(int i=0;i<array.length;i++){ 4 int count = 0; 5 for(int j=0;j<array.length;j++){ 6 if(array[i]>array[j]){ 7 count++; 8 } 9 } 10 tempArray[count] = array[i]; 11 } 12 return tempArray; 13 }
标签:
原文地址:http://www.cnblogs.com/CherishFX/p/4644996.html