最近在复习数据结构,看到排序算法,以前一直模模糊糊懂,现在就把它弄明白了。以后用处多多。写了N次,终于把所有的算法都能独立写出来了,这些记录一下成果,如果能帮到你是我的荣幸。这里用的语言是Java
1.直接插入排序
//直接插入排序
public void insertSort(int[] array){
int n = array.length; //数组长度
for(int i = 1;i < n;i++){ //共执行n-1次插入
int temp = array[i]; //保存要插入的数据
int j = i - 1;
while(j >= 0 && array[j] > temp){ //比待插入数据大的依次向后移动
array[j + 1] = array[j];
j--;
}
array[j + 1] = temp; //插入数据
}
}
2.折半插入排序
//折半插入排序
public void binaryInsertSort(int[] array){
int n = array.length; //数组长度
for(int i = 1;i < n;i++){ //执行n-1次插入
int temp = array[i]; //保存待插入的值
int left = 0;
int right = i - 1;
while(left <= right){ //进行折半查找
int mid = (right + left) / 2;
if(array[mid] > temp){
right = mid - 1;
}else{
left = mid + 1;
}
}
for(int j = i - 1;j >= left;j--){ //将所有比待插入值大的向后移动
array[j + 1] = array[j];
}
array[left] = temp;
}
}
3.希尔排序
//希尔排序
public void shellSort(int[] array){
int n = array.length; //数组长度
int d = n / 2;
while(d >= 1){
for(int i = 0;i < d;i++){
for(int j = i + d;j < n;j+=d){
int temp = array[j];
int k = j - d;
while(k >= i && array[k] > temp){
array[k + d] = array[k];
k -= d;
}
array[k + d] = temp;
}
}
d = d / 2;
}
}
4.冒泡排序
//冒泡排序
public void bubbleSort(int[] array){
int n = array.length;
for(int i = 1;i < n;i++){
for(int j = 1;j < n - i + 1;j++){
if(array[j - 1] > array[j]){
int temp = array[j - 1];
array[j - 1] = array[j];
array[j] = temp;
}
}
}
}
5.快速排序
//快速排序
public int partition(int[] array,int left,int right){
int n = array.length;
int pivot = array[left];
while(left < right){
while(left < right && array[right] >= pivot){
right--;
}
array[left] = array[right];
while(left < right && array[left] < pivot){
left++;
}
array[right] = array[left];
}
array[left] = pivot;
return left;
}
public void quickSort(int[] array,int left,int right){
if(left < right){
int p = partition(array, left, right);
quickSort(array, left, p - 1);
quickSort(array, p + 1, right);
}
}
6.简单选择排序
//简单选择排序
public void selectSort(int[] array){
int n = array.length;
int min = 0;
for(int i = 1;i < n;i++){
min = i - 1;
for(int j = i;j < n;j++){
if(array[min] > array[j]){
min = j;
}
}
int temp = array[min];
array[min] = array[i - 1];
array[i - 1] = temp;
}
}
7.堆排序
//堆排序
public void siftDown(int[] array,int i,int n){
int l = 2*i + 1,r = 2*i + 2,max = i;
if(l < n && array[l] > array[max]){
max = l;
}
if(r < n && array[r] > array[max]){
max = r;
}
if(max != i){
int temp = array[max];
array[max] = array[i];
array[i] = temp;
siftDown(array,max,n);
}
}
public void buildHeap(int[] array){
int n = array.length;
int p = n / 2 - 1;
for(int i = p;i >= 0;i--){
siftDown(array,i,n);
}
}
public void heapSort(int[] array){
int n = array.length;
int temp = 0;
buildHeap(array);
for(int i = n - 1;i > 0;i--){
temp = array[0];
array[0] = array[i];
array[i] = temp;
siftDown(array,0,i);
}
}
8.归并排序
//归并排序
public void merge(int[] array,int left,int right,int mid){
int len1 = mid - left + 1,len2 = right - mid;
int[] array1 = new int[len1];
int[] array2 = new int[len2];
for(int i = 0;i < len1;i++){
array1[i] = array[i + left];
}
for(int i = 0;i < len2;i++){
array2[i] = array[mid + i + 1];
}
int i = 0,j = 0,k = 0;
for(k = left;k < right;k++){
if(i == len1 || j == len2){
break;
}
if(array1[i] <= array2[j]){
array[k] = array1[i++];
}else{
array[k] = array2[j++];
}
}
while(i < len1){
array[k++] = array1[i++];
}
while(j < len2){
array[k++] = array2[j++];
}
}
public void mergeSort(int[] array,int left,int right){
if(left < right){
int mid = (left + right) / 2;
mergeSort(array, left, mid);
mergeSort(array, mid + 1, right);
merge(array, left, right, mid);
}
}
最后是我用10w个随机数进行测试的时间:
----------------Start--------------------
直接插入排序-耗时:6034
折半插入排序-耗时:4115
希尔排序-耗时:31
冒泡排序-耗时:23347
快速排序-耗时:37
简单选择排序-耗时:5421
堆排序-耗时:33
归并排序-耗时:53
----------------END--------------------
可以看出堆排序,快速排序,和希尔排序的效果都很好,归并排序需要额外的空间,具体选择依情况而定!