1, Quick sort
1. Scattered knowledge points
(1) swap() function:
C + + standard library functions can exchange the values of two variables. Including: integer, string, array, stack and other array structures.
Detailed explanation of swap function
c + + has built-in swap function and header file #include < iostream >. If you re write the swap function yourself, it may conflict with the original built-in function, so you can change the function name to swap or swap1.
(2) > > bit operation
i=x+y>>1; //This is the binary value of (x+y). All bits move one bit to the right, that is, divide by 2. i = i << 2; //Shift the value in i to the left by 2 bits
A special case in shift left is that when the number of bits shifted left exceeds the maximum number of bits of the numerical type, the compiler will use the number of bits shifted left to modulus the maximum number of bits of the type, and then shift by the remainder, such as:
int i = 1, j = 0x80000000; // Set int to 32 bits
i = i << 33; // 33% 32 = 1 shifts 1 bit left, I becomes 2
j = j << 33; // 33% 32 = 1 shifts 1 bit left, J becomes 0, and the highest bit is discarded
Bit operation priority:
(3)const int N=1e6+10;
//1*10^6+10
2. Quick sort template questions
(1) AcWing 785 quick sort
Give you a length of n Integer sequence of.
Please use quick sort to sort this sequence from small to large.
And output the ordered sequence in order.
Input format
The input consists of two lines. The first line contains integers n.
The second line contains n Integers (all integers are in 1∼1091∼109 Range), representing the entire sequence.
Output format
Output a total of one line, including n An integer representing an ordered sequence of numbers.
Data range
1≤n≤100000
Input example:
5 3 1 2 4 5
Output example:
1 2 3 4 5
The first code, like y in general, takes the first element as the split point, but it can't ac. We should replace int x=p[l] with int x = P [(L + R) > > 1], because in the given case, most elements are arranged in positive order, and the execution times of swap function can be ignored. If you take the first element, most of the subsequent elements are larger than the first element, so the i pointer (the one moving from left to right) will stop almost every time it moves to exchange elements. The execution times of swap function are close to n/2.
#include<iostream> #include<stdio.h> using namespace std; const int N=1e6+10; void quick_sort(int p[],int l,int r){ if(l>=r) return;//Excluding the number of elements 1 and 0, I forgot to write it for the first time int x=p[l],i=l-1,j=r+1;//In this place, you can ac only replace int x=p[l] with int x = P [(L + R) > > 1]. For the case of this topic, the time complexity is less while(i<j){ do i++;while (p[i]<x); do j--;while (p[j]>x); if(i<j) swap(p[i],p[j]); } //It is divided into two parts, and then recursion is continued until all elements are arranged in order quick_sort(p,l,j); quick_sort(p,j+1,r); } int main (){ int n; int p[N]; scanf("%d",&n); //Input array for(int i=0;i<n;i++) scanf("%d",&p[i]); quick_sort(p,0,n-1); //Output array for(int i=0;i<n;i++) printf("%d ",p[i]); }
The following case will not pass
100000 15915 16204 16772 39929 49780 54646 77889 95421 99907 111172 121952 122706 124731 131398 139760 148589 155181 170780 175583 188205 212376 217320 221990 232051 239426 248803 254604 254673 264967 268169 269199 276115 300535 320678 326159 343556 360571 364829 371381 377226 382586 384554 392322 424697 431253 445607 458868 461257 462269 462718 471566 495039 500714 531706 535351 546189 598985 605570 608169 613225 620863 621772 621961 622137 627701 630193 640276 649408 681872 696496 699171 701757 720370 721454 734730 737943 763532 770863 777830 798750 807871 813234 815923 817637 818637 848772 854192 859020 863563 869743 891206 906042 911164 927131 934261 937119 942289 978503 998519 1012979 1097505 1098574 1100041 1108883 1120574 1122034 1127503 1135396 1154850 1168703 1180078 1201147 1220407 1220776 1225060 1226999 1234379 1245895 1250079 1265821 1267700 1273550 1273763 1273926 1283855 1307052 1341878 1347086 1359513 1394362 1408506 1414060 1420067 1427682 1440646 1442642 1451958 1453582 1471274 1494703 1502278 1516591 1529917 1540677 1569316 1592346 1606577 1608654 1624278 1627103 1630514 1630737 1636008 1640086 1646308 1649628 1666459 1667332 1667807 1685189 1699255 1706371 1707828 1709570 1742037 1747728 1752040 1759841 1760306 1760735 1767907 1776488 1791896 1800481 1807411 1810027 1814428 1815449 1822032 1823800 1846352 1854440 1861090 1870495 1882156 1886069 1892128 1901710 1908498 1917505 1926331 1944882 1947042 1956168 1958502 1998742 2020980 2025295 2048831 2055746 2056233 2057170 2059619 2066864 2067131 2080478 2082421 2091404 2100097 2121441 2145666 2171123 2195198 2198673 2201081 2203998 2221169 2225421 2234497 2245383 2250376 2255023 2256200 2262075 2278943 2280415 2303991 2307401 2308518 2322320 2324184 2329125 2333602 2343849 2349531 2353410 2380408 2383118 2385012 2395403 2408273 2425489 2430119 2432622 2437419 2444271 2458042 2469823 2471846 2475428 2481559 2482620 2498788 2503102 2512559 2513103 2519955 2521968 2536834 2548583 2550327 2553713 25...
3. Time complexity:
Worst case: O(N2)
Best case and average case: O(NlogN)
2, Merge sort
1. Scattered knowledge points
(1) Stable sort and unstable sort
Merge sort is stable, while quick sort is unstable. Generally speaking, it can ensure that the sequence of the first two equal numbers in the front and back of the sequence is the same as that after sorting.
- Stable sorting: bubble, insert, merge
- Unstable sort: select, hill, quick sort (stable but difficult), heap sort
Example of unstable quick sort: 3 (1) 3(2) one four five --> one 3(2) 3(1) four five // (1) (2) used to mark
The way to make quick sort stable is that all elements in the quick sort are different.
2. Merge and sort template questions
Give you a length of An integer sequence of n.
Please use merge sort to sort this sequence from small to large.
And output the ordered sequence in order.
Input format
The input consists of two lines. The first line contains integers n.
The second line contains n Integers (all integers are in 1∼1091∼109 Range), representing the entire sequence.
Output format
Output a total of one line, including n An integer representing an ordered sequence of numbers.
Data range
1≤n≤100000
Input example:
5 3 1 2 4 5
Output example:
1 2 3 4 5
#include<iostream> using namespace std; const int N=1e6+10; int p[N],tmp[N]; void merge_sort (int p[],int l,int r){ if(l>=r) return; int mid=l+r>>1; merge_sort(p,l,mid),merge_sort(p,mid+1,r); int i=l,j=mid+1,k=0;//This line of statements can also be placed before recursion without affecting the result while(i<=mid&&j<=r) if(p[i]<=p[j]) tmp[k++]=p[i++]; else tmp[k++]=p[j++]; //The first time I forgot, if one of the arrays has been traversed, I just need to store the other array in turn while(i<=mid) tmp[k++]=p[i++]; while(j<=r) tmp[k++]=p[j++]; for(i=l,j=0;i<=r;i++,j++) p[i]=tmp[j]; } int main(){ int n; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&p[i]); merge_sort(p,0,n-1); for(int i=0;i<n;i++) printf("%d ",p[i]);//When submitting, you should add spaces, otherwise the format is wrong }
3. Time complexity:
O(NlogN) // The analysis process is similar to quick sort
3, Binary search (integer)
1. Diagram of core ideas
2. Binary search template question
Given a length in ascending order is An integer array of n, and q Queries.
For each query, one element is returned k Start and end positions of (from 0 Start counting).
Returns if the element does not exist in the array - 1 -1.
Input format
The first line contains integers n and q. Represents the length of the array and the number of queries.
The second line contains n Integers (all in 1 ∼ 10000 range), indicating the complete array.
next q Rows, each containing an integer k. Represents a query element.
Output format
common q Line, each line contains two integers, indicating the starting position and ending position of the element.
Returns if the element does not exist in the array - 1 -1.
Data range
1≤n≤100000
1≤q≤10000
1≤k≤10000
Input example:
6 3 1 2 2 3 3 4 3 4 5
Output example:
3 4 5 5 -1 -1
#include<iostream> using namespace std; const int N=1e6+10;//As long as it is greater than or equal to 1e6, the test data is just overwritten int p[N]; int main(){ int n,m; scanf("%d%d",&n,&m);//m represents the number of queries for(int i=0;i<n;i++) scanf("%d",&p[i]); while(m--){ int x; scanf("%d",&x);//x is the number to query int l=0,r=n-1; //The cycle of template 1 is performed first because it finds the position where x first appears (assuming that x exists) while(l<r){ int mid=l+r>>1;//This should be placed in the while loop, because the values of l and r will be updated every time, so the value of mid should be updated at the beginning of the loop if(p[mid]>=x) r=mid; else l=mid+1; } if(p[l]!=x) cout<<"-1 -1"<<endl; else { cout<<l<<" "; int l=0,r=n-1; while(l<r){ int mid=l+r+1>>1;//When l=mid, that is, when mid appears on the left of the interval, make mid = L + R + 1 > > 1 to prevent dead circulation if(p[mid]<=x) l=mid; else r=mid-1; } //If you enter the else statement, it indicates that x exists, so you don't need to judge whether p[l] is equal to x, just output L cout<<l<<endl; } } return 0; }
3. Time complexity
logN // Each time, regardless of whether the setting property is met or not, a bisection cutting will be carried out. When n numbers are cut into 1, the cycle ends, and the number of cutting times required is logn; Carry out the second cycle. Similarly, the total number of times is 2logN.
4, Binary lookup (floating point number)
1. Diagram of core ideas
The most important thing to pay attention to when finding the square root of a number is when the number is less than 1!!!
When x > = 1, let X be the right boundary of the dichotomy, so that it is convenient to evaluate the square root of a very large number and will not be limited because the value of the right boundary is not enough;
When x < 1, let 1 be the right boundary of the dichotomy, so that the square root of X will not be taken because it is greater than x (beyond the dichotomy range).
2. Square root template
#include<iostream> using namespace std; int main() { double x; cin>>x;//Square number double l=0,r=x; if(x<1) r=1;//This statement is very important!!! while(r-l>1e-8){//This number should be 2 more than the reserved digits required by the topic in order to meet the accuracy condition double mid=(l+r)/2;//Can floating point numbers use this double mid = L + R > > 1 if(mid*mid>=x) r=mid; else l=mid; } printf("%lf",l);//It is accurate to 6 decimal places, so it corresponds to 1e-8 in front; // %lf--->double %f--->float return 0; }
So far, the first session of y total online class has been finished
2021/11/5 22:59
-------------------------------------------------------------------------