简单的梳理一下我对几种简单算法的思想的认识,代码我都是copy的,网上有很多前辈的代码是不错的。我这里就不去再次实现了,虽然之前基本都写过。
一.归并排序:
先递归:
一个数组,可以看做是由两个子数组构成的,而这两个数组,也可以当成是由两个子数组构成的。。。。不断直到当这个数组中只有一个元素的时候(起始位置的下标和终止位置的下标相等)。
再合并:
先申请一块数组存放这两个数组的值,排序完成然后存回原数组对应的位置。
当两个数组中有其中一个已经全部放入temp数组的时候,就将另一个数组的直接放入最后就好。
时间复杂度:O(n log n)
归并排序是基于分治法的
分治法的一般的求解步骤为:
a 分解:将原问题分解为一系列子问题
b 解决:递归地求解各子问题
c 合并:将子问题的结果合并为原问题的解
注:代码是copy的
package com.collonn.algorithm.sort;
/**
* <pre>
* 经典归并排序
* </pre>
*/
public class MergeSort {
public void mergeSort(int[] s, int start, int end) {
if (start >= end) {
return;
}
int m = (start + end) / 2;
int start1 = start;
int end1 = m;
int start2 = m + 1;
int end2 = end;
this.mergeSort(s, start1, end1);
this.mergeSort(s, start2, end2);
this.merge(s, start1, end1, start2, end2);
}
// 合并两个有序数组为一个有序数组
private void merge(int[] s, int start1, int end1, int start2, int end2) {
System.out.printf("\n开始合并,合并范围,[%d,%d],[%d,%d]", start1, end1, start2, end2);
int start = start1;
// 临时数组
int[] t = new int[end2 - start1 + 1];
// 临时数组下标
int i = 0;
// 比较开始
while (start1 <= end1 && start2 <= end2) {
if (s[start1] < s[start2]) {
t[i] = s[start1];
start1++;
i++;
continue;
}
if (s[start1] > s[start2]) {
t[i] = s[start2];
start2++;
i++;
continue;
}
}
// 拷贝剩余元素
while (start1 <= end1) {
t[i] = s[start1];
start1++;
i++;
}
// 拷贝剩余元素
while (start2 <= end2) {
t[i] = s[start2];
start2++;
i++;
}
// 将已排好序的元素放回对应位置
for (i = 0; i < t.length; i++) {
s[start + i] = t[i];
}
// 打印数组
PrintArray(s);
}
// 打印数组
private static void PrintArray(int[] s) {
System.out.print("\n下标:");
for (int p = 0; p < s.length; p++) {
System.out.printf("%2d,", p);
}
System.out.print("\n值值:");
for (Integer m : s) {
System.out.printf("%2d,", m);
}
System.out.print("\n-----------------------------");
}
public static void main(String[] args) {
// int[] s = new int[] { 99, 88, 5, 99, 7, 9, 3, 8, 10, 90, 56, 83, 39, 22 };
int[] s = new int[] { 9, 2, 3, 7, 6, 5, 8, };
// 打印数组
PrintArray(s);
MergeSort mergeSort = new MergeSort();
mergeSort.mergeSort(s, 0, s.length - 1);
// 打印数组
PrintArray(s);
}
}
二.插入排序:
插入排序是这样的:一个数组a,从第一个元素开始,认为其是一个子数组b(其实可以不存在),那么子数组b是有序的。开始遍历整个数组b,将从第二个数开始的元素,插入到数组b中的相应的位置。
时间复杂度 O(n2)
package com.njue;
public class insertSort {
public insertSort(){
inta[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};
int temp=0;
for(int i=1;i<a.length;i++){
int j=i-1;
temp=a[i];
for(;j>=0&&temp<a[j];j--){
a[j+1]=a[j]; //将大于temp的值整体后移一个单位
}
a[j+1]=temp;
}
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
}
三.快速排序
快排算是用的很多的一种排序了,其的思想是,有一个准线temp(一般默认第一个),从左右两边同时开始,左边找到比temp大于等于的第一个元素,右边找到比temp小于等于的第一个元素,两两交换。直到两个下标元素相碰为止,然后开始递归。将两个子数组递归下去就ok。
public class quickSort {
int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};
public quickSort(){
quick(a);
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
public int getMiddle(int[] list, int low, int high) {
int tmp = list[low]; //数组的第一个作为中轴
while (low < high) {
while (low < high && list[high] >= tmp) {
high--;
}
list[low] = list[high]; //比中轴小的记录移到低端
while (low < high && list[low] <= tmp) {
low++;
}
list[high] = list[low]; //比中轴大的记录移到高端
}
list[low] = tmp; //中轴记录到尾
return low; //返回中轴的位置
}
public void _quickSort(int[] list, int low, int high) {
if (low < high) {
int middle = getMiddle(list, low, high); //将list数组进行一分为二
_quickSort(list, low, middle - 1); //对低字表进行递归排序
_quickSort(list, middle + 1, high); //对高字表进行递归排序
}
}
public void quick(int[] a2) {
if (a2.length > 0) { //查看数组是否为空
_quickSort(a2, 0, a2.length - 1);
}
}
}
四.冒泡排序:
很经典的排序了。从第一个元素i开始,之后的元素两两比较,大的浮在后边,那么一次交换之后,最大的数就在最右了。第二次,仍然从第一个数开始,到倒数第二个数停止,两两比较,大的浮在最右边,那么次大数就在倒数第二个位置了。。。。
时间复杂度:O(n2)
public class bubbleSort {
public bubbleSort(){
int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};
int temp=0;
for(int i=0;i<a.length-1;i++){
for(int j=0;j<a.length-1-i;j++){
if(a[j]>a[j+1]){
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
}
五.选择排序:
在一个数组中,找出最小的元素,然后和第一个元素交换。然后再选出次小的元素,和第二个元素交换。。。。。。
时间复杂度:O(n2)
public class selectSort {
public selectSort(){
int a[]={1,54,6,3,78,34,12,45};
int position=0;
for(int i=0;i<a.length;i++){
int j=i+1;
position=i;
int temp=a[i];
for(;j<a.length;j++){
if(a[j]<temp){
temp=a[j];
position=j;
}
}
a[position]=a[i];
a[i]=temp;
}
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
}