大四狗刚考完研,刷牛客网的时候发现自己七大排序都不能很流畅地写出来,实在惭愧,而排序算法是非常基础和重要的算法,所以今天特意总结了下排序算法。
为了编码方便,我所有的排序都是递增排序
(算法解释我就不写了,好多博主写了解释,感觉学会以后写算法解释好费时间。。。。每个排序我都会贴几个解释得比较好的博客链接,文末我会贴上我对这个七个排序所有的源代码,代码都写得比较精简,不过要是有觉得我写得不好的可以给我留言,毕竟我没有找别人看过代码)
一:冒泡排序
二:插入排序
三:简单选择排序
四:归并排序
五:堆排序
六:希尔排序
七:快速排序
为什么不自己写这些排序算法呢。。。?因为我懒。。我只是知识的搬运工orz。
上一段我写的完整代码,很长奥,耐着性子看完,会有收获的!(C++、Visual Studio 2017)
#include<iostream>
#include<string>
using namespace std;
//所有排序算法,为了方便都从小到大来实现
template<class T>
void swap(T*num, int i, int j)//交换元素
{
T tmp;
tmp=num[i];
num[i] = num[j];
num[j] = tmp;
}
//冒泡排序, 时间复杂度O(n ^ 2),空间复杂度O(1);
template<class T>
void BubbleSort(T *num, int size)
{
if (size <= 1)return;
for (int i = 0; i < size; i++)
{
bool flag = false;
for (int j = 0; j < size - i - 1; j++)
if (num[j] > num[j + 1])
{
swap(num, j, j + 1);
flag = true;
}
if (!flag)return;//这个是个好改进,排序完成了就退出
}
}
//插入排序,时间复杂度O(n^2),空间复杂度O(1)
template<class T>
void InsertSort(T*num, int size)
{
if (size <= 1)return;
for (int i = 1; i < size; i++)
{
T tmp = num[i];
int j;
for (j = i - 1; j >= 0 && tmp < num[j]; j--)
//反正我觉得这个写法挺酷炫的哈哈
num[j + 1] = num[j];
num[j + 1] = tmp;
}
}
//简单选择排序,时间复杂度O(n^2),空间复杂度O(1)
template<class T>
void SelectSort(T*num, int size)
{
if (size <= 1)return;
for (int i = 0; i < size; i++)
{
int min = num[i];
int min_dex = i;
for (int j = i + 1; j < size; j++)
{
if (num[j] < min)
{
min = num[j];
min_dex = j;
}
swap(num, min_dex, i);
}
}
}
//快速排序,时间复杂度O(logN),空间复杂度O(logN);
template<class T>
void QuickSort(T*num, int size)
{
int start = 0;
QuickSortway(num, start, size - 1);
之所以另外弄个函数,我只是想QuickSort函数和其他排序的参量一致
}
template<class T>
void QuickSortway(T*num, int s, int t)//递归求解
{
T tmp = num[s];
int i = s;
int j = t;
if (s >= t)return;
while (i < j)
{
//这样写快排,背都能背下来了
while (i<j&&num[j]>tmp)j--;
num[i] = num[j];
while (i<j&&num[i]<tmp)i++;
num[j] = num[i];
}
num[i] = tmp;
QuickSortway(num, s, i - 1);
QuickSortway(num, i + 1, t);
}
//堆排序,时间复杂度O(logN),空间复杂度O(1)
/*堆排序略微难理解,值得注意的是,我们要从小到大排序,是要建成大顶堆,这一点都不矛盾,因为建成大堆之后我们将堆顶和堆尾交换,这样最后一个元素就是最大的,然后再调整堆,如此循环,我一开始是就是这里卡了,不过你要是建立小顶堆也可以,就是不断地把堆顶取出来,用尾元素替换,取出来的值放到新的数组中,但是这样要开辟新的空间*/
template<class T>
void HeapAdjust(T*num, int i, int size)//调整堆,大顶堆
{
int child = 2 * i + 1;//左孩子节点下标
while (child<size)
{
if (child + 1 < size&&num[child]<num[child + 1])//右孩子更小
child++;
if (num[child]>num[i])
{
swap(num, child, i);
i = child;
child = 2 * i + 1;
}
else
break;
}
}
template<class T>
void HeapSort(T*num, int size)//堆排序
{
if (size <= 1)return;
for (int i = size / 2 - 1; i >= 0; i--)
{
HeapAdjust(num, i, size);
}//构建初始堆
for(int i = size - 1; i > 0; i--)
{
swap(num, 0, i);
HeapAdjust(num, 0, i);//不断地把堆顶取下来放到末尾
}
}
//定义的输出函数
template<class T>
void printout(T*num,int size)
{
for (int i = 0; i < size; i++)
cout << num[i];
cout << endl;
}
//归并排序,时间复杂度O(logN),空间复杂度O(N)因为需要另外开个数组
template<class T>
void MergeSort(T*num, int size)
{
if (size <= 1)return;
MergeSortway(num, 0, size - 1);
}
template<class T>
void MergeSortway(T*num, int begin, int end)
{
if (begin < end)
{
int mid = (begin + end) / 2;
MergeSortway(num, begin, mid);
MergeSortway(num, mid + 1, end);
Merge(num, begin, mid,end);
}
}
template<class T>
void Merge(T*array, int low, int mid, int hight) {
if (low >= hight) {
return;
}
T*auxArray = new T[hight - low + 1];
int index1 = low;
int index2 = mid + 1;
int i = 0;
while (index1 <= mid && index2 <= hight) {
/*虽然这样可读性低,但是我觉得很酷啊,哈哈哈,理解下++的前缀后缀就懂了*/
if (array[index1] <= array[index2])
auxArray[i++] = array[index1++];
else
auxArray[i++] = array[index2++];
}
// 继续合并前半段数组中未被合并的部分
while (index1 <= mid)
auxArray[i++] = array[index1++];
// 继续合并后半段数组中未被合并的部分
while (index2 <= hight)
auxArray[i++] = array[index2++];
// 将合并好的序列写回到数组中
for (int j = 0; j < hight - low + 1; j++)
array[low + j] = auxArray[j];
delete[]auxArray;
}
template<class T>
void initial(T*t,int size)
{
t[0] = 2;
t[1] = 3;
t[2] = 4;
t[3] = 1;
t[4] = 5;
t[5] = 9;
t[6] = 8;
t[7] = 7;
t[8] = 6;
t[9] = 0;
}
//希尔排序,这个时间复杂度和div大小有关,不好分析,空间复杂度O(1)
template<class T>
void ShellSort(T num[], int size)
{
T gap, i, j;
for (gap = size / 2; gap > 0; gap /= 2)
for (i = gap; i < size; i++)
for (j = i - gap; j >= 0 && num[j] > num[j + gap]; j -= gap)
swap(num, j, j + gap);
}
int main()
{
int num[10] = { 2,3,4,1,5,9,8,7,6,0 };
cout << "冒泡排序结果" << endl;
BubbleSort(num, 10);
printout(num, 10);
cout << endl << "选择排序结果" << endl;
initial(num, 10);
SelectSort(num, 10);
printout(num, 10);
cout << endl << "插入排序结果" << endl;
initial(num, 10);
InsertSort(num, 10);
printout(num, 10);
cout << endl<< "堆排序结果" << endl;
initial(num, 10);
HeapSort(num, 10);
printout(num, 10);
cout << endl << "快速排序结果" << endl;
initial(num, 10);
QuickSort(num, 10);
printout(num, 10);
cout << endl << "归并排序结果" << endl;
initial(num, 10);
MergeSort(num, 10);
printout(num, 10);
cout << endl << "希尔排序结果" << endl;
initial(num, 10);
ShellSort(num, 10);
printout(num, 10);
getchar();
return 0;
}
2018,请对自己狠一点!!!未来会更好,不放弃!