排序
STL
1 | bool compare(your_own_node a, your_own_node b) { |
排序不简单
应该有很多选手和我一样,虽然名义上学过排序,但到了考场就只会一行代码:1
sort(a + 1, a + n + 1, cmp);
不要说快速排序了,连冒泡都不一定打得出完整的。统计逆序对也不会归并,只会用树状数组+离散化(烦得要死)甚至干脆用冒泡跑暴力。
直到下一届的新生开始学排序,我才发现:我甚至连快排都不会!
今天,就以模板题P1177来扒一扒,怎么写出又快又简洁的快速排序。
基础算法
1 | void qsort(int l, int r) { |
似乎这么打就能过了。但让我一直不解的是,用《算法导论》上的代码,死活都过不了。如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20int Partition(int *arr, int beg, int end) {
int sentinel = arr[end];
int i = beg - 1;
for(int j = beg; j <= end - 1; ++j) {
if(arr[j] <= sentinel) {
i++;
swap(arr[i], arr[j]);
}
}
swap(arr[i+1], arr[end]);
return i+1;
}
void QuickSort(int *arr, int beg, int end) {
if(beg < end) {
int pivot = Partition(arr, beg, end);
QuickSort(arr, beg, pivot-1);
QuickSort(arr, pivot+1, end);
}
}
即使是加了随机化,仍然慢的要死,甚至递归到爆栈。
下了一个数据点,简直被吓死。看一下这数据的险恶:
1 | 100000 99999 99998 99997 99996 99995 99994 99993 99992 99991 99990 99989 99988 99987 99986 99985 99984 99983 99982 99981 99980 99979 99978 99977 99976 99975 99974 99973 99972 99971 99970 99969 99968 99967 99966 99965 99964 99963 99962 99961 99960 99959 99958 99957 99956 99955 99954 99953 99952 99951 99950 99949 99948 99947 99946 99945 99944 99943 99942 99941 99940 99939 99938 99937 99936 99935 99934 99933 99932 99931 99930 99929 99928 99927 99926 99925 99924 99923 99922 99921 99920 99919 99918 99917 99916 99915 99914 99913 99912 99911 99910 99909 99908 99907 99906 99905 99904 99903 99902 99901 99900 99899 99898 99897 99896 99895 99894 99893 99892 99891 99890 99889 99888 99887 99886 99885 99884 99883 99882 99881 99880 99879 99878 99877 99876 99875 99874 99873 99872 99871 99870 99869 99868 99867 99866 99865 99864 99863 99862 99861 99860 99859 99858 99857 99856 99855 99854 99853 99852 99851 99850 99849 99848 99847 99846 99845 99844 99843 99842 99841 99840 99839 99838 99837 99836 99835 99834 99833 99832 99831 99830 99829 99828 99827 99826 99825 99824 99823 99822 99821 99820 99819 99818 99817 99816 99815 99814 99813 99812 99811 99810 99809 99808 99807 99806 99805 99804 99803 99802 99801 99800 99799 99798 99797 99796 99795 99794 99793 99792 99791 99790 99789 99788 99787 99786 99785 99784 99783 99782 99781 99780 99779 99778 99777 99776 99775 99774 99773 99772 99771 99770 99769 99768 99767 99766 99765 99764 99763 99762 99761 99760 99759 99758 99757 99756 99755 99754 99753 99752 99751 99750 99749 99748 99747 99746 99745 99744 99743 99742 99741 99740 99739 99738 99737 99736 99735 99734 99733 99732 99731 99730 99729 99728 99727 99726 99725 99724 99723 99722 99721 99720 99719 99718 99717 99716 99715 99714 99713 99712 99711 99710 99709 99708 99707 99706 99705 99704 99703 99702 99701 99700 99699 99698 99697 99696 99695 99694 99693 99692 99691 99690 99689 99688 99687 99686 99685 99684 99683 99682 99681 99680 99679 99678 99677 99676 99675 99674 99673 99672 99671 99670 99669 99668 99667 99666 99665 99664 99663 99662 99661 99660 99659 99658 99657 99656 99655 99654 99653 99652 99651 99650 99649 99648 99647 99646 99645 99644 99643 99642 99641 99640 99639 99638 99637 99636 99635 99634 99633 99632 99631 99630 99629 99628 99627 99626 99625 99624 99623 99622 99621 99620 99619 99618 99617 99616 99615 99614 99613 99612 99611 99610 99609 99608 99607 99606 99605 99604 99603 99602 99601 99600 99599 99598 99597 99596 99595 99594 99593 99592 99591 99590 99589 99588 99587 99586 99585 99584 99583 99582 99581 99580 99579 99578 99577 99576 99575 99574 99573 99572 99571 99570 99569 99568 99567 99566 99565 99564 99563 99562 99561 99560 99559 99558 99557 99556 99555 99554 99553 99552 99551 99550 99549 99548 99547 99546 99545 99544 99543 99542 99541 99540 99539 99538 99537 99536 99535 99534 99533 99532 99531 99530 99529 99528 99527 99526 99525 99524 99523 99522 99521 99520 99519 99518 99517 99516 99515 99514 99513 99512 99511 99510 99509 99508 99507 99506 99505 99504 99503 99502 99501 99500 99499 99498 99497 99496 99495 99494 99493 99492 99491 99490 99489 99488 99487 99486 99485 99484 99483 99482 99481 99480 99479 99478 99477 99476 99475 99474 99473 99472 99471 99470 99469 99468 99467 99466 99465 99464 99463 99462 99461 99460 99459 99458 99457 99456 99455 99454 99453 99452 99451 99450 99449 99448 99447 99446 99445 99444 99443 99442 99441 99440 99439 99438 99437 99436 99435 99434 99433 99432 99431 99430 99429 99428 99427 99426 99425 99424 99423 99422 99421 99420 99419 99418 99417 99416 99415 99414 99413 99412 99411 99410 99409 99408 99407 99406 99405 99404 99403 99402 99401 99400 99399 99398 99397 99396 99395 99394 99393 |
1 | 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 50000 |
这跑个屁呀!
分析一下就可以发现,《算法导论》中的算法选取的是最右端的数作为基准,所以面对完全相同的数据,即使随机化,所有的数也都落在基准的一侧,直接退化为 \(O(n^2)\) 。所以,要想快排写的快,取中间的数做基准。
归并排序 & 逆序对
逆序对是满足 \(i < j\) 且 \(a_i > a_j\) 的有序数对 。
我们可以发现,归并排序中将两个数组合并时,较靠后的数组每被取出一个数,意味着它和较靠前的数组剩下的所有数都产生了逆序对。而且容易发现,这样的统计是不重不漏的。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15int a[maxn], b[maxn];
long long sum; /*****long long is important!*****/
void merge_sort(int l, int r) {
if (l >= r) return;
int mid = (l + r) >> 1;
merge_sort(l, mid);
merge_sort(mid + 1, r);
for (int i = l; i <= r; i++) b[i] = a[i];
int i = l, j = mid + 1;
for (int k = l; k <= r; k++) {
if (j > r || (i <= mid && b[i] <= b[j])) a[k] = b[i++]; /*****<= is important*****/
else a[k] = b[j++], sum += mid - i + 1;
}
}