voidquick_sort(int q[], int l, int r)//l指向最左边,r指向最右边 { if (l >= r) return;//当l和r跑到一起时,结束运行,即只有一个数据或没有数据,就不需要排序
int i = l - 1, j = r + 1, x = q[l + r >> 1];//因为下面的代码不管判断先进行一次挪位,所以i和j要往外一位,确保能扫到所有的数 while (i < j)//x为分割点,>>1相当于/2 { do i ++ ; while (q[i] < x);//比x小的放左边 do j -- ; while (q[j] > x);//比x大的放右边 if (i < j) swap(q[i], q[j]);//此时i和j都停在不符合条件的地方,用swap把值互换 } quick_sort(q, l, j), quick_sort(q, j + 1, r);//用递归对左边和右边的数据进行多次分割 }
#include<iostream> usingnamespace std; int n; constint N = 1e6 + 10; int q[N]; voidquick_sort(int q[], int l,int r){ if (l >= r) { return; } int i = l - 1; int j = r + 1; int x = q[l]; while (i<j) { do i++; while (q[i] < x); do j--; while (q[j] > x); if (i < j) { swap(q[i], q[j]); } } quick_sort(q,l,j); quick_sort(q, j + 1, r); } intmain(){ cin >> n; for (int i = 0; i < n; i++) { cin >> q[i]; } quick_sort(q, 0, n - 1); for (int i = 0; i < n; i++) { cout << q[i]<<" "; } return0; }
归并排序
确定分界点$(l+r)>>1$
递归排序左边和右边
归并————把两个有序的数组合并成一个有序的数列,即合二为一
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
voidmerge_sort(int q[], int l, int r)//left和right { if (l >= r) return;//只有一个数据或没有数据,就不需要排序
int mid = l + r >> 1;//取中间, 确定分界点 merge_sort(q, l, mid);//递归,排序右边 merge_sort(q, mid + 1, r);//递归,排序左边
int k = 0, i = l, j = mid + 1;//k表示两个数组合并了几个数,i是指向左半边的起点,j是指向右半边的起点 while (i <= mid && j <= r)//i小于左半边的边界,j小于右半边的边界 if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];//左半边最小值小于右半边最小值时,用一个临时数组存储左半边 else tmp[k ++ ] = q[j ++ ];//即把最小的存到临时数组
while (i <= mid) tmp[k ++ ] = q[i ++ ];//左半边没有循环完,就把左半边剩下的存到临时数组里 while (j <= r) tmp[k ++ ] = q[j ++ ];//同上
for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];//把临时数组里存放的数据还到需要排序的数组里 }
#include<iostream> usingnamespace std; constint N=100010; int n, m;//n是数组长度,m是询问个数 int q[N];
intmain() { cin >> n >> m;//n是数组长度,m是询问个数 for (int i = 0; i < n; i++) { cin >> q[i]; } while (m--)//一共有m个询问 { int x; cin >> x;//x是要查询的数字 int l = 0, r = n - 1; while (l < r) { int mid = l + r >> 1; if (q[mid] >= x)r = mid;//有序数组的中间值比找的数组值x大或者等于,说明x在l和mid之间,即[l.mid],因此把右边界改为mid else l = mid + 1;//有序数组的中间值比找的数组值x小,取不到mid,所以在[mid+1,r]中,因此把左边界改为mid+1 } if (q[l] != x)cout << "-1 -1" << endl;//检查所查找的数据x是否存在于数组中,不存在就输出-1 -1 else { cout << l << ' ';
int l = 0, r = n - 1; while (l < r) { int mid = l + r + 1 >> 1;//当l=r-1,即l和r仅仅相差一位,如果不+1,mid会等于l if (q[mid] <= x)l = mid;//这里就会变成l=mid=l,陷入死循环 else r = mid - 1; } cout << l << endl; } } return0; }