七种常见的排序:插入排序(直接排序,希尔排序),选择排序(选择排序,堆排序),交换排序(冒泡排序,快速排序),递归排序(归并排序)

1.第一种用堆进行排序

//用堆进行排序

void HeapAdjust(int *array, int size, int parent)
{
   int child =parent * 2 + 1;
   while (child< size)
   {
      if (child+ 1 < size&&array[child + 1] < array[child])
         child =child + 1;
      if (array[child]< array[parent])
      {
         Swap(&array[parent],&array[child]);
         parent =child;
         child =parent * 2 + 1;
      }
      else
         return;
   }
}
void HeapSort(int *array, int size)
{
//1.建堆
   int last =((size - 2) >> 1);
   for (; last>= 0; --last)
      HeapAdjust(array, size,last);//向下调整
//2.排序
   int end =size - 1;
   while (end)
   {
      Swap(&array[0],&array[end]);
      HeapAdjust(array, end,0);
      end--;
   }
}

第二类排序方式插入排序(直接排序,希尔排序)

//插入排序(直接排序)
void InsertSort(int *array, int size)
{
   int i = 1;
   for (i; i< size; i++)
   {
      int key = array[i];
      int end = i- 1;
      //搬移元素
      while (key< arrar[end] && end >= 0)
      {
         array[end +1] = array[end];
         end--;
      }
      //插入
      array[end +1] = key;
   }
}
//插入排序适合量小,并且接近有序的序列
//假如给你一个量大的序列 ,并且让你使用插入排序的思想进行排序(分组)
//什么叫接近有序---->大的元素尽量靠后,小的元素尽量前,不大不小的在中间

//插入排序(希尔排序)    隔着元素交换,所以希尔排序不稳定
void ShellSort(int *array,int size)
{
   int gap =size;                

   while (gap> 1)
   {
    gap = gap / 3 + 1;             //如果gap给的不好,会影响希尔排序性能,那gap有人提出,gap=gap/3+1;
    int i = gap;              
    for (i; i < size; i++)
     {
      int key = array[i];
      int end = i- gap;
      //搬移元素
      while (key< arrar[end] && end >= 0)
      {
         array[end +gap] = array[end];
         end -= gap;
      }
      //插入
      array[end +gap] = key;
     }
    //gap-=1;
   }
}

3.第三类排序选择排序(选择排序和堆排序)

//选择排序(选择排序,堆排序)
//选择排序
void Swap(int *x, int *y)
{
   int temp =*x;
   *x = *y;
   *y = temp;
}


void SelectSort(int *array, int size)
{
   for (int i = 0;i < size; ++i)
   {
      int MaxPos= 0;
      int j = 1;
      for (j; j< size - i; ++j)
      {
         if (array[j]>array[MaxPos])
            MaxPos =j;
      }
      if(MasPos!=size-i-1)
       Swap(&array[MaxPos],&array[size -i - 1]);
   }
}


//选择排序优化(上面那个排序只是一次性找一个元素,优化后的代码一次性找一个最大的,一个最小的 ,使效率加快)
void SelectSort_OP(int *array, int size)
{
   int begin =0;
   int end =size - 1;
   while (begin< end)
   {
      int MaxPos= begin;
      int MinPos= begin;
      int i =begin;
      while (i<= end)
      {
         if (array[i] >MaxPos)
            MaxPos =i;
         if (array[i] <MinPos)
            MinPos =i;
         i++;
      }
      if (MaxPos!= end)
        Swap(&array[MaxPos],&array[end]);
      if (MinPos== end)
         MinPos =MaxPos;          //这个是一个判读,这个判断,判断的是一个特殊情况,最大值交换后,改变了原先最小值所标记的位置,所以这里需要重新标记
      if (MinPos!= begin)
         Swap(&array[MinPos],&array[begin]);
      begin++;
      end--;
   }
}
//选择排序不稳定

4.交换排序(冒泡排序,快排)

//交换排序(冒泡排序,快速排序)
//冒泡排序
void BubbleSort(int *array, int size)
{
   int i, j;
   for (i = 0;i < size; ++i)
   {
      for (j = 1;j < size - i; ++j)
      {
         if (array[j -1]>array[j])
            Swap(&array[j - 1],&array[j]);
      }
   }
}


//冒泡稳定
//快排,面试里面考的最多的
int Partion(int *array, int left, int right)
{
   int key = array[right -1];
   int begin =left;
   int end =right - 1;
   while (begin< end)
   {
      //从前往后找比基准值大的元素,找到就停下来
      while (begin< end && array[begin] <= key)
         begin++;
      //从后往前找比基准值小的元素,找到就停下来
      while (begin< end && array[end] >= key)
         end--;
      if (begin< end)
         Swap(&array[begin],&array[end])
   }
   if (begin!= right - 1)
      Swap(&array[begin],&array[right -1])
      return begin;
}

 

 
void QuickSort(int *array, int left, int right)
{
   while (right- left > 1)
   {
      int div =Partion(array, left,right);
      QuickSort(array, left,div);
      QuickSort(array, div -1, right);
   }
}

 

