选择排序学习总结

选择排序:
第一趟:从n个元素中选择1个最小元素,放到序列的第一个位置;
第二趟:从n-1个元素中选择1个次小元素,放到序列的第二个位置;

第n-1趟:从2个元素中选择1个元素,放到序列倒数第二个位置。
结束。

1.简单选择排序

void SelectSort(ElemType A[],int n)
{
   for(int i=1;i<=n-1;i++)       //共进行n-1趟排序
   {
   int min=i-1;   //记录最小元素的位置
   for(int j=i;ja[j])
           min=j;       //不断更新最小元素位置
   }
   if(min!=j-1)
      swap(a[i-1],a[min]);
   }
}

分析:
①空间复杂度:O(1);
②时间复杂度:比较次数:(n-1)+(n-2)+…+2+1=n(n-1)/2固定不变,所以O(n2);
③不稳定。

2.堆排序(树形选择排序)

思想:将L[1~n]的一个序列看成是完全二叉树的顺序存储结构,利用双亲节点与孩子节点之间的关系,在无序区中选择最大或最小元素。

概念一:小根堆(L[i]<=L[2i]&&L[i]<=L[2i+1])
概念二:大根堆(L[i]>=L[2i]&&L[i]>=L[2i+1])
其中:1<=i<=⌊n/2⌋

问题1:给定一个序列,建立小根堆。
{23,17,72,60,25,8,68,71,52}
选择排序学习总结_第1张图片
问题2:堆的插入操作(插入到堆的末尾)。
选择排序学习总结_第2张图片
问题2:堆的删除操作(删除堆顶元素)。
步骤:将堆的最后一个元素放到堆顶,逐步进行向下调整。
选择排序学习总结_第3张图片
算法描述:

//建立大根堆的算法
void BuildMaxHeap(ElemType A[],int n)
{
  for(int i=n/2;i>=1;i--)
      AdjustDown(A,i,n);
}

//向下调整算法
void AdjustDown(ElemType A[],int k,int n)
{
   A[0]=A[k];     //将要调整的节点值暂时存放在A[0]中
   for(int i=2k;iA[i])      //此时,已经满足:要调整的节点值>子节点中的较大值,
            break;               即满足大根堆的要求,则不需调整,结束循环   
       else    //要调整的节点值<子节点中的较大值。
            A[k]=A[i];    //将子节点中的较大节点上移
             k=i;     ///要调整的节点位置下移
   }
   A[k]=A[0];    //将要调整的节点值放在最终位置
}


//堆排序算法
void HeapSort(ElemType A[],int n)
{
     BuildMaxHeap(A,n);
     for(i=n;i>1;i--)    //进行n-1趟
         printf(A[i]);  //输出堆顶元素
         AdjustDown(A,1,i-1);   //将剩下的i-1个元素整理成堆
}

分析:
①空间复杂度:O(1);
②时间复杂度:
           建堆时间为:O(n);
            调整趟数:n-1;
            一趟调整时间是O(h),即log2n。
所以时间复杂度为:O(nlog2n)。——不存在好坏情况
③不稳定。

你可能感兴趣的:(数据结构)