排序算法
排序算法可以分为两种:
- 比较排序。主要有:冒泡排序,选择排序,插入排序,快速排序,归并排序。
- 非比较排序。
冒泡排序
冒泡排序运作方式
- 比较相邻的元素,如果前一个比后一个大,就把它们两个调换位置。
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做 完后,最后的元素会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
代码实现
void BubbleSort(int* array,int length)
{
for(int i=0;i<length-1;i++)
{
for(int j=0;j<length-1-i;j++)
{
if(array[j]>array[j+1])
{
int tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
}
}
}
return;
}
选择排序
选择排序工作原理
初始时在序列中找到最小(大)元素,放到序列的起始位置作为已排序序列;然后,再从剩余未排序元素中继续寻找最小(大)元素,放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
代码实现
void SelectSort(int* array,int length)
{
int index = 0;
for(int i=0;i<length-1;i++)
{
index = i;
for(int j=i+1;j<length;j++)
{
if(array[j]<array[index])
{
index = j;
}
}
if(i != index)
{
int tmp = array[i];
array[i] = array[index];
array[index] = tmp;
}
}
return;
}
插入排序
插入排序实现步骤
- 从第一个元素开始,该元素可以认为已经被排序
- 取出下一个元素,在已经排序的元素序列中从后向前扫描
- 如果该元素(已排序)大于新元素,将该元素移到下一位置
- 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
- 将新元素插入到该位置后
- 重复步骤2~5
代码实现
void InsertSort(int* array,int length)
{
for(int i=1;i<length;i++)
{
for(int j=i;j>0;j--)
{
if(array[j-1]<array[j])
break;
else
{
int tmp = array[j];
array[j] = array[j-1];
array[j-1] = tmp;
}
}
}
}
快速排序
快速排序原理
- 在待排序的元素任取一个元素作为基准(通常选第一个元素,但最的选择方法是从待排序元素中随机选取一个作为基准),称为基准元素;
- 将待排序的元素进行分区,比基准元素大的元素放在它的右边,比其小的放在它的左边;
- 对左右两个分区重复以上步骤直到所有元素都是有序的。
代码实现
void QuickSort(int* array,int length)
{
int *left,*right;
int left_length=0,right_length=0;
int base = array[0];
left = array;
right = array + length -1;
while(right != left)
{
while(*right>=base and right != left)
--right;
while(*left<=base and right != left)
{
++left;
++left_length;
}
if(right != left)
{
int tmp = *left;
*left = *right;
*right = tmp;
}
}
int tmp = *array;
*array = *left;
*left = tmp;
right_length = length - left_length - 1;
if (left_length >= 2)
QuickSort(array,left_length);
if (right_length >= 2)
QuickSort(array + left_length + 1,right_length);
return;
}
归并排序
归并排序原理图
代码实现
void memeryArray(int *a, int first, int mid, int last, int *temp)
{
int i = first, j = mid + 1;
int m = mid, n = last;
int k = 0;
while (i <= m && j <= n)
{
if (a[i] <= a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}
while (i <= m)
temp[k++] = a[i++];
while (j <= n)
temp[k++] = a[j++];
for (i = 0; i < k; i++)
a[first + i] = temp[i];
}
void mergeSort(int *array, int first, int last, int *tmp)
{
if (first < last)
{
int mid = (first + last) / 2;
mergeSort(array, first, mid, tmp);
mergeSort(array, mid + 1, last, tmp);
memeryArray(array, first, mid, last, tmp);
}
}
bool MergeSort(int a[], int n)
{
int *p = new int[n];
if (p == NULL)
return false;
mergeSort(a, 0, n - 1, p);
delete[] p;
return true;
}
时间复杂度比较
排序方法 | 时间复杂度 |
---|---|
冒泡排序 | |
选择排序 | |
插入排序 | |
快速排序 | |
归并排序 |