美文网首页
关于列表的排序算法

关于列表的排序算法

作者: LOOOOD | 来源:发表于2018-01-15 14:42 被阅读0次
  • 插入排序(insertionsort)
    算法的思路可简要描述为:始终将整个序列视作并切分为两部分:有序的前缀,无序的后缀;通过迭代,反复地将后缀的首元素转移至前缀中
    //对起始位置p的n个元素就行排序
void insertionsort(ListNode p,int n){
for (int r = 0; r < n; r++) {
 insertAfter(search(p->data, r, p), p->data); 
 p = p->succ;
 remove(p->pred);
}
}

复杂度是O(n^2),是稳定算法

  • 选择排序
    该算法也将序列划分为无序前缀和有序后缀两部分,此外,还要求前缀不大于后后缀。如此,每次只需从前缀中选出最大者,并作为最小元素转移至后缀中,即可使有序部分的范围不断扩张。
    //对起始于位置p的n个元素排序
void selectionSort(ListNode p,int n){
ListNode header=p.pred,ListNode trailer=p;
for(int r=0,r<n,r++){
trailer=trailer.succ;
}//待排序区间为(header,trailer)
while(1<n){
ListNode max=selectMax(header.succ,n);//找出最大者
insertBefore(trailer,remove(max));//作为有序区间的首元素
trailer=trailer.pred;
n--;
}
}
//从位置p起始的n个元素中查找最大的元素
ListNode selectMax(ListNode p,int n){
ListNode max=p;
for(ListNode curr=p;1<n;n--){
if((curr=curr.succ).data>=max){
max=curr;
}
return max;
}

该算法复杂度为O(n^2),从selectMax方法着手,可整体优化为O(nlogn)

  • 归并排序
    1.二路归并算法
    //有序列表的归并:当前列表自p起的n个元素,与列表L中自q起的m个元素归并
void merge(ListNode p,int n,List T,ListNode q,int m){
ListNode pp=p.pred;
while(m>0){
if((n>0)&&(p.data<=q.data)){
  if(q==(p=(p.succ))){
break;
n--;
}
  }
else{
insertBefore(p,L.remove((q=q.succ).pred));
m--;
}
p = pp->succ;
}

2.分治策略

void mergeSort(ListNode p, int n) { 
if (n < 2)
 return; //若待排序范围已足够小,则直接返回;
int m = n >> 1; //以中点为界
ListNode q = p; 
for (int i = 0; i < m; i++) 
q = q->succ; //均分列表
 mergeSort(p, m);
 mergeSort(q, n - m); //对前、后子列表分删排序
 merge(p, m, *this, q, n - m); //归并
}

总体算法复杂度是O(nlogn)

相关文章

网友评论

      本文标题:关于列表的排序算法

      本文链接:https://www.haomeiwen.com/subject/pgploxtx.html