冒泡排序
冒泡排序是一种稳定的排序。
代码
void bubble(int *a, int n){
int tmp;
for(int i = 0; i < n; i ++){
for(int j = i + 1; j < n; j ++){
if(a[i] > a[j]){
tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
}
}
优化版
优化的目的在于减少不必要的比较
void bubble(int *a, int n){
int flag = 0, tmp;
for(int i = 0; i < n - 1; i ++){
flag = 0;
for(j = n - 1; j > i; j --){
if(a[j - 1] > a[j]){
tmp = a[j - 1];
a[j-1] = a[j];
a[j] = tmp;
flag = 1;
}
}
if(flag == 0){
return;
}
}
}
快速排序
严奶奶认为快速排序是性能比较优秀的内部排序
- 时间复杂度最好O(nlog(n)),最坏O(n^2)
- 最好O(log(n)),最坏O(n)
- 稳定的性,不稳定
- 基本思想 分治思想:在待排序表中任选一个元素pivot作为枢轴,通过一趟排序将待排序表划分成独立的两部分,使其左半部分的元素都小于pivot,右半部分的元素都大于等于pivot,则pivot已就位,这个过程称为一趟快速排序。然后分别递归的对两个子表重复上述过程,直到每部分内只有一个元素为止,即所有元素到达最终位置上。
代码实现
int partition(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) return;
int pivot;
pivot = partition(a, low, high);
quickSort(a, low, pivot - 1);
quickSort(a, pivot + 1, high);
}
快速查找数组的第k大元素
在快速排序中,经过一趟排序后,pivot元素将就位,将pivot元素所在位置pos与k比较,如果pos等于k,则pivot就是第k大元素,如果pos比k小,则说明第k大元素在分区的右边,否则在左边。理想情况下,算法的查找效率与二分查找相似,算法的时间复杂度为O(log(n));
代码实现
int partition(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;
}
int findKTh(int *a, int low, int high, int k){
if(k > n) return -1;
int pivot = partition(a, low, high);
int pos = pivot + 1;
if(pos == k){
return a[pivot];
}else if(pos > k){ //在pivot的左边
return findKTh(a, low, pivot - 1, k);
}else{//在pivot的右边
return findKTh(a, pivot + 1, high, k);
}
}