您的位置:首页 > 其它

归并排序,插入排序,快速排序,冒泡排序,选择排序的思想

2017-02-26 21:28 639 查看
简单的梳理一下我对几种简单算法的思想的认识,代码我都是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]);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法
相关文章推荐