多种排序算法的总结(不包括复杂度的详细推算)
稳定排序与不稳定排序
稳定排序:相同元素在排序中的相对位置不改变。
不稳定排序:相同元素在排序中的相对位置改变。
内部排序与外部排序:
内部排序:待排的记录与内容都放在计算机的随机存储器中进行的排序过程
外部排序:一般指待排序记录的数量很大,以致内存中一次不能完全容纳全部的记录,在排序过程中,需要对外存进行访问的排序过程。
排序算法的复杂度:
在此我们一般只要考虑的就是时间复杂度,当然个别排序的空间复杂度也很大,如希尔排序。这里时间复杂度的计算方法和一般复杂度计算方法类似。
按照排序的过程中所依据的不同可以分类为:
插入排序,交换排序,选择排序,归并排序,基数排序,二叉排序树排序
插入排序:
利用有序表的插入操作进行排序
有序表的插入:将一个记录插入到已经安排好的有序表中,从而得到一个新的有序表。
直接插入排序算法主要应用比较和移动两种操作。
void insertsort(int R[],int n){ int i,j,temp; for(i=1;i<n;i++) { temp=R[i]; j=i-1; while((j>=0)&&(temp<R[j])) { R[j+1]=r[j]; j--; } R[j+1]=temp;//put single on first }</span>
希尔排序(有一种直接插入排序的改进)
方法:先将待排序列分割成为若干的子序列分别进行直接插入排序;待整个序列中的记录基本有序后,在进行一次直接插入排序。
希尔排序的时间复杂度:
O(nlog2n)和O(N平方)之间大约O(N的1.3次方)
void shellsort(int a[],int arrsize) { int temp; int gap=arrsize/2; while(gap != 0){ for(int i=gap;i<arrsize;i++){ temp=a[i]; for(int j=i;j>=gap;j-=gap){ if(temp < a[j-gap]) a[j]=a[j-gap]; else break; } a[j] = temp; } gap = (int)(gap/2); } }</span>
交换排序--冒泡排序
思想:通过不断比较相邻元素的大小,进行交换实现排序
void bubblesort(int a[],int n) { int flag = 1; for(i=1;i<n;i++) { flag=0; for(int j=n-1;j>=i;j--) if(R[j]<R[j-1]) { t = R[j]; R[j]=R[j-1]; R[j-1]=t; flag=1; } if(flag==0) return ; } }</span>
交换排序--快速排序
冒泡排序的一种改进算法
思想:以首记录作为轴记录,从前,后向扫描序列,通过交换,实现大值记录后移,小值记录前移,最终将轴记录安置在一个适当的位置(小值记录在前,大值记录在后)
轴记录将原序列分割成两个部分,依次对前后两部分重新设定轴记录,继而分别在进行快速排序。直至整个序列有序。
快速排序----分割过程
快速排序是一个分治的算法
对于一个序列,取它的一个元素作为轴,把所有小与轴的元素放在它的左边,大于它的元素放在它的右边
分割算法:
用临时变量对轴进行备份
取链噶个指针LOW 和HING ,他们的初始值就是序列的两端小表,在整个过程中保证LOW 不大于HIGH
移动两个指针
首先从HING 所知的位置向左搜索,找到第一个小与轴的元素,把这个元素放在LOW 的位置
在从LOW开始向右,找到第一个大与轴的元素,把它放在HING 的位置
重复上述过程,直到LOW=HIGH
把轴放在LOW 所指的位置
这样所有大于轴的元素北方在右边,所有小与轴的元素被放在左边。
void Fquick_sort(int *addr,int low,int high) { int lowpos = low; int highpos= high; int povite = addr[low]; if(lowpos >= highpos){ return ; } while(lowpos < highpos){ while((lowpos < highpos)&&(add[highpos]>=povite)){ highpos--; } if(lowpos < highpos){ addr[lowpos] = addr[highpos]; lowpos++; } while((lowpos < highpos)&&(addr[lowpos]<=povite)){ lowpos++; } if(lowpos < highpos){ addr[highpos]=addr[lowpos]; highpos--; } } addr[lowpos]=povit; Fquick_sort(addr,low,lowpos-1); Fquick_sort(addr,lowpos+1,high); return ; }</span>
时间复杂度:平均O(nlog2n)
空间复杂度:O(N平方)
快速排序是一种不稳定的排序方法
简单选择排序:
每一趟都选出一个最大或最小的元素,并放在适当的位置。
void selsectSort(int a[],int n) { int i,j; int temp; for(i=0;i<n-1;i++) for(j=i+1;j<n;j++) { if(a[i]>a[j]) { temp=a[i]; a[i]=a[j]; a[j]=a[i]; } } } </span>
归并排序:
思想:将两个有序的序列合并成一个有序的序列,所以如果只有两个元素,所以归并排序就是将一个序列不停拆分,直到拆成一个一个元素为止,然后再进行合并排序。
void merge(int *add,int len) { int lenA = 0,lenB = 0,lenC = 0,lentmp = 0; int *arrC = NULL; if(len <= 1){ return ; } arrC = (int *)malloc(len*sizeof(int)); lentmp = len/2; merge(add,lentmp); merge(&add[lentmp],len-lentmp); lenA = 0;lenB = lentmp; lenC = 0; while((lenA != lentmp)&&(lenB != len)){ if(add[lenA]<add[lenB]){ arrC[lenC] = add[lenA]; lenA++; }else{ arrC[lenC] = add[lenB]; lenB++; } lenC++; } if(lenA == lentemp){ while(lenB < len){ arrC[lenC++]=add[lenB++]; } }else if(lenB == len){ while(lenA < lentmp){ arrC[lenC++]=add[lenA++]; } }else{ //printf("all ok !\n"); memcpy(add,arrC,len*sizeof(int)); free(arrC);</span>