您的位置:首页 > 理论基础 > 数据结构算法

总结数据结构中重要的排序算法

2017-09-09 09:44 218 查看

一、插入类排序

       1、直接插入排序:适合数据较小且数据较有序的数字序列。
              算法思想:将一个数组先划分成已排序好的部分和未排序好的部分,从未排序好的部分中获取一个关键数作为待排序数,在
                                  已排好序的序列中找到合适位置插入这个数据。需要一个中间变量tmp存放每次获取的关键数。
            程序代码如下:
             void insertSort(int arr[], int len)

             {

                  int i, j;

                  for (i = 2; i < len; ++i)

                {

                    arr[0] = arr[i];

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

                   {

                       arr[j + 1] = arr[j];

                   }             

                  arr[j + 1] = arr[0];

                }

            }
        2、希尔排序:又称缩小增量排序法
             
算法思想:给一个增量组合,通常给{5,3,1},即下面代码中的dka[];根据增量组合将待排序的关键字序列分成相应的若干
                                  较小子序列,对子序列进行直接插入排序,使整个待排序列排好序。
              程序代码如下:
                void shell(int arr[], int arr_len,int dk)

                 {

                       int i, j;

                       int tmp;

                      for (i = dk; i < arr_len; ++i)

                    {

                         tmp = arr[i];

                         for (j = i - dk; j >= 0 && arr[j] > tmp; j = j - dk)

                       {

                           arr[j + dk] = arr[j];

                       }

                      arr[j + dk] = tmp;

                   }

               }

              void shellSort(int arr[], int arr_len, int dka[], int dka_len)

           {

                for (int i = 0; i < dka_len; ++i)

             {

                 shell(arr,arr_len,dka[i]);

             }

          }

二、选择排序

     1、简单选择排序
           算法思想:第一趟简单选择排序时,从第一个记录开始,通过n-1次关键字的比较,从n个记录中选出关键字最小的记录,并和
                               第一个记录进行交换;
                               第二趟简单选择排序时,从第二个记录开始,通过n-2次关键字的比较,从n-1个记录中选出关键字最小的记录,并
                              和第二个记录进行交换;
                                 ......
                              第i趟简单排序时,从第i个记录开始,通过n-i次关键字的比较,从n-i+1个记录中选出关键字最小的记录,并和第i个
                            
记录进行交换;
                             如此反复,经过n-1趟简单选择排序,将把n-1个记录排到位,剩下一个最小记录直接在最后。
         程序代码如下:
             void SelectSort(int arr[], int len)

           {

               int i, j;

               int min;

               int tmp;//O(n^2) O(1)

              for (int i = 0; i < len-1; ++i)

            {

                 min = i;

                 for (j = i + 1; j < len; ++j)

               {

                     if (arr[j] < arr[min])

                    {

                         min = j;

                    }

               }

               tmp = arr[min];

              arr[min] = arr[i];

              arr[i] = tmp;

            }

         }
   2、堆排序
         算法思想:采用完全二叉树的顺序结构的特征进行分析。将待排序数组看成是一颗完全二叉树的顺序表示,每个结点表示一个
                             记录,第一个记录作为二叉树的根,之后的各记录依次逐层从左到右顺序排列,任意结点i的左孩子是2i,右孩子是
                             2i+1,对这颗完全二叉树进行调整建堆,以下程序调整为大根堆。
          程序代码如下:
                  void HeapAdjust(int arr[], int i, int len)

                 {

                          int j;

                         //j <= len   有左子树 

                         for (j = 2 * i; j <= len; j = 2 * j)

                        {

                             //j  左子树   j = len; //有左 没右  j = len

                            //左右都有

                           //就j < len

                          //j = len   有左 没右

                         // j < len  左右都有 

                           if (j < len && arr[j] < arr[j + 1])

                          {

                                j++;

                           }

                            if (arr[j] < arr[i])break;

                            arr[0] = arr[i];

                            arr[i] = arr[j];

                            arr[j] = arr[0];

                            i = j;

                        }

                    }

                 void HeapSort(int arr[], int len)

                {

                     int tmp;

                     for (int i = len / 2; i > 0; --i)

                    {

                        //i  当前要调整的堆的父节点下标  len 有效长度

                        HeapAdjust(arr,i,len);

                     }

                     for (int j = len; j > 0; --j)

                    {

                         tmp = arr[1];

                         arr[1] = arr[j];

                         arr[j] = tmp;

                        HeapAdjust(arr, 1, j-1);

                    }

                 }

