排序算法作为算法和数据结构的重要部分,系统地学习一下是很有必要的。排序是计算机内经常进行的一种操作,其目的是将一组“无序”的记录序列调整为“有序”的记录序列。
排序分为内部排序和外部排序:
常说的的八大排序算法均属于内部排序。如果按照策略来分类,大致可分为:交换排序、插入排序、选择排序、归并排序和基数排序。如下图所示:
下表给出各种排序的基本性能,本篇文章不做详细介绍,具体分析请参看其他博客的详解:
下面介绍面试中经常出现的三种排序算法:
LeetCode中关于排序的题目有以下三种类型题:
(一)排序之三大排序代码实现:
(二)排序之变形排序相关题目:
(三)排序之归位排序相关题目:
class Solution {
public:
int Partition1(vector& nums, int low, int high){
int key = nums[low];
while(low < high){
while(low < high && nums[high] >= key) high--;
swap(nums[low], nums[high]);
while(low < high && nums[low] <= key) low++;
swap(nums[low], nums[high]);
}
return low;
}
int Partition2(vector& nums, int low, int high){
int pos = low;
for(int i = low; i < high; i++){
if(nums[i] <= nums[high]) swap(nums[pos++], nums[i]);
}
swap(nums[pos++], nums[high]);
return pos - 1;
}
int QuickSort(vector& nums, int low, int high){
if(low < high){
int index = Partition2(nums, low, high);
QuickSort(nums, low, index - 1);
QuickSort(nums, index + 1, high);
}
}
void sortIntegers(vector& nums) {
QuickSort(nums, 0, (int)nums.size() - 1);
}
};
class Solution {
public:
void MaxHeap(vector& nums, int parent, int len){
int child = 2 * parent + 1;
while(child < len){
while(child + 1 < len && nums[child] < nums[child + 1]) child++;
if(nums[child] > nums[parent]){
swap(nums[child], nums[parent]);
parent = child;
child = 2 * parent + 1;
}else break;
}
}
void HeapSort(vector& nums){
int len = nums.size();
for(int i = (len - 1)/2; i >= 0; i--)
MaxHeap(nums, i, len);
for(int j = len ; j > 0; j--){
MaxHeap(nums, 0, j);
swap(nums[0], nums[j - 1]);
}
}
void sortIntegers(vector& nums) {
HeapSort(nums);
}
};
class Solution {
public:
void MergeArray(vector& nums, int low, int high){
vector temp(high - low + 1, 0);
int mid = (low + high)/2, k = 0;
int i = low, m = mid, j = mid + 1, n = high;
while(i <= m && j <= n){
if(nums[i] <= nums[j]) temp[k++] = nums[i++];
else temp[k++] = nums[j++];
}
while(i <= m) temp[k++] = nums[i++];
while(j <= n) temp[k++] = nums[j++];
for(int p = 0; p < temp.size(); p++)
nums[low + p] = temp[p];
}
void MergeSort(vector& nums, int low, int high){
if(low < high){
int mid = (low + high)/2;
MergeSort(nums, low, mid);
MergeSort(nums, mid + 1, high);
MergeArray(nums, low, high);
}
}
void sortIntegers(vector& nums) {
MergeSort(nums, 0, (int)nums.size() -1);
}
};
75. Sort Colors
class Solution {
public:
void sortColors(vector& nums) {
int n = nums.size(), left = 0, right = n - 1, i = 0;
while(i <= right){
if(nums[i] == 0) swap(nums[i++], nums[left++]);
else if(nums[i] == 1) i++;
else swap(nums[i], nums[right--]);
}
}
};
324. Wiggle Sort II
nums
, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]...
.class Solution {
public:
void wiggleSort(vector& nums) {
int n = nums.size(),j = (n + 1)/2, k = n;
sort(nums.begin(), nums.end());
vector temp = nums;
for(int i = 0; i < n; i++){
nums[i] = (i&1) ? temp[--k] : temp[--j];
}
}
};
179. Largest Number
class Solution {
public:
string largestNumber(vector& nums) {
string res = "";
sort(nums.begin(), nums.end(), [](int a, int b){
return to_string(a) + to_string(b) > to_string(b) + to_string(a);
});
for(auto num : nums){
res += to_string(num);
}
return res[0] == '0' ? "0" : res;
}
};
451. Sort Characters By Frequency
class Solution {
public:
string frequencySort(string s) {
unordered_map hash;
for(auto ch : s) hash[ch]++;
sort(s.begin(), s.end(), [&](char& a, char& b){
return hash[a] > hash[b] || (hash[a] == hash[b] && a < b);
});
return s;
}
};
215. Kth Largest Element in an Array
class Solution {
public:
int findKthLargest(vector& nums, int k) {
int low = 0, n = nums.size(), high = n -1;
while(low <= high){
int pos = partition(nums, low, high);
if(pos < n - k) low = pos + 1;
else if(pos > n - k) high = pos - 1;
else return nums[pos];
}
return low;
}
int partition(vector& nums, int low, int high){
int key = nums[low];
while(low < high){
while(low < high && nums[high] >= key) high--;
swap(nums[low], nums[high]);
while(low < high && nums[low] <= key) low++;
swap(nums[low], nums[high]);
}
return low;
}
};
442. Find All Duplicates in an Array
class Solution {
public:
vector findDuplicates(vector& nums) {
vector res;
for(int i = 0; i < nums.size(); i++){
if(nums[i] != nums[nums[i] - 1]){
swap(nums[i], nums[nums[i] - 1]);
--i;
}
}
for(int i = 0; i < nums.size(); i++){
if(nums[i] != i + 1){
res.push_back(nums[i]);
}
}
return res;
}
};
448. Find All Numbers Disappeared in an Array
class Solution {
public:
vector findDisappearedNumbers(vector& nums) {
vector res;
for(int i = 0; i < nums.size(); i++){
if(nums[i] != nums[nums[i] - 1]){
swap(nums[i], nums[nums[i] - 1]);
--i;
}
}
for(int i = 0; i < nums.size(); i++){
if(nums[i] != i + 1){
res.push_back(i + 1);
}
}
return res;
}
};
41. First Missing Positive
class Solution {
public:
int firstMissingPositive(vector& nums) {
int n = nums.size();
for(int i = 0; i < nums.size(); i++){
if(nums[i] != i + 1){
if(nums[i] >= 1 && nums[i] <= nums.size() && nums[i] != nums[nums[i]-1]){
swap(nums[i], nums[nums[i]-1]);
i--;
}
}
}
for(int i = 0; i < nums.size(); i++){
if(nums[i] != i + 1)
return i + 1;
}
return n + 1;
}
};
如果各位看官们,大神们发现了任何错误,或是代码无法通过OJ,或是有更好的解法,或是有任何疑问,意见和建议的话,请一定要在帖子下面评论区留言告知博主啊,多谢多谢,祝大家刷得愉快,刷得精彩,刷出美好未来~