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

来源:互联网 发布:amd优化游戏 编辑:程序博客网 时间:2024/05/01 03:46

一、插入类排序

       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);
               }
           }