十大排序算法(程序员必会)
Posted 小研说技术
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了十大排序算法(程序员必会)相关的知识,希望对你有一定的参考价值。
十大排序算法(C、Java)
1、 绪论
- 身为程序员,十大排序是对每一个程序员都应该掌握的算法,现在比较流行的算法如快速排序、归并排序等,对算法的时间复杂度和空间复杂度的掌握都有要求。本文将分享常见的十大排序算法,基于Java和C语言实现,让你能够掌握!
- 对于排序的分类,可以根据不同的角度比如时间、空间复杂度、比较、非比较等角度来划分。我们通常的十大排序都是内部排序,通常的话,基于[比较和非比较]这个层次来划分:
如图:
2、交换类
2-1冒泡排序
基本思想:循环遍历多次,每次从前往后把大元素往后调,每次确定一个最大(最小)元素,多次到达排序序列。
2-1-1动画演示
- Java实现代码:
/*
* 1、冒泡排序
*/
public static void maoPaoSort(int[] array) {
for(int i=array.length-1;i>=0;i--) {
for(int j=0;j<i;j++) {
if(array[j]>=array[j+1]) {
int t=array[j];
array[j]=array[j+1];
array[j+1]=t;
}
}
}
}
- C语言实现代码:
void bubble_sort(int a[], int n)
{
int i,j,temp;
for (j=0;j<n-1;j++)
{
for (i=0;i<n-1-j;i++)
{
if(a[i]>a[i+1])
{
temp=a[i];
a[i]=a[i+1];
a[i+1]=temp;
}
}
}
}
2-2快速排序
基本思想:将一个序列分为2部分,序列左边全部小于一个数,序列右边全部大于一个数。然后利用递归的思想再将左序列当成一个完整的序列再进行排序,同样把序列的右侧也当成一个完整的序列进行排序。
2-2-1动画演示
- Java实现代码:
/*
* 2、快速排序
*/
public static void quickSort(int[] array,int left,int right) {
int low=left;
int high=right;
if(low>high) {
return ;
}
int k=array[low];
while(low<high) {
while(low<high&&array[high]>=k) {
high--;
}
array[low]=array[high];
while(low<high&&array[low]<=k) {
low++;
}
array[high]=array[low];
}
array[low]=k;
quickSort(array,left,low-1);
quickSort(array,low+1,right);
}
- C语言实现代码:
void QuickSort(int* data, int left, int right, int direction)
{
int i = left, j = right, index = data[left];
if (data == NULL)
return;
if (right >= sizeof(*data)/sizeof(int))return;
if (left < 0)
return;
if (left >= right)
return;
while(i<j)
{
while(data[j]<=index)
j--;
data[i] = data[j];
while(data[i]>=index&&i < j)
i++;
data[j]=data[i];
}
data[i]=index;
QuickSort(data,left,i-1,direction);
QuickSort(data,i+1,right,direction);
}
3、插入类
3-1直接插入排序
基本思想:简单的说,就是按身高来排序,从第一个开始,如果前面有比自己高的,就直接插入到合适的位置。一直到队伍的最后一个完成插入,整个队列才能满足有序。
3-1-1动画演示
- Java实现代码:
/*
* 3、直接插入排序
*/
public static void insertSort(int[] array) {
int temp=0;
for(int i=1;i<array.length;i++) {
temp=array[i];
for(int j=i-1;j>=0;j--) {
if(array[j]>temp) {
array[j+1]=array[j];
array[j]=temp;
}else {
break;
}
}
}
}
- C语言实现代码:
void insertsort(int *k,int n)
{
int i,j;
int temp;
for(i=1;i<n;i++)
{
temp = k[i];
j = i - 1;
while(j>=0 && k[j]>temp)
{
k[j+1] = k[j];
j--;
}
k[j+1] = temp;
}
}
3-2希尔排序
基本思想:希尔排序是特殊的插入排序,直接插入排序每次插入前的遍历步长为1,而希尔排序是将待排序列分为若干个子序列,对这些子序列分别进行直接插入排序,当每个子序列长度为1时,再进行一次直接插入排序时,结果一定是有序的。常见的划分子序列的方法有:初始步长(两个子序列相应元素相差的距离)为要排的数的一半,之后每执行一次步长折半。
3-2-1动画演示
- Java实现代码:
/*
* 4、希尔排序
*/
public static void shellSort(int[] array) {
int len=array.length;
int temp=0;
for(;len>=1;len/=2) {
for(int i=len;i<array.length;i++) {
temp=array[i];
for(int j=i-len;j>=0;j-=len) {
if(array[j]>temp) {
array[j+len]=array[j];
array[j]=temp;
}else {
break;
}
}
}
}
}
- C语言实现代码:
void shellSort(int *a, int len)
{
int i, j, k, tmp, gap;
for(gap=len/2;gap>0;gap/=2) {
for(i=0;i<gap;++i) {
for(j=i+gap;j<len;j+=gap) {
tmp=a[j];
k=j-gap;
while(k>=0&&a[k]>tmp) {
a[k+gap]=a[k];
k-=gap;
}
a[k+gap]=tmp;
}
}
}
}
4、选择类
4-1简单选择排序
基本思想:首先,选出最小的数,放在第一个位置;然后,选出第二小的数,放在第二个位置;以此类推,直到所有的数从小到大排序。
4-1-1动画演示
- Java实现代码:
/*
*5、 简单选择排序
*/
public static void selectSort(int[] array) {
for(int i=0;i<array.length-1;i++) {
int min=i;
for(int j=i+1;j<array.length;j++) {
if(array[j]<array[min]) {
min=j;
}
}
if(min!=i) {
swap1(array,i,min);
}
}
}
public static void swap1(int[] array,int i,int j) {
int t=array[i];
array[i]=array[j];
array[j]=t;
}
- C语言实现代码:
void SelectSort(int a[],int n){
int mix,temp;
int i,j;
for(i=0;i<n-1;i++){
mix=i;
for(j=i+1;j<n;j++)
if(a[j]<a[mix])
mix=j;
if(i!=mix) {
temp=a[i];
a[i]=a[mix];
a[mix]=temp;
}
}
}
4-2堆排序
基本思想:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。
4-2-1动画演示
- Java实现代码:
/*
* 6、堆排序
*/
public static void swap2(int[] array,int m,int n) {
int t=array[m];
array[m]=array[n];
array[n]=t;
}
public static void shiftDown(int[] array,int index,int len) {
int left=index*2+1;
int right=index*2+2;
if(left>=len) {
return ;
}else if(right<len&&array[right]<array[index]&&array[right]<array[left]) {
swap2(array, index, right);
shiftDown(array, right, len);
}else if(array[left]<array[index]) {
swap2(array, index, left);
shiftDown(array, left, len);
}
}
public static void createHeap(int[] array) {
for(int i=array.length/2;i>=0;i--) {
shiftDown(array, i,array.length);
}
}
public static void heapSort(int[] array) {
int[] val=new int[array.length];
createHeap(array);
for(int i=0;i<array.length;i++) {
val[i]=array[0];
array[0]=array[array.length-1-i];
shiftDown(array, 0, array.length-i);
}
for(int i=0;i<array.length;i++) {
array[i]=val[i];
}
}
- C语言实现代码:
void AdjustDown(DataType* a, size_t n, int parent)
{
int child = parent * 2 + 1;
while(child < n)
{
if((child + 1 < n)&&(a[child+1]>a[child]))
{
++child;
}
if(a[child]>a[parent])
{
Swap(&a[child], &a[parent]);
parent=child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
void HeapSort(DataType* a, size_t n)
{
assert(a);
for(int i = (n - 2) / 2; i >= 0; i--)
{
AdjustDown(a, n, i);
}
int end = n - 1;
while(end > 0)
{
Swap(&a[0], &a[end]);
AdjustDown(a, end, 0);
--end;
}
}
5、归并类
5-1归并排序
基本思想:将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并, 使用中牺牲空间换取时间的算法。
5-1-1动画演示
- Java实现代码:
/*
* 7、归并排序
*/
public static void mergeSort(int[] array,int left,int right) {
int mid=(left+right)/2;
if(left<right)
{
mergeSort(array, left, mid);
mergeSort(array, mid+1, right);
merge(array, left,mid, right);
}
}
public static void merge(int[] array,int l,int mid,int r) {
int lindex=l;
int rindex=mid+1;
int temp[]=new int[r-l+1];
int teamindex=0;
while (lindex<=mid&&rindex<=r) {
if(array[lindex]<=array[rindex])
{
temp[teamindex++]=array[lindex++];
}else {
temp[teamindex程序员必会十大算法之贪心算法