在面试或者数据结构相关的考试中,经常会被要求到的算法主要有插入排序、冒泡排序、归并排序和快速排序。对这几种算法,不但应该知道其原理或者过程,还应该对他们的各种特性了然于胸,从最好、最差、平均时间空间复杂度等方面对比其优劣。在面试中这几种排序算法也会经常作为手写代码能力的考量,所以应该要求自己对这几种算法的代码信手拈来。所以在此把几种算法详细记录一下。
冒泡排序
/***********冒泡排序************
空间复杂度:O(1)
时间复杂度:有序的时候最好情况为O(n),最坏和平均为O(n^2)
稳定性:稳定
*/
void bubbleSort(int *arr, int n){
for(int i = 1; i<n; i++){
int j = i-1;
while(j>=0){
if(arr[j] > arr[j+1]){
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
j--;
}
else break;//本趟遍历没有发生交换
}
}
}
快排
//http://blog.csdn.net/morewindows/article/details/6684558 挖坑排序
void quick_sort(int s[], int l, int r)
{
if (l < r)
{
int i = l, j = r, x = s[l];
while (i < j)
{
while(i < j && s[j] >= x) // 从右向左找第一个小于x的数
j--;
if(i < j)
s[i++] = s[j];
while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数
i++;
if(i < j)
s[j--] = s[i];
}
s[i] = x;
quick_sort(s, l, i - 1); // 递归调用
quick_sort(s, i + 1, r);
}
}
插入排序
/***********折半插入排序*************
相对于直接插入排序,它在查找的时候用
折半查找,减少了比较的次数,但是移动
的次数不变,还是n平方
空间复杂度:O(1)
时间复杂度:O(n^2)
稳定性:稳定
************************************/
void insertSortBi(int *arr, int n){
int i, j, low, mid, high;
for(i = 2; i<=n; i++){
arr[0] = arr[i];//arr[0]为哨兵,不存放元素
low = 1; high = i-1;
//折半查找,减少了比较次数
while(low <= high){
mid = (low+high)/2;
if(arr[mid] > arr[0]) high = mid-1;
else low = mid + 1;
}
//向后移动元素
for(j = i-1; j>=high+1; --j)
arr[j+1] = arr[j];
arr[high+1] = arr[0];
}
//打印元素
//for(int k = 0; k<6; k++)
//cout<<arr[k]<<endl;
}
堆排序
//从i节点开始调整,从0开始计数,len为节点总数
void MinHeapFixdown(int a[], int i, int n)
{
int j, temp;
temp = a[i];
j = 2 * i + 1;
while (j < n)
{
if (j + 1 < n && a[j + 1] < a[j]) //在左右孩子中找最小的
j++;
if (a[j] >= temp)
break;
a[i] = a[j]; //把较小的子结点往上移动,替换它的父结点
i = j;
j = 2 * i + 1;
}
a[i] = temp;
}
//构建小根堆
void buildMinHeap(int arr[], int len)
{
for(int i = len/2-1; i>=0; i--)
//把第i个元素向下调整(如果大于子节点的话)
MinHeapFixdown(arr, i, len);
}
/***********堆排序*******
堆排序需要先对线性表中的元素构建堆,然后根据堆的性质,
输出堆顶元素,然后对输出堆顶后被破坏的堆重新调整为堆,
如此重复,直到堆中仅剩下一个元素位置
空间复杂度:O(1)
时间复杂度:最好最坏和平均情况下都为O(nlogn)
稳定性:不稳定
*/
void heapSort(int arr[], int n)
{
//构建小根堆,小根堆的排序后是从大到小的顺序
buildMinHeap(arr, n);
for(int i = n-1; i>0; i--){
swap(arr[i], arr[0]);
MinHeapFixdown(arr, 0, i);
}
}