数据结构与算法之排序:堆排序、归并排序及快速排序

来源:互联网 发布:ios11降级数据丢失 编辑:程序博客网 时间:2024/05/17 04:25

堆排序(Heap Sort) 利用堆(一般为大根堆)进行排序的方法。它的基本思想是:将待排序的序列构造成一个大根堆。此时,整个序列的最大值就是堆顶的根结点。将它移走(其实就是将其与堆数组的末尾元素进行交换,此时末尾元素就是最大值),然后将剩余的n-1个序列重新构造成一个大根堆,这样就会得到n个元素中的次大值。如此反复执行,便能得到一个有序序列了。

堆是具有下列性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大根堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小根堆。其时间复杂度为O(NlogN)

  void PercDown(int A[] , int i , int N) { int child ; int tmp ; for ( tmp = A[i] ; LeftChild(i) < N ; i = child) { child = LeftChild(i); if( child != N-1 && A[child+1] > A[child])//判断做孩子是否小于有孩子      child++; if(tmp < A[child]) //判断父节点 是否大于子节点,大于则不交换,反之交换。      A[i] = A[child]; else break; } A[i] = tmp ; // 将tmp的值赋给父节点  }  void HeapSort(int A[] , int N) {  for ( int i = N/2 ; i >= 0 ; --i) // 构造一个大根堆          PercDown(A,i,N);  for ( int i = N - 1 ; i >= 0; --i)//将堆顶和未排序的最后一个元素交换,然后继续调整堆   {     swap(A[0],A[i]);     PercDown(A,0,i);  }        }

归并排序:一种典型的利用了分治算法的实例。归并排序的基本思想是将两个已排序的表合并到一起,对于两个已经排序的表不断比较,将较小者放入暂存的表中。当两个表有一个用完的时候,就直接将剩下的表放入暂存表中。对于归并排序的分割来说,它需要将长度为N 的表不断的递归分割,然后归并排序,大概需要O(logN)的时间,由于需要对分割的表进行比较,总次数为N次,则总的时间复杂度为O(NlogN),但是有一点不可忽略,归并排序需要一个暂存的数组,大小为N.

void Merge(int A[], int Tmp[] , int lo , int lb , int hi) { int loEd = lb - 1 ;int Tpos = lo ;int Num = hi - lo + 1 ; while(lo <= loEd && lb <= hi){ if(A[lo] < A[lb]) Tmp[Tpos++] = A[lo++]; else  {   Tmp[Tpos++] = A[lb++];  // count += loEd - lo + 1 ;     }}while(lo <= loEd) Tmp[Tpos++] = A[lo++];while(lb <= hi)   Tmp[Tpos++] = A[lb++];for ( int i = 0 ; i < Num ; ++i ,hi--)        A[hi] = Tmp[hi]; } void Msort(int A[], int Tmp[] , int lo , int hi) { if( lo < hi) { int mid =  ((hi+lo))/2; Msort(A , Tmp , lo , mid); Msort(A , Tmp , mid+1 , hi); Merge(A , Tmp , lo , mid+1 , hi); } } void  MergeSort(int A[] , int N) { int *Tmp = new int[N];    if(Tmp == NULL)  exit(-1);    else    {     Msort(A , Tmp , 0 , N - 1);     delete[] Tmp;    } } 

快速排序:详情见点击打开链接

这个里面谈到一种简单明了的思想就是“挖坑填数法+分治”。、

1.当i在j的左边时候,i右移,移过小于坑的元素;

2.j左移,移过大于坑的元素。

3.当i指向一个大元素,而j指向一个小元素。相互交换

4.当i==j 的时候,开始填坑,将坑中的元素赋给i

5.然后不断的重复这个过程,直到全部有序

void Qsort( int A[] , int lo , int hi) { if ( lo < hi) { int i = lo , j = hi ; int key = A[lo];  while(i<j)  { while(i<j && A[j] >= key) j--; if(i < j ) A[i++] = A[j] ; while(i<j && A[i] <= key) i++; if(i < j)  A[j--] = A[i] ;  }  A[i] = key ;     Qsort(A , lo , i-1);     Qsort(A ,i+1 , hi) ; }     }


0 0
原创粉丝点击