非比较排序:计数排序,基数排序
直接插入排序
“test.cpp”
#include<iostream>
using namespace std;
#include<assert.h>
void InsertSort(int* arr,size_t size)
{
assert(arr);
for(int i = 0;i < size-1;i++)
{
int j = i;
int tmp = arr[i+1];
while(j >= 0 && arr[j] > tmp)
{
arr[j+1] = arr[j];
j--;
}
arr[j+1] = tmp;
}
}
void test()
{
int arr[] = {3,7,1,0,2,6,8,5,9,4};
size_t size = sizeof(arr)/sizeof(arr[0]);
InsertSort(arr,size);
for(size_t i = 0;i < size;i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
int main()
{
test();
return 0;
}
希尔排序
“test.cpp”
#include<iostream>
using namespace std;
#include<assert.h>
void ShellSort(int* arr,size_t size)
{
assert(arr);
int gap = size;
while(gap > 1)
{
gap = gap / 3 + 1;
for(int i = 0;i < size - gap;i++)
{
int j = i;
int tmp = arr[i+gap];
while(j >= 0 && arr[j] > tmp)
{
arr[j + gap] = arr[j];
j -= gap;
}
arr[j + gap] = tmp;
}
}
}
void test()
{
int arr[] = {3,4,1,2,8,9,5,6,0,7};
size_t size = sizeof(arr)/sizeof(arr[0]);
ShellSort(arr,size);
for(size_t i = 0;i < size;i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
int main()
{
test();
return 0;
}
选择排序
“test.cpp”
#include<iostream>
using namespace std;
void SelectSort(int* arr,int size)
{
//最小的放在左边,最大的放在右边
int left = 0;
int right = size - 1;
while(left < right)
{
int min = left;
int max = left;
for(int i = left;i <= right;i++)
{
if(arr[i] < arr[min])
min = i;
if(arr[i] > arr[max])
max = i;
}
swap(arr[left],arr[min]);
//处理最大的数字在最左边,最小的数字在最右边的情况(图解)
if(max == left)
{
max = min;
}
swap(arr[right],arr[max]);
left++;
right--;
}
}
void test()
{
//int arr[] = {2,5,4,9,3,6,8,7,1,0};
int arr[] = {9,5,4,2,3,6,8,7,1,0};
int size = sizeof(arr)/sizeof(arr[0]);
SelectSort(arr,size);
for(int i = 0;i < size;++i)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
int main()
{
test();
return 0;
}
堆排序
“test.cpp”
#include<iostream>
using namespace std;
//向下调整
void AdjustDown(int* arr,size_t size,int parent)
{
int child = 2 * parent + 1;
while(child < size)
{
if(child + 1 < size && arr[child + 1] > arr[child])
++child;
if(arr[child] > arr[parent])
swap(arr[child],arr[parent]);
else
break;
parent = child;
child = 2 * parent + 1;
}
}
void HeapSort(int* arr,size_t size)
{
//建堆,从第一个非叶子节点开始向下调整
for(int i = (size-2) / 2;i >= 0; --i)
{
AdjustDown(arr,size,i);
}
//升序,每次取堆顶的数据和最后一个数据进行交换
//再对堆顶进行向下调整
int end = size - 1;
while(end > 0)
{
swap(arr[0],arr[end]);
//size的范围逐渐缩小,用end来控制size的大小
AdjustDown(arr,end,0);
--end;
}
}
void test()
{
int arr[] = {2,5,4,9,3,6,8,7,1,0};
int size = sizeof(arr)/sizeof(arr[0]);
HeapSort(arr,size);
for(int i = 0;i < size;++i)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
int main()
{
test();
return 0;
}
冒泡排序
“test.cpp”
#include<iostream>
using namespace std;
void BubbleSort(int* arr,size_t size)
{
for(int i = 0;i < size - 1;i++)//趟数
{
bool flag = false;
for(int j = 0;j < size - 1 - i;j++)//比较个数
{
if(arr[j + 1] < arr[j])
{
swap(arr[j+1],arr[j]);
flag = true;
}
}
if(flag == false)
break;
}
}
void test()
{
int arr[] = {2,6,4,9,0,1,7,3,8,5};
int size = sizeof(arr)/sizeof(arr[0]);
BubbleSort(arr,size);
for(int i = 0;i < size;i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
int main()
{
test();
return 0;
}
快速排序
“test.cpp”
#include<iostream>
using namespace std;
#include<stack>
//前后指针法
int ParkSort3(int* arr,int begin,int end)
{
int key = arr[end];
int cur = begin;
int prev = begin - 1;
while(cur < end)
{
if((arr[cur] < key) && (++prev !=
cur))
swap(arr[cur],arr[prev]);
++cur;
}
swap(arr[++prev],arr[end]);//记住每次交换前
prev都要++
return prev;
}
//三数取中法——解决时间复杂度最坏的情况(O(N^2))
int GetMidNum(int* arr,int begin,int end)
{
int mid = begin + (end - begin)/2;
if(arr[begin] > arr[mid])
{
if(arr[end] < arr[mid])//arr[mid]是中
间值
return mid;
else//arr[end] > arr[mid]
{
//此时,arr[mid]是最小的值,中
间值在arr[begin],arr[end]中选择
if(arr[end] > arr[begin])
return begin;
else//arr[end] < arr[begin]
return end;
}
}
else//arr[begin] < arr[mid]
{
if(arr[end] > arr[mid])
return mid;
else//arr[end] < arr[mid]
{
if(arr[end] > arr[begin])
return end;
else //arr[end] < arr[begin]
return begin;
}
}
}
//挖坑法
int ParkSort2(int* arr,int begin,int end)
{
int tmp = GetMidNum(arr,begin,end);
swap(arr[end],arr[tmp]);
int key = arr[end];
int left = begin;
int right = end;
while(left < right)
{
while(left < right && arr[left] <=
key)
++left;
arr[right] = arr[left];
while(left < right && arr[right] >=
key)
--right;
arr[left] = arr[right];
}
arr[left] = key;
return left;
}
//单趟排序
int ParkSort1(int* arr,int begin,int end)
{
int left = begin;
int right = end - 1;
int tmp = GetMidNum(arr,begin,end);
swap(arr[end],arr[tmp]);
int key = arr[end];
while(left < right)
{
//left所指的值要比arr[end](key值)大
while(left < right && arr[left] <=
key)
++left;
//right所指的值要比arr[end](key值)小
while(left < right && arr[right] >=
key)
--right;
if(left < right)
swap(arr[left],arr[right]);
}
//出了循环以后,此时left和right指向同一个位置,
此时
//将arr[left](arr[right])的值和arr[end](key值)
交换
if(arr[left] > key)
{
swap(arr[left],arr[end]);
return left;
}
else
return end;
}
void QuickSort(int* arr,int begin,int end)
{
if(begin >= end)
return;
//int div = ParkSort1(arr,begin,end);
//int div = ParkSort2(arr,begin,end);
int div = ParkSort3(arr,begin,end);
QuickSort(arr,begin,div-1);
QuickSort(arr,div+1,end);
}
//非递归实现快速排序
void QuickSortNonR(int* arr,int begin,int end)
{
stack<int> s;
s.push(end);
s.push(begin);
while(!s.empty())
{
int left = s.top();
s.pop();
int right = s.top();
s.pop();
int div = ParkSort1(arr,left,right);
if(left < div - 1)
{
s.push(div-1);
s.push(left);
}
if(div + 1 < right)
{
s.push(right);
s.push(div+1);
}
}
}
void test()
{
int arr[] = {5,2,9,0,1,8,3,6,4,7};
//int arr[] = {5,2,9};
int size = sizeof(arr)/sizeof(arr[0]);
//QuickSort(arr,0,size-1);
QuickSortNonR(arr,0,size-1);
for(int i = 0;i < size;i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
int main()
{
test();
return 0;
}
归并排序
“test.cpp”
#include<iostream>
using namespace std;
void Sort(int* arr,int* tmp,int begin,int mid,int end)
{
int index = 0;
int left = begin;
int right = mid + 1;
while(left <= mid && right <= end)
{
if(arr[left] < arr[right])
tmp[index++] = arr[left++];
else
tmp[index++] = arr[right++];
}
while(left <= mid)
tmp[index++] = arr[left++];
while(right <= end)
tmp[index++] = arr[right++];
index = 0;
for(int i = begin;i <= end;++i)
{
arr[i] = tmp[index++];
}
}
void _MergeSort(int* arr,int* tmp,int begin,int end)
{
if(begin >= end)
return;
int mid = begin + (end - begin)/2;
_MergeSort(arr,tmp,begin,mid);
_MergeSort(arr,tmp,mid+1,end);
Sort(arr,tmp,begin,mid,end);
}
void MergeSort(int* arr,size_t size)
{
int* tmp = new int[size];
_MergeSort(arr,tmp,0,size-1);
delete[] tmp;
}
void test()
{
int arr[] = {3,8,2,0,7,6,1,5,9,4};
//int arr[] = {3,8,2};
int size = sizeof(arr)/sizeof(arr[0]);
MergeSort(arr,size);
for(size_t i = 0;i < size;i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
int main()
{
test();
return 0;
}
非比较排序
计数排序
“test.cpp”
#include<iostream>
using namespace std;
void CountSort(int* arr,int size)
{
int min = arr[0];
int max = arr[0];
for(int i = 1;i < size;++i)
{
if(arr[i] < min)
min = arr[i];
if(arr[i] > max)
max = arr[i];
}
int range = max - min + 1;
int* count = new int[range];
for(int i = 0;i < size;++i)
{
count[arr[i] - min]++;
}
int index = 0;
for(int i = 0;i < range;i++)
{
while(count[i] != 0)
{
arr[index++] = i + min;
count[i]--;
}
}
}
void test()
{
int arr[] = {5,2,9,6,1,8,7,0,4,3};
//int arr[] = {5,2,9};
int size = sizeof(arr)/sizeof(arr[0]);
CountSort(arr,size);
for(int i = 0;i < size;++i)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
int main()
{
test();
return 0;
}
基数排序
“test.cpp”
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
//求数中最大数的位数
int GetMaxDigit(int* arr,int size)
{
int base = 10;
int digit = 1;
for(int i = 0;i < size;++i)
{
while(arr[i] >= base)
{
base *= 10;
++digit;
}
}
return digit;
}
void NewCountSort(int* arr,int size)
{
int digit = GetMaxDigit(arr,size);
int base = 1;
int* tmp = new int[size];
while(digit--)
{
vector<int> count(10);//0-9
for(int i = 0;i < size;++i)
{
int num = (arr[i] / base) % 10;
count[num]++;
}
vector<int> start(10);
for(int i = 1;i < 10;++i)
start[i] = start[i-1] + count[i-1];
for(int i = 0;i < size;++i)
{
int num = (arr[i] / base) % 10;
//对各个数字进行排序(快速转置的方法)
tmp[start[num]++] = arr[i];
}
//拷贝数值回数组里
for(int i = 0;i < size;++i)
{
arr[i] = tmp[i];
}
//由低位向高位排序
base *= 10;
}
delete[] tmp;
}
void test()
{
int arr[] = {4,7,2,0,9,3,6,1,8,5};
int size = sizeof(arr)/sizeof(arr[0]);
NewCountSort(arr,size);
for(int i = 0;i < size;++i)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
int main()
{
test();
return 0;
}