常用的排序算法集锦

来源:互联网 发布:php过滤敏感词的例子 编辑:程序博客网 时间:2024/06/06 04:31

前言


昨晚参加了今日头条的笔试,大部分都是算法题,而算法恰恰就是我的弱项,所以被虐得不轻。于是为了提升自己的算法能力,我在博客整理一些常用的算法及原理,巩固一下基础知识,顺便为秋招做准备。先讲一下最基础的排序算法吧(昨晚就是有一道关于排序的,我居然忘了排序算法的实现,以此为戒)


插入排序


1.直接插入排序(稳定)

思路:在插入第i个记录时,R1、R2、......、Ri-1已经排好序,这时将Ri的关键字ki依次与关键字ki-1、ki-2等进行比较,从而找到应该插入的位置并将Ri插入,插入位置及其后的记录依次向后移动。


java实现:

public class Main{public static void main(String[] args){//待排序的数组int[] numbers = {3,56,12,456,5,23,16,15,56,456};int i,j,temp;for(i = 1;i < numbers.length;i++){temp = numbers[i];j = i - 1;//将当前数与排好序的序列逐个比较,寻找插入位置while(j >= 0 && numbers[j] > temp){//将大于当前数的元素后移numbers[j+1] = numbers[j];j--;}numbers[j+1] = temp;}//输出排序后的数组for(int number : numbers){System.out.print(number + " ");}}}

2.折半插入排序(稳定)

思路:折半插入排序是对直接插入排序的完善。直接插入排序将无序区中开头元素R[i](1 <= i <= n-1)插入到有序区R[0..i-1]中,此时可以采用折半查找方法先在R[0..i-1]中找到插入位置,再通过移动元素进行插入。这样的插入排序称为折半插入排序或二分插入排序。


Java实现:

public class Main{public static void main(String[] args){//待排序的数组int[] numbers = {3,56,12,456,5,23,16,15,56,456};int i,j,temp,low,high,mid;for(i = 1;i < numbers.length;i++){temp = numbers[i];j = i - 1;low = 0;high = j;//通过折半查找插入的位置while(low <= high){mid = (low + high)/2;if(numbers[mid] < temp)low = mid+1;elsehigh = mid-1;}//元素后移for(j = i - 1;j >= high + 1;j--){numbers[j+1] = numbers[j];}numbers[high + 1] = temp;}//输出排序后的数组for(int number : numbers){System.out.print(number + " ");}}}

3.希尔排序(不稳定)

思路:希尔排序实际上是一种分组插入方法。其基本思想是:先取定一个小于n的整数d1(一般为n/2)作为第一个增量,把表的全部元素分成d1个组,所有相互之间距离为d1的倍数的元素放在同一个组中,在各组内进行直接插入排序;然后,取第二个增量d2(<d1,一般为d1/2),重复上述的分组和排序过程,直至所取的增量dt=1(dt<dt-1<...<d2<d1),即所有元素放在同一组中进行插入排序。


java实现:

public class Main{public static void main(String[] args){//待排序的数组int[] numbers = {3,56,12,456,5,23,16,15,56,456};int i,j,temp,gap;//增量置初值gap = numbers.length / 2;while(gap > 0){//对所有相隔gap位置的元素组采用直接插入排序for(i = gap;i < numbers.length;i++){temp = numbers[i];j = i - gap;//对相隔gap位置的元素组进行排序while(j >= 0 && temp < numbers[j]){numbers[j+gap] = numbers[j];j -= gap;}numbers[j+gap] = temp;}//减小增量gap = gap/2;}//输出排序后的数组for(int number : numbers){System.out.print(number + " ");}}}


交换排序


1.冒泡排序(稳定)

路:通过无序区中相邻元素间关键字的比较和位置的交换,使关键字最小的元素如气泡一般逐渐往上“漂浮”直至“水面”。整个算法是从最下面的元素开始,对每两个相邻的关键字进行比较,且使关键字较小的元素换至关键字较大的元素之上,使得经过一趟冒泡排序后,关键字最小的元素到达上端。接着,再在剩下的元素中找关键字次小的元素,并把它换到第二个位置上。以此类推,一直到所有元素都有序为止。


java实现:

public class Main{public static void main(String[] args){//待排序的数组int[] numbers = {3,56,12,456,5,23,16,15,56,456};int i,j,temp;boolean exchange = false; //比较,找出关键字最小的元素for(i = 0;i < numbers.length - 1;i++){for(j = numbers.length - 1; j > i;j--){if(numbers[j-1] > numbers[j]){//将numbers[j-1]与numbers[j]进行交换,将关键字最小的往前移temp = numbers[j-1];numbers[j-1] = numbers[j];numbers[j] = temp;exchange = true;}}//若本趟没有发生交换,中途结束算法if(!exchange)break;}for(int number : numbers){System.out.print(number + " ");}}}

2.快速排序(不稳定)

思路:快速排序是由冒泡排序改进而得的,他的基本思想是:在待排序的n个元素中任取一个元素(通常取第一个元素)作为基准,把该元素放入适当位置后,数据序列被此元素划分成两部分,所有关键字比该元素关键字小的元素放置在前一部分,所有关键字比它大的元素放置在后一部分,并把该元素排在这两部分的中间(称该元素归位),这个过程称做一趟快速排序,之后对所有划分出来的两部分分别重复上述过程,直至每部分内只有一个元素或为空为止。


java实现:

public class Main{public static void main(String[] args){//待排序的数组int[] numbers = {3,56,12,456,5,23,16,15,56,456};QuickSort(numbers,0,numbers.length-1);for(int number : numbers){System.out.print(number + " ");}}public static void QuickSort(int[] numbers,int s,int t){int i = s,j = t,temp;//区间内至少存在两个元素的情况if(s < t){//用区间的第一个元素作为基准temp = numbers[s];//从区间两端交替向中间扫描,直至i = j为止while(i != j){//从右向左扫描,找第一个小于temp的numbers[j]while(j > i && numbers[j] >= temp){j--;}//找到这样的numbers[j],numbers[i]与numbers[j]交换numbers[i] = numbers[j];//从左向右扫描,找第一个大于temp的numbers[i]while(j > i && numbers[i] <= temp){i++;}//找到这样的numbers[i],numbers[i]与numbers[j]交换numbers[j] = numbers[i];}numbers[i] = temp;//对左区间递归排序QuickSort(numbers,s,i-1);//对右区间递归排序QuickSort(numbers,i+1,t);}}}



参考文献:

数据结构教程/李春葆主编 -北京:清华大学出版社,2013.1

软件设计师教程/褚华主编 -北京:清华大学出版社,2014

原创粉丝点击