排序算法总结

Posted auhz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序算法总结相关的知识,希望对你有一定的参考价值。

冒泡排序:从无序区通过交换找出最大元素放到有序区前端。

1 void BubbleSort(vector<int> &v) 
2     int n = v.size();
3     for (int i = 0; i < n - 1; ++i)
4         for (int j = 0; j < n - 1 - i; ++j)
5             if (v[j] > v[j + 1])
6                 swap(v[j], v[j + 1]);
7 

选择排序:从未排序序列中找到最小(大)元素,存到已排序序列的起始位置。

 1 void SelectSort(vector<int> &v) 
 2     int n = v.size();
 3     for (int i = 0; i < n - 1; ++i) 
 4         min = i;
 5         for (int j = i + 1; j < n; ++j) 
 6             if (v[j] < v[min]) 
 7                 min = j;
 8         
 9         if (i != min)
10             swap(v[j], v[min]);
11     
12 

插入排序:

1. 从第一个元素开始,该元素可以认为已经被排序

2. 取出下一个元素,在已经排序的元素序列中从后向前扫描

3. 如果该元素(已排序)大于新元素,将该元素移到下一位置

4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置

5. 将新元素插入到该位置后

6. 重复步骤2~5

 1 void InsertSort(vector<int> &v) 
 2     int n = v.size();
 3     for (int i = 1; i < n; ++i) 
 4         int tmp = v[i];
 5         for (int j = i - 1; j >= 0; --j) 
 6             if (v[j] > tmp) 
 7                 v[j + 1] = v[j];
 8                 v[j] = tmp;
 9              else break;
10         
11     
12 

快速排序:(小数,基准元素,大数)。在区间中随机挑选一个元素作基准,将小于基准的元素放在基准之前,大于基准的元素放在基准之后,再分别对小数区与大数区进行排序。

 1 void QuickSort(vector<int> &v, int left, int right) 
 2     if (left >= right) return;
 3     int i = left + 1, j = right, key = v[left];
 4     while (i < j) 
 5         while (v[i] < key)
 6             i++;
 7         while (v[j] > key)
 8             j--;
 9         if (i < j)
10             swap(v[i++], v[j--]);
11         else i++;
12     
13     swap(v[j], v[left]);
14     QuickSort(v, left, j - 1);
15     QuickSort(v, j + 1, right);
16 

归并排序:归并排序是将数组分成两半,这两半分别排序后,再归并在一起。排序某一半时,继续沿用
同样的排序算法,最终,你将归并两个只含一个元素的数组。

 1 void Merge(vector<int> &v, int left, int mid, int right) 
 2     int i = left, j = mid + 1;
 3     vector<int> help(right - left + 1, 0);
 4     for (int k = 0; k < right - left; ++k) 
 5         help[k] = v[left + k];
 6     for (int k = 0; k < rigfht - left; ++k) 
 7         if (i > mid) v[left + k] = help[j++];
 8         else if (j > right) v[lqft + k] = help[i++];
 9         else if (help[j - left] < help[i - left]) v[left + k] = help[j++ - left];
10         else v[left + k] = help[i++ - left];
11     
12 
13 void MergeSort(vector<int> &v, int l, int r) 
14     if (r <= l) return;
15     int mid = l + (r - l) / 2;
16     MergeSort(v, l, mid);
17     MergeSort(v, mid + 1, r);
18     merge(v, l, mid, r);
19 

希尔排序:每一轮按照事先决定的间隔进行插入排序,间隔会依次缩小,最后一次一定要是1。

 1 void ShellSort(vector<int> &v, int length) 
 2     int h = 1;
 3     while (h < length / 3) 
 4         h = 3 * h + 1;
 5     
 6     while (h >= 1) 
 7         for (int i = h; i < length; i++) 
 8             for (int j = i; j >= h && v[j] < v[j - h]; j -= h) 
 9                 swap(a[j], a[j - h]);
10             
11         
12         h = h / 3;
13     
14 

计数排序:计数排序基于一个假设,待排序数列的所有数均为整数,且出现在(0,k)的区间之内。如果 k(待排数组的最大值) 过大则会引起较大的空间复杂度,一般是用来排序 0 到 100 之间的数字的最好的算法,但是它不适合按字母顺序排序人名。计数排序不是比较排序,排序的速度快于任何比较排序算法。时间复杂度为 O(n+k),空间复杂度为 O(n+k)。

堆排序:堆是一种特殊的树形数据结构,即完全二叉树。堆分为大根堆和小根堆,大根堆为根节点的值大于两个子节点的值;小根堆为根节点的值小于两个子节点的值,同时根节点的两个子树也分别是一个堆。

  • 步骤一:建立大根堆--将n个元素组成的无序序列构建一个大根堆,
  • 步骤二:交换堆元素--交换堆尾元素和堆首元素,使堆尾元素为最大元素;
  • 步骤三:重建大根堆--将前n-1个元素组成的无序序列调整为大根堆

    重复执行步骤二和步骤三,直到整个序列有序。

 

以上是关于排序算法总结的主要内容,如果未能解决你的问题,请参考以下文章

十大经典排序算法总结(希尔排序)

十大经典排序算法总结(快速排序)

十大经典排序算法总结(基数排序)

十大经典排序算法总结(冒泡排序)

十大经典排序算法总结(堆排序)

排序算法总结