注:以下算法代码为编程过程中自己排序根据基本性能和要求所创造的一个备忘录,经常写着代码忘记了排序算法怎么写,如有侵权,请联系我删除
1.插入排序
算法步骤 :
1.从第一个元素开始,通常认为该元素已经排序,从第二个元素开始
2.取下一个元素elem,从已排序的元素序列从后往前扫描
3.如果该元素大于elem,则将该元素移到下一位
4.重复步骤3,直到找到已排序元素中小于等于elem的元素
5.elem插入到该元素的后面,如果已排序所有元素都大于elem,则将elem插入到下标为0的位 置,首位
6.重复步骤2~5
思路:通常认为是N-1个序列有序,加入第N个序列,也使这个序列成为有序序列。但是通常不检验该序列是否有序,插入位置,应从头开始比较。即为首位元素有序。依次加入剩余元素。由于算法思想,当该序列有序,即为从小到大升序,时间复杂度也为o(n),最好情况,这里采用的是直接插入方法。
代码实现:
void insertsort(elemtype a[],int length)//elemtype 是数据类型,length为数组长度
{
for (int i = 1; i < length; i++)
{
elemtype temp = a[i]; //从第二为数据开始插入排序
int j = i;
while (j > 0 && a[j - 1] > temp)//设置j>0,当前一位元素大于后一位时,交换元素
{
a[j] = a[j - 1];
j--;
}
a[j] = temp;
}
}
//双层循环,平均时间复杂度O(n*n),最坏时间时间复杂度也为O(n*n),空间复杂度O(1)
补充:算法稳定性稳定
2.冒泡排序
被认为是所有算法中最为简单的一个初学者算法,但是由于其时间复杂度和性能低,而被大部分程序不喜欢
冒泡排序算法的原理如下:
-
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
-
对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
-
针对所有的元素重复以上的步骤,除了最后一个。
-
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较
-
代码实现:
void bubbleSort(elemtype a[], int length)
{
int begin = length;
while (begin)
{
int flag = 0;
for (int i = 1; i < end; ++i)
{
if (a[i - 1] > arr[i])
{
elemtype tem = arr[i];
a[i] = a[i - 1];
a[i - 1] = tem;
flag = 1;
}
}
if (flag == 0)
{
break;
}
--begin;
}
}
3.选择排序
算法思想
- 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置
- 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
- 重复第二步,直到所有元素均排序完毕。其中最小的元素是除之前已经找到的元素中,最小的
//选择排序
void selectionsort(elemtype num[], int length)
{
for (int i = 0; i < length - 1; i ++)
{
int j = i;
for (int k = i + 1; k < length; k++)
{
if (num[k] < num[j])
{
j = k;
}
}
if (j != i)
{
elemtype temp = num[j];
num[j] = num[i];
num[i] = temp;
}
}
}
4.归并排序
1.概念
归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法,归并排序对序列的元素进行逐层折半分组,然后从最小分组开始比较排序,合并成一个大的分组,逐层进行,最终所有的元素都是有序的
步骤:
-
申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
-
设定两个指针,最初位置分别为两个已经排序序列的起始位置
-
比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
-
重复步骤3直到某一指针达到序列尾
-
将另一序列剩下的所有元素直接复制到合并序列尾
代码实现:
//first和end为num第一个元素和最后一个元素的索引
void merge_sort(int num[], int first, int end)
{
if (first < end)
{
int mid = (first + end) / 2;
merge_sort(num, first, mid);
merge_sort(num, mid + 1, end);
merge(num, first, mid, end);
}
}
//合并序列[start, mid]、[mid+1, end]
void merge(int num[], int first, int mid, int end)
{
int n1 = mid - first + 1;
int n2 = end - mid;
int* L = new int[n1];
int* R = new int[n2];
for(int i = 0; i < n1; i++)
{
L[i] = num[first + i];
}
for (int j = 0; j < n2; j++)
{
R[j] = num[mid + j + 1];
}
int i = 0;
int j = 0;
int k = first;
while(i < n1 && j < n2)
{
if (L[i] < R[j])
{
num[k++] = L[i++];
}
else
{
num[k++] = R[j++];
}
}
while (i < n1)
{
num[k++] = L[i++];
}
while (j < n2)
{
num[k++] = R[j++];
}
delete [] L;
delete [] R;
}
5.快速排序
概念:快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。
代码实现:
void quick_sort(int num[], int left, int right)
{
if (left < right)
{
int i = left;
int j = right;
int x = num[i];
while (i < j)
{
while (i < j && num[j] >= x)
{
j--;
}
if(i < j)
{
num[i++] = num[j];
}
while (i < j && num[i] < x)
{
i++;
}
if(i < j)
{
num[j--] = num[i];
}
}
num[i] = x;
quick_sort(num, left, i - 1);
quick_sort(num, i + 1, right);
}
}