9大排序

内排和外排:内排是指在排序的整个过程中,待排序的所有记录全部被放置在内存中。外排序是由于排序的记录个数太多,不能同时放在内存,整个排序过程需要在内外村之间多次交换数据才能进行。

1 冒泡排序:基本思想是两两比较相邻记录的关键字,如果反序则交换,最好情况为O(n),最坏情况为O(n^2). 稳定 空间复杂度O(1)

正宗的冒泡排序--从后向前循环,两重,

for(i =1;i <L.length;i++){

     for(j =L.length-1;j>i:j++){

           if(L[j] > L[j+1])

                 swap(L,j,j+1)

      }

}

 优化的冒泡排序--在基本为正序的序列中,没有必要进行多次循环。增加一个标记变量FLAG,如果j循环一遍没有发生任何数据交换的操作,则flag为false,算法结束

status  flag = TRUE

for(i =1;i <L.length&&flag;i++){

flag = FALSE

     for(j =L.length-1;j>i:j++){

           if(L[j] > L[j+1]){

                 swap(L,j,j+1)

                 flag = TRUE

      }

   }

}

2 选择排序:通过n-i次关键字间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i个记录交换

特点是交换移动的次数比较少,稳定 空间复杂度O(1)

for(i =1;i <L.length;i++){

min =i   

for(j = i+1;j<=L.length;j++){

    if(L[min] > L[j])

          min = j

}

if(min != i)

    swap(L,min,i)

}

3 插入排序: 基本操作--将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增1的有序表 稳定 空间复杂度O(1)

for(i=2;i <= L.length:i++){

if(L[i] < L[i-1]){

L[0]  = L[i]

for(j = i-1;L[j]>L[0];j--)

     L[j+1] = L[j]

L[j+1] = L[0]

}

}

以下均为时间复杂度为O(nlogn)

堆排序:数据结构为大顶堆和小顶堆,向下取整n/2是叶子节点的分界线。每次将堆顶的元素与堆尾的元素交换,剩下的n-1个序列重新构造成堆      不稳定 空间复杂度O(1) 当待排序序列个数较少的时候堆排序不建议使用,因为初始建堆比较次数很多

 l两个部分:调整堆和主排序函数

for(i= n/2;i >0;i--){

HEAP-ADJUST(L,i,L.length) 

}

for(i = L.length;i>1;i--){

swap(L,1,i)

HEAP-ADJUST(L,1,i-1)

}


HEAP-ADJUST(L,i,m){

int temp,j

temp = L[i]         //存储父结点

for(j = 2i;j <=m;j++){

if(L[j]<L[j+1]&&j <m)

      ++j

if(temp >= L[j])

     break;

 L[s] = L[j]

  s =j

}

L[s] = temp

}


4 快速排序--通过一趟排序将待排序记录分为独立的两部分,其中一部分关键字均比另一部分记录的关键字小,性能和取得枢轴元素有关。    不稳定,时间复杂度为O(1) 使用递归实现

QUICKSORT(L){

Qsort(L,1,L.length)

}

Qsort(L,low,high){

int pivot

 if(low < high){

      pilot = partition(L,low,high)

Qsort(L,low,pivot-1)

Qsort(L,pivot+1,high)

   }

}

partition(L,high,low){

int pivotkey

pivotkey = L[low]

while(low < high){

while(low < high && L[high] >= pivotkey)

high --;

swap(L,low,high)

while(low< high && L[low] <=pivotkey)

 low++;

swap(L,low,high)

}

return low;

}

partition 如果每次都分的很均匀,需要的时间是nlogn.最坏情况则是n^2

 

快速排序优化:随机化快排(随机选择low&high之间的一个元素,不要最左最右的元素)在期望意义上最优的算法

5 归并排序:基于分治的思想,用树实现,假如初始序列中含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个长度为2或者1的子序列,再两两归并,如此重复直到得到一个长度为n的有序数列为止, 稳定,O(nlogn),空间为O(n)

MergeSort(L){

Msort(L,1,L.length)

}

Msort(L,left,right){

if(left < right){

   Msort(L,left,(left+right)/2)

   Msort(L,(left+right)/2),right}

    merge(L,left,(left+right)/2,right)

}

merge(L,left,middle,right){

int[] temp,int i,j,k

 i = left j =middle k =0

while(i< =m&& j <=right){

          if(L[i]  <= L[j])

              temp[k] = L[i]

                 i++;

          else

              temp[k] = L[j]

                    j++ ;

}
for(k = 0 ;k<=(right-left);k++){

     L [left+k]= temp[k]

}

}

归并排序使用递归实现,有大量的递归开销,不用递归实现,需要额外的空间。

 MergeSort(){

 int len  int[] L1

while(len < L.length){

       Mergepass(L,L1,len)

       len = len*2

       Mergepass(L1,L,len

        len = len*2)

}

Mergeapass(int[] L,int[] L1,int len){

int i =1

int j 

while(i <= L.length-2len+1){

Merge(L,L1,i,i+len-1,i+2len-1)

     i = i+2len+1}

if( i <n-s+1)

Merge(L,L1,i,i+s+1,L.length)}

else

for(j =i;j <= n;j++)

L1[j] = L[j]

}

 6 希尔排序 并不是随便分组,各自排序,相隔某个增量的记录组成一个子序列,实现跳跃式的移动,在最后的一个增量必须是1.

适用于数列基本有序。空间复杂度为O(1)

ShellSort(int[] L,int len){

int increment = len,temp

do{

increment = increment/3+1

for(i =increment; i <len;i +=increment){

     k =i

     temp = L[k] 

for(j = i-increment;;j >0&&L[j] >temp);j-=increment){

      L[j+increment] = L[j]

      k=j}

L[k] = temp 

}

while(increment > 1)

}

7计数排序:元素分布在一定范围k内,时间复杂度紧确界(k+n),n是元素个数  , 稳定 不基于元素之间的比较

COUNTING-SORT(A,B,k)

for  i 1to k

C[i] =0

forj=1 to length(A)

 do C[A[j]] =C[A[j]]+1

for i =2 to length(C)

   C[i ] =  C[i-1]+C[i

for j  = length(A) downto 1 

    do  B[C[A[j]]] = A[j]

               C[A[j]] = C[A[j]] -1


8 基数排序   按位排序,先排个位,十位,最后百位。如果内部嵌套的按位排序是稳定的则算法稳定。要求位数相同。当总数有n位时,分成lgn份计算最优。

RadixSort(A,n)

for i 1 to n

9 桶排序  假设数据服从均匀分布需要空间存放链表

BucketSort(A){

for i =0 to n-1

B[i] =0

for i=1 to n 

A[i]插入链表B中

fori =0 to n-1

B[i]进行排序


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值