三、交换类排序
   1、冒泡排序
         算法思想:通过对相邻的数据元素的进行交换,逐步将待排序列变成有序序列。
         程序代码如下:
                 void BubbleSort(int arr[], int len)
               { 

                   int tmp;

                   bool mark = false;

                  for (int i = 0; i < len-1; i++)

                {

                     mark = false;

                     for (int j = 0; j < len - 1 - i; ++j)

                   {

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

                       {

                          tmp = arr[j];

                          arr[j] = arr[j + 1];

                          arr[j + 1] = tmp;

                          mark = true;

                       }

                  }

                  printf("i = %d\n", i);

                  if (!mark)

                {

                      break;

                }

              }

            }    
   2、快速排序
         算法思想:采用分治法的思想,选一个基准,晓得数据放到基准数字的左边,大的数据放到右边。
         程序代码如下:
                int partition(int *arr,int low,int high)
              {
                    int tmp=arr[low];
                   while(low<high)
                  {
                         while(low<high&&arr[high]>tmp)
                        {
                              high--;
                        }
                        arr[low]=arr[high];
                        while(low<high&&arr[low]<tmp)
                       {
                             low++;
                       }
                       arr[high]=arr[low];
                  }
                  arr[low]=tmp;
                  return low;
              }
             void QSort(int *arr,int low,int high)
            {
                   if(low<high)
                  {
                       int boundkey=partition(arr,low,high);
                       QSort(arr,low,boundkey-1);
                       QSort(arr,boundkey+1,high);
                   }
            }
             void QuickSort(int *arr,int len)
            {
                 QSort(arr,0,len-1);
            }
四、归并排序
        算法思想:归并排序基本思想基于合并,将两个或两个以上有序表合并成一个新的有序表。首先将初始序列的n个记录看成n个有
                            序的子序列,每个子序列长度为1,然后两两归并,得到n/2个长度为2的有序子序列;在此基础上,再对长度为2的有
                            序子序列进行两两归并,得到若干长度为4的有序子序列。如此重复,直到得到一个长度为n的有序子序列为止。
        程序代码如下:
               void Merge(int arr[], int tmp[], int startIndex, int midIndex, int endIndex)

              {

                   int i = startIndex;

                   int j = midIndex + 1;

                   int k = startIndex;
                   while (i != midIndex + 1 && j != endIndex + 1)

                  {

                      if (arr[i] > arr[j])

                     {

                         tmp[k++] = arr[j++];

                      }

                      else

                     {

                         tmp[k++] = arr[i++];

                      }

                   }

                  while (i != midIndex + 1)

                 {

                     tmp[k++] = arr[i++];

                  }

                  while (j != endIndex + 1)

                 {

                    tmp[k++] = arr[j++];

                  }
                  for (int i = startIndex; i <= endIndex; ++i)

                 {

                      arr[i] = tmp[i];

                  }

             }

            void MergeSort(int arr[], int tmp[], int startIndex, int endIndex)

           {

                if (startIndex < endIndex)

               {

                    int midIndex = (startIndex + endIndex) / 2;

                    MergeSort(arr, tmp, startIndex, midIndex);

                    MergeSort(arr, tmp, midIndex + 1, endIndex);

                    Merge(arr, tmp, startIndex, midIndex, endIndex);

               }

           }

      
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: