基于整型数组的几种基本的排序算法

一、选择排序(排成从小到大的顺序)(不稳定,时间复杂度:最差、平均都是O(n2)

   1.算法思路:

      ①找出数组中最小的数与第一个数进行交换;

      ②找出数组中第二小的数与第二个数进行交换

      ③依此类推,直到数组排序完毕.

  2.例子:

void SelectSort(int Arr[],int length)
{
   for(int m=0;m<length;m++)
   {
    int min=Arr[m];
    int index=m;
    for(int n=m+1;n<length;n++)
    {
      if(Arr[n]<min)
   { 
    min=Arr[n];
    index=n;
   }
 }
 if(index!=m)
 {
   int temp=Arr[index];
   Arr[index]=Arr[m];
   Arr[m]=temp;
 }
   }
}

二、冒泡排序(排成从小到大的顺序,大冒情况)(稳定,时间复杂度:最差、平均都是O(n2),最好是O(n)(正序情况))

1.算法思路:

  ①顺序遍历数组,相邻两个元素两两比较,大的往后交换

  ②第一遍将最大的数冒到最后一位

  ③第二遍将第二大的数冒到倒数第二位

  ④依次类推,遍历n-1遍即可排好序

2.例子:

void BubbleSort(int Arr[],int length)
{
   for(int m=0;m<length;m++)
   {
    for(int n=0;n<length-m-1;n++)
    {
      if(Arr[n]>Arr[n+1])
   { 
    int temp=Arr[n];
    Arr[n]=Arr[n+1];
    Arr[n+1]=temp;
   }
 }
   }
}

 

三、直接插入排序(排成从小到大的顺序)(稳定,时间复杂度:最差、平均都是O(n2)、最好:O(n))

1.算法思路:

 ①从第二个元素开始执行第一遍“插入”算法,将当前元素与前面(已经排好序)的元素依次进行比较

 ②当前元素是从后往前比较前面已经排好序的元素的,遇到比自己大的元素时与之交换,遇到比自己小的元素或到数组起始位置时停留在原位置不动,算是“插入”结束

 ③接着第三个元素开始执行第二遍"插入"算法,依次类推,数组中所有元素都"插入"完毕也就排好序了

2.例子:

  void InsertSort(int Arr[],int length)
{
   for(int m=1;m<length;m++)
   {
    for(int n=m;n>0;n--)
    {
      if(Arr[n-1]>Arr[n])
   { 
    int temp=Arr[n];
    Arr[n]=Arr[n-1];
    Arr[n-1]=temp;
   }
 }
   }
}

 

四、二分插入排序(稳定,时间复杂度:最差、平均都是O(n2)、最好:O(nlogn))

1.算法思路:

 ①.从数组第二个元素开始执行算法,将当前元素作为待插元素,折半查找待插元素在前面已经排好的序列中应该插入的位置index

 ②.将应该插入的位置index到待插元素当前位置前一位这一段元素全部后移一位

 ③.将待插元素插入到待插位置

 ④.当所有元素插入完毕时,即可完成排序。

2.例子:

void MiddleSort(int Arr[],int length)
{
  for(int m=1;m<length;m++)
  {
    int low=0;
    int high=m-1;
    int key=Arr[m];
    while(low<=high)
    {
      int middle=(low+high)/2;
      if(key<Arr[middle])
           high=middle-1;
      else
           low=middle+1;       
 }
 
 for(int n=m-1;n>=low;n--)
 {
      Arr[n+1]=Arr[n];
 }
 Arr[low]=key;
  }
}

 

五、希尔排序(不稳定,时间复杂度:O(nlogn))

1.算法思路:

①希尔排序本质上是直接插入排序的变种,直接插入排序是相邻元素的交换移动,这样做效率低,希尔排序进行交换的元素的间隔为dl(dl>=1),这个dl叫做增量

②给增量一个初始值,将数组划分为dl个字数组,所有距离为dl的元素互为同一子数组,用直接插入法排序所有子数组

③变小增量值,重复上一操作

④直到增量值为1,希尔排序跟直接插入排序操作一样(只不过这时,数组有很多段是连续的),排序完毕 

2.例子:

  void ShellPass(int Arr[],int length,int dl)
{
  for(int m=0+dl;m<length;m++)
  { 
 for(int n=m;n>=0+dl;n=n-dl)
 {
      if(Arr[n-dl]>Arr[n])
      {
     int temp=Arr[n-dl];
     Arr[n-dl]=Arr[n];
     Arr[n]=temp;
   }
 }
  }
}

 

void int ShellSort(int Arr,int lenth,int n)
{
   int dl=n;
   do{
     dl=dl/3+1;
     ShellPass(Arr,lenth,dl);       
   }while(dl>1);
}

 

六、快速排序(不稳定,时间复杂度:最差O(n2)、平均O(nlogn))

1.算法思路:

 ①快排采用的是分治的策略,把数组中一个元素作为基数,将数组分成左右两字段,左边所有元素均小于等于该基数,右边所有元素均大于等于该基数,递归操作字段,到字段长度为1时,即可排好序。

 ②将待排序列第一项作为该次排序的基数,有两个指针left、right,初始值分别为待排序列最左端和最右端;

 ③首先right向左边移动(不越过left,这是因为此时left指向的位置要存入待转移的元素,要保证right不能超过该位置),找到一个小于基数的元素的位置,将该元素转移到left指向的位置,同时left后移一位;

 ④然后left向右边移动(不越过right,这是因为此时right指向的位置存入待转移的元素,要保证left不能超过该位置),找到一个大于基数的元素的位置,将该元素转移到right指向的位置,同时right前移一位;

 ⑤待left和right重逢时(left==right),left所指向的位置就是该次待排序列的分割点,将基数存入left位置,left左边的元素均小于等于基数,右边均大于等于基数

 ⑥递归操作被分割出来的两个子序列序列,直到序列长度等于1时,排序结束

 

2.例子:
void QuickSort(int Arr[] ,int m,int n)
{
   if(m==n) return;
   int left=m,right=n;
   int base=Arr[left];
   while(left<right)
   {
     while((left<right)&&(Arr[right]>base))
  {
    right--;
  } 
  if(left<right)
  {
    Arr[left]=Arr[right];
    left++;
  }
   
  while((left<right)&&(Arr[left]<base))
  {
    left++;
  }
 
  if(left<right)
  {
    Arr[right]=Arr[left];
    right--; 
  }
   }
   Arr[left]=base;
   QuickSort(Arr,m,left-1);
   QuickSort(Arr,left+1,n);
}

 

posted on 2013-11-01 23:16  JYsharp  阅读(2361)  评论(0编辑  收藏  举报