十种排序算法的C++实现
前言
大学时学C语言时,依稀还记得老师讲过冒泡、插入、选择等排序算法。当时听过也就留了个印象,这么多年下来,几乎完全不记得了。最近从网上找了些博客看,自己学着用CPP实现了一遍,今日记录于此。
冒泡排序
void Solution::BubbleSort(int *arr, int length)
{
bool flag;
for(int i = 1; i < length; i++) //每次都冒泡前length-i个数
{
flag = true;
for(int j = 0; j < length - i; j++)
{
if(arr[j]>arr[j+1])
{
swap(arr[j],arr[j+1]); //大数向后移动
flag = false;
}
}
if(flag)
break;
}
}
选择排序
void Solution::SelectionSort(int *arr, int length)
{
int min;
for(int i = 0; i < length - 1; i++) //i指向未排序数组的左侧
{
min = i;
for(int j = i + 1; j < length; j++) //每次都从i后面一个开始比
{
if(arr[j] < arr[min]) min = j;
}
if(min != i) swap(arr[min],arr[i]);
}
}
插入排序
void Solution::InsertionSort(int *arr, int length)
{
int temp;
for(int i = 1; i < length; i++)
{
temp = arr[i]; //待排序数
int j;
for(j = i - 1;j >= 0 && arr[j] > temp; j--) //j指向已排序数组的最右侧
{
arr[j+1] = arr[j]; //后移
}
arr[j+1] = temp; //最后后移的元素位置
}
}
希尔排序
void Solution::ShellSort(int *arr, int length)
{
int temp;
for(int gap = length/2; gap>0; gap/=2)
{
for(int i = gap; i < length; i++) //插入排序
{
temp = arr[i]; //待排序数
int j;
for(j = i - gap; j >= 0 && arr[j] > temp; j-=gap)
{
arr[j+gap] = arr[j];
}
arr[j+gap] = temp;
}
}
}
归并排序
void Solution::MergeSort(int *arr, int left, int right)
{
if(left == right)
return;
int mid = (left + right)/2;
MergeSort(arr,left,mid);
MergeSort(arr,mid+1,right);
Merge(arr,left,mid,right);
}
void Solution::Merge(int *arr, int left, int mid, int right)
{
int *temp_arr = new int[right - left + 1];
int i = 0;
int left_ptr = left;
int right_ptr = mid + 1;
while(left_ptr <= mid && right_ptr <= right)
{
if(arr[left_ptr] < arr[right_ptr])
{
temp_arr[i++] = arr[left_ptr++];
}
else
{
temp_arr[i++] = arr[right_ptr++];
}
}
while(left_ptr <= mid)
{
temp_arr[i++] = arr[left_ptr++];
}
while(right_ptr <= right)
{
temp_arr[i++] = arr[right_ptr++];
}
i = 0;
while(i < right - left + 1)
{
arr[left + i] = temp_arr[i];
i++;
}
}
void Solution::MergeSort(int *arr, int length)
{
if(length <= 1 || arr == nullptr)
{
return;
}
MergeSort(arr, 0, length-1);
}
快速排序
void Solution::QuickSort(int *arr, int left, int right)
{
if(left >= right) return;
int mid = Partition(arr, left, right);
QuickSort(arr, left, mid - 1);
QuickSort(arr, mid + 1, right);
}
int Solution::Partition(int *arr, int left, int right)
{
int pivot = arr[left];
while (left < right)
{
while (left < right && pivot <= arr[right]) right--;
if (left < right) arr[left++] = arr[right];
while (left < right && pivot >= arr[left]) left++;
if (left < right) arr[right--] = arr[left];
}
arr[left] = pivot;
return left;
}
void Solution::QuickSort(int *arr, int length)
{
if(length <= 1 || arr == nullptr)
{
return;
}
QuickSort(arr, 0, length-1);
}
堆排序
void Solution::Heapify(int *arr, int i, int length)
{
int left = i*2+1;
int right = i*2+2;
int max_index = i;
if(left < length && arr[left] > arr[max_index]) max_index = left;
if(right < length && arr[right] > arr[max_index]) max_index = right;
if(max_index != i)
{
swap(arr[max_index], arr[i]);
Heapify(arr, max_index, length);
}
}
void Solution::HeapSort(int *arr, int length)
{
if(arr == nullptr || length <= 1) return;
int i;
for(i = length/2-1; i > 0; i--)
{
Heapify(arr, i, length);
}
for(i = length - 1; i > 0; i--)
{
swap(arr[0], arr[i]);
Heapify(arr, 0, i);
}
}
计数排序
void Solution::CountSort(int *arr, int length)
{
int i;
int max_value = arr[0];
int min_value = arr[0];
for(i = 0; i < length; i++)
{
if(arr[i] > max_value) max_value = arr[i];
if(arr[i] < min_value) min_value = arr[i];
}
int *count_arr = new int[max_value-min_value+1];
for(i = 0; i < max_value - min_value + 1; i++) count_arr[i] = 0;
for(i = 0; i < length; i++)
{
count_arr[arr[i] - min_value] += 1;
}
int j = 0;
for(i = 0; i < max_value-min_value+1; i++)
{
if(count_arr[i] > 0)
{
while(count_arr[i] > 0)
{
arr[j++] = i + min_value;
count_arr[i]--;
}
}
}
}
桶排序
void Solution::BucketSort(int *arr, int length)
{
int i;
int max_value = arr[0];
int min_value = arr[0];
for(i = 0; i < length; i++)
{
if(arr[i] > max_value) max_value = arr[i];
if(arr[i] < min_value) min_value = arr[i];
}
int bucket_size = 50;
int bucket_count = (max_value-min_value)/bucket_size + 1;
vector<vector<int>> bucket_arr(bucket_count);
for(i = 0; i < length; i++)
{
bucket_arr[(arr[i]-min_value)/bucket_size].push_back(arr[i]);
}
int j = 0;
for(auto &v1 : bucket_arr)
{
std::sort(v1.begin(), v1.end());
for(auto &v2 : v1)
{
arr[j++] = v2;
}
}
}
基数排序
void Solution::RadixSort(int *arr, int length, int radix)
{
int i, temp = 1;
vector<vector<int>> radix_arr(20);
while(radix > 0)
{
temp*=10;
radix--;
}
for(i = 0; i < length; i++)
{
radix_arr[arr[i]/temp%10+10].push_back(arr[i]);
}
int j = 0;
for(auto v1 : radix_arr)
{
for(auto v2 : v1)
{
arr[j++] = v2;
}
}
}
void Solution::RadixSort(int *arr, int length)
{
int i;
int max_value = arr[0];
int min_value = arr[0];
for(i = 0; i < length; i++)
{
if(arr[i] > max_value) max_value = arr[i];
if(arr[i] < min_value) min_value = arr[i];
}
//get radix
int radix = 0;
i = abs(max_value)>abs(min_value)?abs(max_value):abs(min_value);
while(i>0)
{
radix++;
i /= 10;
}
for(i = 0; i < radix; i++)
{
RadixSort(arr, length, i);
}
}