十大经典排序算法
https://www.runoob.com/w3cnote/ten-sorting-algorithm.html
排序算法:
快排:
基本思路:每次都取数组的第一个元素作为比较标准(哨兵元素),凡是大于这个哨兵元素的都放在它的右边,凡是小于这个哨兵元素的都放在它的左边;递归的进行此过程,直至排序完成。
最好:nlogn 最坏:n^2 平均:nlogn
void quicksort(struct Interval *intervals, int start, int end)
{
int i, j;
struct Interval temp;
if (start > end)
{
return;
}
temp = intervals[start];
i = start;
j = end;
while (i != j)
{
while (i < j && intervals[j] >= temp)
{
j--;
}
while (i < j && intervals[i] <= temp)
{
i++;
}
if (i < j)
{
struct Interval tmp = intervals[i];
intervals[i] = intervals[j];
intervals[j] = tmp;
}
}
intervals[start] = intervals[i];
intervals[i] = temp;
quicksort(intervals, start, i - 1);
quicksort(intervals, i + 1, end);
}
//严蔚敏《数据结构》标准分割函数
Paritition1(int A[], int low, int high) {
int pivot = A[low];
while (low < high) {
while (low < high && A[high] >= pivot) {
--high;
}
A[low] = A[high];
while (low < high && A[low] <= pivot) {
++low;
}
A[high] = A[low];
}
A[low] = pivot;
return low;
}
void QuickSort(int A[], int low, int high) //快排母函数
{
if (low < high) {
int pivot = Paritition1(A, low, high);
QuickSort(A, low, pivot - 1);
QuickSort(A, pivot + 1, high);
}
}
非递归算法
void QuickSortNotR(int* array,int left,int right)
{
assert(array);
stack<int> s;
s.push(left);
s.push(right);//后入的right,所以要先拿right
while(!s.empty)//栈不为空
{
int right = s.top();
s.pop();
int left = s.top();
s.pop();
int index = PartSort(array,left,right);
if((index - 1) > left)//左子序列
{
s.push(left);
s.push(index - 1);
}
if((index + 1) < right)//右子序列
{
s.push(index + 1);
s.push(right);
}
}
}选择排序:
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
重复第二步,直到所有元素均排序完毕。
最好:n^2 最坏:n^2 平均:n^2
void selectsort(struct Interval *intervals, int intervalsSize)
{
int k;
for (int i = 0; i < intervalsSize-1; i++)
{
k=i;
for (int j = k + 1; j < intervalsSize; j++)
{
if (intervals[j] < intervals[k])
{
k = j;
}
}
if (i!=k)
{
struct Interval tmp = intervals[i];
intervals[i] = intervals[k];
intervals[k] = tmp;
}
}
}插入排序:
将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)
最好:n 最坏:n^2 平均:n
void insertsort(struct Interval *intervals, int intervalsSize)
{
for (int i = 1; i < intervalsSize; i++)
{
int key=intervals[i];
int j=i-1;
while((j>=0) && (key<intervals[j])){
intervals[j+1]=intervals[j];
j--;
}
intervals[j+1]=key;
}
}冒泡排序:
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
最好:n 最坏:n^2 平均:n^2
template<typename T> //整数或浮点数皆可使用,若要使用类(class)或结构体(struct)时必须重载大于(>)运算符
void bubble_sort(T arr[], int len) {
int i, j;
for (i = 0; i < len - 1; i++)
for (j = 0; j < len - 1 - i; j++)
if (arr[j] > arr[j + 1])
swap(arr[j], arr[j + 1]);
}归并排序:
1.申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
2.设定两个指针,最初位置分别为两个已经排序序列的起始位置;
3.比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
4.重复步骤 3 直到某一指针达到序列尾;
5.将另一序列剩下的所有元素直接复制到合并序列尾。
最好: nlogn 最坏: nlogn 平均:nlogn
template<typename T> // 整數或浮點數皆可使用,若要使用物件(class)時必須設定"小於"(<)的運算子功能
void merge_sort(T arr[], int len) {
T *a = arr;
T *b = new T[len];
for (int seg = 1; seg < len; seg += seg) {
for (int start = 0; start < len; start += seg + seg) {
int low = start, mid = min(start + seg, len), high = min(start + seg + seg, len);
int k = low;
int start1 = low, end1 = mid;
int start2 = mid, end2 = high;
while (start1 < end1 && start2 < end2)
b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++];
while (start1 < end1)
b[k++] = a[start1++];
while (start2 < end2)
b[k++] = a[start2++];
}
T *temp = a;
a = b;
b = temp;
}
if (a != arr) {
for (int i = 0; i < len; i++)
b[i] = a[i];
b = a;
}
delete[] b;
}。。
void merge(vector<int>& A,int start,int mid,int end) {
vector<int> left(A.begin()+start,A.begin()+mid+1);
vector<int> right(A.begin() + mid+1, A.begin() + end + 1);
left.push_back(numeric_limits<int>::max());
right.push_back(numeric_limits<int>::max());
int leftid = 0, rightid = 0;
for (int i = start; i <= end;++i ) {
if (left[leftid] < right[rightid]) {
A[i] = left[leftid];
++leftid;
}
else {
A[i] = right[rightid];
++rightid;
}
}
}
void merge_sort(vector<int>& A, int start, int end) {
if (start < end) {
int mid = (start + end) / 2;
merge_sort(A,start,mid);
merge_sort(A,mid+1,end);
merge(A,start,mid,end);
}
}。。
希尔排序
希尔排序算是对简单插入排序的一种改进,属于一种增量式的排序算法。
时间复杂度:
一、基本原理
希尔排序听名字就能想到是Shell提出来的,只是对直接插入排序做了一个基本的改进。什么改进呢?
希尔排序是把序列按一定间隔分组,对每组使用直接插入排序;随着间隔减小,一直到1,使得整个序列有序
我们用一张图来表示一下:

腾讯成长空间 5960人发布