//快排变化,挖坑法(变的只是划分方式,上面的这种排列方式是快排创始人给出的,下面说明其他方式)

int Partion2(int *array, int left, int right)
{
   int key = array[right -1];
   int begin =left;
   int end =right - 1;
   while (begin< end)
   {
     while (begin< end && array[begin] <= key)
         begin++;
      if (begin< end)
      {
         array[end] = array[begin];
         end--;
      }
      while (begin< end && array[end] >= key)
         end--;
      if (begin< end)
      {
         array[begin]= array[end];
         begin++;
      }
   }
   array[begin]= key;
   return begin;
}

 
void QuickSort2(int *array, int left, int right)
{
   while (right- left > 1)
   {
      int div =Partion2(array, left,right);
      QuickSort(array, left,div);
      QuickSort(array, div -1, right);
   }
}


//关于快排的第三种划分方式(一般想不到)
//比较短,但是也不好理解

int Partion3(int *array, int left, int right)
{
   int cur =left;
  int pre =cur - 1;
   int key = array[right -1];
   while (cur< size)
   {
      if (array[cur]< key && ++pre != cur)
         Swap(&array[cur],&array[pre]);
      ++cur;
   }
   if(++pre!=right-1)
     Swap(&array[pre],&array[right -1]);
   return pre;
}

void QuickSort3(int *array, int left, int right)
{
   while (right- left > 1)
   {
      int div =Partion2(array, left,right);
      QuickSort(array, left,div);
      QuickSort(array, div -1, right);
   }
}


//用三数取中法,改变的只是获取基数的方式
int GetMiddleIdx(int *array, int left, int right)
{
   int mid =(right + left) / 2;
  if (array[left]< array[right -1])
   {
      if (array[mid]< array[left])
         return left;
      else if (array[mid]>array[right -1])
         return right -1;
      else
         return mid;
   }
   else
   {
      if (array[mid]> array[left])
         return left;
      else if (array[mid]< array[right -1])
         return right -1;
      else
         return mid;
   }
}

 
int Partion(int *array, int left, int right)
{
   int middle= GetMiddleIdx(array, left, right);
   if (middle!= right - 1)
      Swap(&array[middle],&array[rigght- 1]); //如果基准值不是最后一个元素就把基准值和最后一个元素互换
   int key = array[right -1];
   int begin =left;
   int end =right - 1;
   while (begin< end)
   {
      //从前往后找比基准值大的元素,找到就停下来
      while (begin< end && array[begin] <= key)
         begin++;
      //从后往前找比基准值小的元素,找到就停下来
      while (begin< end && array[end] >= key)
         end--;
      if (begin< end)
         Swap(&array[begin],&array[end])
   }
   if (begin!= right - 1)
      Swap(&array[begin],&array[right -1])
      return begin;
}



void QuickSort(int *array, int left, int right)
{
   while (right- left > 1)
   {
      int div =Partion(array, left,right);
      QuickSort(array, left,div);
      QuickSort(array, div -1, right);
   }
}

5.最后一种递归排序(归并排序)

//递归排序(归并排序)
void  MergeDate(int *array, int left, int mid, int *temp)
{
   int begin1= left , end1 = mid;
   int begin2= mid , end2 = right;
   int index =left;
  while (begin1< end1&&begin2 < end2)
   {
      if (array[begin1]< array[begin2])
         temp[index++]= array[begin1++];
      else
         temp[index++]= array[begin2++];
   }
   while(begin1<end1)
      temp[index++]= array[begin1++];
   while(begin2<end2)
      temp[index++]= array[begin2++];
}


void  _MergeSort(int *array, int left, int right,int *temp)
{
   //int*temp = malloc(sizeof(array[left])*(right - left));
   if (right- left > 1)
   {
      int mid =left + ((right - left) >> 1);
      _MergeSort(array, left,mid, temp);
      _MergeSort(array, mid,right, temp);
      MergeDate(array, left,mid, temp);
      memcpy(array + left,temp + left, sizeof(array[left])*(right- left));
   }
}
 
void MergeSort(int *array, int size)
{
   int *temp =malloc(sizeof(array[0])*size);
   if (NULL== temp)
   {
      assert(0);
      return;
   }
   _MergeSort(array, 0,size, temp);
   free(temp);
}

猜你喜欢

转载自blog.csdn.net/weixin_43767691/article/details/89597401