经典算法:二分查找、插入排序、选择排序、冒泡排序
2015-01-11 11:43
507 查看
这4个算法真的堪称经典,里面包含了许多数学思想,面试的时候也经常被问到。排序的话面试官一般会问你最熟悉的一种排序深入点的会问这几种排序的依据,二分查找更为重要,比起排序查找算是比较简单的了。下面我自己整理了一些东西和大家分享,说来惭愧以前就只会冒泡排序这么一种,废话不说了下面开始了。
1.最容易理解的排序【冒泡排序】
冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。
它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端,故名。
由于冒泡排序简洁的特点,它通常被用来对于计算机程序设计入门的学生介绍算法的概念。
简单的说就是一次一次的交换数据,这样数据就会“浮”上来
[java] view
plaincopy
//冒泡排序
for(int i=1;i<array.length;i++){
for(int j=i+1;j<array.length;j++){
int temp=0;
//如果后面一个数小于前面的就交换
if(array[i]>array[j]){
temp=array[j];
array[j]=array[i];
array[i]=temp;
}
}
}
这段代码相信大家都能看懂,个人觉得如果面试的时候有这样的冒泡排序但是答不上来的话,真的够丢脸的
2.效率稍高一些的排序【选择排序】
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
选择排序的主要优点与数据移动有关。如果某个元素位于正确的最终位置上,则它不会被移动。选择排序每次交换一对元素,它们当中至少有一个将被移到其最终位置上,因此对n个元素的表进行排序总共进行至多n-1次交换。在所有的完全依靠交换去移动元素的排序方法中,选择排序属于非常好的一种。
简要的说就是先取出或假设一个最小或最大的数,之后在剩下的数里挑选一个最小或最大的,再和我们认为的最小或最大的数比较。满足条件就交换位置
[java] view
plaincopy
int temp=0;
//这里开始逐个假设作为最小的数(这里是从大到小排序)
for(int i=0;i<array.length-1;i++){
//假设一个最小的数
int minVal=array[i];
//最小数的下标
int minIndex=i;
//接下来和后面的数进行比较如果有更小的则前面的假设不成立
for(int j=minIndex+1;j<array.length;j++){
//假设不成立,则修改最小的数和下标
if(array[j]<minVal){
minVal=array[j];
minIndex=j;
}
}
//把我们找到的最小的数和前面的交换
temp=array[i];
array[i]=array[minIndex];
array[minIndex]=temp;
}
这个程序比起前面的冒泡排序效率稍微高了一些
3.三种排序效率最高的一种【插入排序】
插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
下面是插入排序的代码片段
[java] view
plaincopy
for(int i=0;i<array.length;i++){
int insertVal=array[i];
int insertIndex=i-1;
//移动位置直到找到合适的位置
while(insertIndex>=0&&insertVal<array[insertIndex]){
array[insertIndex+1]=array[insertIndex];
insertIndex--;
}
if(i!=insertIndex+1){
array[insertIndex+1]=insertVal;
}
}
4 二分查找算法
要求:数字有序排列
下面是java中的递归实现
[java] view
plaincopy
public class Search{
public void HalfSearch(int[] a, int b) {
Arrays.sort(a);//系统排序
int low = 0;
int high = a.length - 1;
int mid = (low + high) / 2;
while ((mid != low) && (mid != high)) {
if (b <= a[mid]) {
high = mid;
mid = (low + high) / 2;
} else {
low = mid;
mid = (low + high) / 2;
}
}
if ((b == a[low]) || (b == a[high])) {
System.out.println(b + "在数组a中");
} else {
System.out.println(b + "不在数组a中");
}
}
public static void main(String[] args){
Search s=new Search();
int[] a={11,41,17,18,14,16,20,45};
s.HalfSearch(a,20);
}
}
快速排序
public class QuickSort {
public int partition(int[] a, int i, int j) {//分割排序
int key = a[i];
while(i < j) {
while(i < j && a[j] >= key) //找出第一个比key小,并记下j值
j--;
a[i] = a[j];//将a[j]移至a[i]处
while(i < j && a[i] <= key)//找出第一个比key大,并记下i值
i++;
a[j] = a[i];//将a[i]移至a[j]处
}
a[i] = key;//此时完成一趟排序
return i;//此时i=j,记下i的值
}
public void sort(int[] a, int i, int j) {//递归调用分割
if(i < j) {
int n = partition(a,i,j);//排一次序列,并获取关键值的位置
sort(a,i,n-1);//左递归
sort(a,n+1,j);//右递归
}
}
public static void main(String[] args) {
int[] a = {49,38,65,97,76,13,27};
new QuickSort().sort(a, 0, 6);
for(int item : a) {
System.out.println(item);
}
}
}
1.最容易理解的排序【冒泡排序】
冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。
它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端,故名。
由于冒泡排序简洁的特点,它通常被用来对于计算机程序设计入门的学生介绍算法的概念。
简单的说就是一次一次的交换数据,这样数据就会“浮”上来
[java] view
plaincopy
//冒泡排序
for(int i=1;i<array.length;i++){
for(int j=i+1;j<array.length;j++){
int temp=0;
//如果后面一个数小于前面的就交换
if(array[i]>array[j]){
temp=array[j];
array[j]=array[i];
array[i]=temp;
}
}
}
这段代码相信大家都能看懂,个人觉得如果面试的时候有这样的冒泡排序但是答不上来的话,真的够丢脸的
2.效率稍高一些的排序【选择排序】
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
选择排序的主要优点与数据移动有关。如果某个元素位于正确的最终位置上,则它不会被移动。选择排序每次交换一对元素,它们当中至少有一个将被移到其最终位置上,因此对n个元素的表进行排序总共进行至多n-1次交换。在所有的完全依靠交换去移动元素的排序方法中,选择排序属于非常好的一种。
简要的说就是先取出或假设一个最小或最大的数,之后在剩下的数里挑选一个最小或最大的,再和我们认为的最小或最大的数比较。满足条件就交换位置
[java] view
plaincopy
int temp=0;
//这里开始逐个假设作为最小的数(这里是从大到小排序)
for(int i=0;i<array.length-1;i++){
//假设一个最小的数
int minVal=array[i];
//最小数的下标
int minIndex=i;
//接下来和后面的数进行比较如果有更小的则前面的假设不成立
for(int j=minIndex+1;j<array.length;j++){
//假设不成立,则修改最小的数和下标
if(array[j]<minVal){
minVal=array[j];
minIndex=j;
}
}
//把我们找到的最小的数和前面的交换
temp=array[i];
array[i]=array[minIndex];
array[minIndex]=temp;
}
这个程序比起前面的冒泡排序效率稍微高了一些
3.三种排序效率最高的一种【插入排序】
插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
下面是插入排序的代码片段
[java] view
plaincopy
for(int i=0;i<array.length;i++){
int insertVal=array[i];
int insertIndex=i-1;
//移动位置直到找到合适的位置
while(insertIndex>=0&&insertVal<array[insertIndex]){
array[insertIndex+1]=array[insertIndex];
insertIndex--;
}
if(i!=insertIndex+1){
array[insertIndex+1]=insertVal;
}
}
4 二分查找算法
要求:数字有序排列
下面是java中的递归实现
[java] view
plaincopy
public class Search{
public void HalfSearch(int[] a, int b) {
Arrays.sort(a);//系统排序
int low = 0;
int high = a.length - 1;
int mid = (low + high) / 2;
while ((mid != low) && (mid != high)) {
if (b <= a[mid]) {
high = mid;
mid = (low + high) / 2;
} else {
low = mid;
mid = (low + high) / 2;
}
}
if ((b == a[low]) || (b == a[high])) {
System.out.println(b + "在数组a中");
} else {
System.out.println(b + "不在数组a中");
}
}
public static void main(String[] args){
Search s=new Search();
int[] a={11,41,17,18,14,16,20,45};
s.HalfSearch(a,20);
}
}
快速排序
public class QuickSort {
public int partition(int[] a, int i, int j) {//分割排序
int key = a[i];
while(i < j) {
while(i < j && a[j] >= key) //找出第一个比key小,并记下j值
j--;
a[i] = a[j];//将a[j]移至a[i]处
while(i < j && a[i] <= key)//找出第一个比key大,并记下i值
i++;
a[j] = a[i];//将a[i]移至a[j]处
}
a[i] = key;//此时完成一趟排序
return i;//此时i=j,记下i的值
}
public void sort(int[] a, int i, int j) {//递归调用分割
if(i < j) {
int n = partition(a,i,j);//排一次序列,并获取关键值的位置
sort(a,i,n-1);//左递归
sort(a,n+1,j);//右递归
}
}
public static void main(String[] args) {
int[] a = {49,38,65,97,76,13,27};
new QuickSort().sort(a, 0, 6);
for(int item : a) {
System.out.println(item);
}
}
}
相关文章推荐
- 经典算法:二分查找、插入排序、选择排序、冒泡排序
- 经典算法:二分查找、插入排序、选择排序、冒泡排序
- 经典算法:二分查找、插入排序、选择排序、冒泡排序
- 经典算法-选择排序,冒泡排序,二分查找
- Java选择排序、冒泡排序、直接插入排序与二分查找
- 算法---冒泡排序,快速排序,二分查找(折半查找),选择排序,插入排序
- 数组 获取最值(最大值 最小值)选择排序 冒泡排序 快速排序 半查找(二分查找) 十进制转其他进制法
- C/C++经典算法精华整理(2)-二分查找和插入查找
- 常见排序集合(冒泡排序,选择排序,直接插入排序,二分插入排序,快速排序,希尔排序,归并排序)
- 冒泡排序,简单插入排序,快速排序,二分查找的JAVA实现
- C语言实现直接插入排序,冒泡排序以及二分查找(巩固理解记忆)
- 黑马程序员——冒泡排序、选择排序、二分查找的实例运用分析
- C 语言 排序算法,冒泡排序,选择排序,插入排序,二分查找
- 几种常用的排序算法:插入排序、冒泡排序、选择排序的算法及C++实现
- 插入,冒泡,选择,快速排序,二分查找(Java版)
- 插入,冒泡,选择,快速排序,二分查找(Java版)
- 插入,冒泡,选择,快速排序,二分查找
- 插入排序的递归实现和二分查找递归实现,算法导论2.3-4和2.3-5
- 插入,冒泡,选择,快速排序,二分查找
- 关于数组的几个小题目-冒泡排序、二分查找、直接选择排序、反转数组