八大排序算法
来源:互联网 发布:长春学历网络教育 编辑:程序博客网 时间:2024/06/06 08:27
排序算法汇总总结
一、插入排序
直接插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
代码实现:
#include <stdio.h>#include <stdlib.h>void swap(int *p1, int *p2){ int temp; temp=*p1; *p1=*p2; *p2=temp;}void insertSort(int *a,int len){ int i,j; for(i=0;i<len;i++) { for(j=i+1;j>=1;j--) { if(a[j]<a[j-1]) swap(&a[j],&a[j-1]); } }}
希尔排序,也称递减增量排序算法,是插入排序的一种高速而稳定的改进版本。它的基本思想是先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为dl的倍数的记录放在同一个组中。先在各组内进行直接插人排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。该方法实质上是一种分组插入方法。
代码实现:
#include <stdio.h>#include <stdlib.h>void swap(int *p1, int *p2) { int temp; temp = *p1; *p1 = *p2; *p2 = temp;}void shell(int *a, int d, int len) { int i, j; for (i = d - 1; i < len; i++) { for (j = i + d; j >= i && j < len; j--) { if (a[j] < a[j-d]) { swap(&a[j], &a[j-d]); } } }}void shellSort(int *a, int d, int len) { while (d >= 1) { shell(a, d, len); d = d / 2; }}
二、交换排序
冒泡排序(Bubble Sort)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
代码实现:(swap函数同前 以后同)
void bubbleSort(int *a,int len){ int i,j,change; for(i=0;i<len;i++) { change=0; for(j=len-1;j>i;j--) { if(a[j]<a[j-1]) { change=1; swap(&a[j],&a[j-1]); } } if(!change) break; }}
快速排序是由东尼·霍尔所发展的一种排序算法 基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
代码实现:
int partition(int *a ,int s, int e){ int roll=a[s], i, j; for (i=s+1,j=i ;i<=e; i++) { if (a[i] < roll) { swap(&a[i],&a[j]); j++; } } swap(&a[s],&a[j-1]); return j-1;}void quickSort(int *a, int start,int end){ if(start<=end) { int split=partition(a,start,end); quickSort(a,start,split-1); quickSort(a,split+1,end); }}
三、选择排序
直接选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾(目前已被排序的序列)。以此类推,直到所有元素均排序完毕。
代码实现:
void selectSort(int *a, int len){ int i,j,min,mark; for(i=0;i<len;i++) { min=a[i]; for(j=i+1;j<len;j++) { if(a[j]<min) { min=a[j]; mark=j } } if(min!=a[i]) swap(&a[i],&a[mark]); }}
堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆性质:即子结点的键值或索引总是小于(或者大于)它的父节点
代码实现:
void shift(int *a,int r,int len){ int j,maxid; for(j=r;j<=len/2;) { maxid=j; if(2*j<len && a[2*j]>a[j]) maxid=2*j; if(2*j+1<len && a[2*j+1]>a[maxid]) maxid=2*j+1; if(maxid!=j) { swap(&a[maxid],&a[j]); } } }void buildHeap(int *a, int len) //为便宜计算 a的下标从1开始 构建大顶堆{ int i; for(i=len/2;i>0;i--) shift(a,i,len);}void heapSort(int *a, int len){ int clen; buildHeap(a,len); swap(&a[1],&a[len]); for(clen=len-1;clen>0;clen--) { shift(a,1,clen); swap(&a[1],&a[clen]); } }
四、归并排序
归并排序(Merge sort,台湾译作:合并排序)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
算法描述
归并操作的过程如下:
- 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
- 设定两个指针,最初位置分别为两个已经排序序列的起始位置
- 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
- 重复步骤3直到某一指针达到序列尾
- 将另一序列剩下的所有元素直接复制到合并序列尾
代码实现:
void merge(int *a,int start,int mid,int end){ if(start>mid || mid >end ) return; int i=start,j=mid+1,k=0; int *L=(int *)malloc((end-start+1)*sizeof(int)); while(i<=mid && j<=end) { if(a[i]<a[j]) { L[k++]=a[i++]; }else { L[k++]=a[j++]; } } while(i<=mid) L[k++]=a[i++]; while(j<=end) L[k++]=a[j++]; for(i=start,j=0;i<=end;i++,j++) { a[i]=L[j]; } free(L);}void mergeSort(int *a, int start,int end){ if(start<end) { int mid=(start+end)/2; mergeSort(a,start,mid); mergeSort(a,mid+1,end); merge(a,start,mid,end); }}
五、基数排序
基数排序(Radix sort)是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。
算法实现(未验证正确性):
struct DNode{ int data; DNode *next;}struct Table{ int id; DNode *fisrt;}int digit(int num,int loc){ for(int i=1;i<loc;i++) num/=10; int res=num%10; return res;}int maxCount(int *a,int len){ int max=0,n,num; for(int i=0;i<len;i++) { n=0; num=a[i]; while(num) { num/=10; n++; } if(n>max) max=n; } return max;}void radixSort(int *a,int len){ int maxloc=maxcount(a,len); DNode *ptemp; Table *t=(Table *)malloc(10 * sizeof(Table)); for(int i=0;i<10;i++) { t[i]->id=i; t[i]->first=NULL; } for(int j=1;j<maxcount;j++) { for(int k=0;k<len;k++) { int idm=digit(a[k],j); DNode *p=t[idm]->first; while(pt->next!=NULL) p=p->next; DNode *d=(DNode *)malloc(sizeof(DNode)); d->data=a[k]; d->next=p->next; p->next=d; } for(int i=0,k=0;i<=9;i++) { while(t[i]->first!=NULL) { a[k--]=t[i]->first->data; ptemp=t[i]->first; t[i]->first=t[i]->first->next; free(ptemp); } } }}
- [算法]--八大排序算法
- 八大排序算法总结
- 八大排序算法总结
- 八大排序算法总结
- 八大排序算法总结
- 八大排序算法总结
- 八大排序算法总结
- 八大排序算法总结
- 八大排序算法总结
- 八大排序算法总结
- 八大排序算法总结
- 八大排序算法
- 八大排序算法总结
- 八大排序算法总结
- 八大排序算法总结
- 八大排序算法总结
- 八大排序算法总结
- 八大排序算法总结
- Socket使用大全
- HashMap与ConcurrentHashMap的区别
- 运用C#编程通过OPC方式实现PC机与西门子PLC通讯-同步通讯篇
- 基本数据型态转换成 String,String 转换成 数字的基本数据型态
- Zookeeper场景实践:(8) 分布式队列
- 八大排序算法
- 2014ICPC World final A题(未解之谜)
- Codeforces Round #157 (Div. 1) C. Little Elephant and LCM (数学、dp)
- 【设计模式笔记】面向对象编程的理解
- 利用分治法的排序算法比较
- 2014.11.1题解(4)——杭电2037
- NOIP复习篇———动态规划
- 归并排序学习笔记
- shell 高级操作、正则表达