South Mail algorithm Analysis and experiment design 1 divide and conquer

Source: Internet
Author: User
Tags strcmp tidy

Divide


Experimental Purpose:

Understand the algorithm thought of divide-and-conquer method, read the realization of some program code and good program in the book, deepen the understanding of the algorithm principle and realization process of divide and conquer method.

Experimental content:

The two-way combined sorting and high-speed ordering of a set of unordered sequences are realized by divide-and-conquer method. Requires a clear combination of sorting and high-speed sequencing of the basic principles, the programming implementation of the two methods of the input of an unordered sequence of ordered sequence after the output.


Code:

#include <iostream> #include <cstdlib> #include <ctime>using namespace std;void Swap (int &a, int & AMP;B) {int t = A;a = B;b = t;} Template <class t>class sortablelist{public:sortablelist (int m) {n = m;} void MergeSort (), void Merge (int left, int mid, Int. right), void QuickSort (), void Input (), void Init (), void Output ();p rivate : int rpartition (int left, int right), int Partition (int left, int right), void mergesort (int left, int right), void QuickSort (int left, int. right); T l[1000];//input array value T a[1000];//the actual sort object int n;}; Template<class t>void Sortablelist<t>::input () {for (int i = 0; i < n; i++) cin >> l[i];} The function of the Init () function is to restore the sequence to the initial sequence at the end of the two merge sorts//and then the high-speed sort template<class t>void sortablelist<t>::init () {for (int i = 0; I < n; i++) A[i] = L[i];} Template<class t>void Sortablelist<t>::output () {for (int i = 0; i < n; i++) cout << a[i] << ""; c Out << Endl << Endl;} Two-way combined sort Template<class t>void Sortablelist<t>::merGesort () {mergesort (0, n-1);} Template<class t>void sortablelist<t>::mergesort (int left, int. right) {if (left < right) {int mid = (left + ri ght)/2; MergeSort (left, mid); MergeSort (mid + 1, right); Merge (left, Mid, right);}} Template <class t>void sortablelist<t>::merge (int left, int mid, Int. right) {t* temp =new t[right-left + 1];i NT i = left, J = mid + 1, k = 0;while ((i <= mid) && (J <= right)) if (A[i] <= a[j]) Temp[k + +] = a[i ++];elset    Emp[k + +] = a[j + +];    while (I <= mid) Temp[k + +] = a[i + +];    while (J <= right) Temp[k + +] = a[j + +]; for (i = 0, k = left; k <= right;) A[k + +] = temp[i + +];} High-speed Sort template <class t>int sortablelist<t>::rpartition (int left, int. right) {Srand ((unsigned) time (NULL)) ; int i = rand ()% (right-left) + left; Swap (A[i], a[left]); return Partition (left, right);} Template <class t>int sortablelist<t>::P artition (int left, int. right) {int i = left, J = right + 1;do{do i + +; while (A[i] < A[left]);d o J--;while (A[j] > A[left]), if (i < j) Swap (A[i], a[j]);} while (I < j); Swap (A[left], a[j]); return J;} Template <class t>void sortablelist<t>::quicksort (int left, int.) {if (left < right) {int J = rpartition (left, right); QuickSort (left, j-1); QuickSort (j + 1, right);}} Template<class t>void Sortablelist<t>::quicksort () {QuickSort (0, n-1);} int main () {int m;cout << "array length n:"; cin >> m; Sortablelist<int> List (m); cout << "input" << m << "number:" << Endl; List.input (); List.init ();//Get Initial state list.mergesort (); cout << "Two-way merge:" << Endl; List.output (); List.init ();//Restore Initial state cout << "after high speed sequencing:" << Endl; List.quicksort (); List.output (); return 0;}


Compare the two:

Problem decomposition Process:

Merge sort--divides the sequence into a double. (Very simple)

High-speed sequencing-Call the Partition function to divide a sequence into sub-sequences. (Decomposition method is relatively difficult)

The solution of the sub-problem is solved by the solution of the original problem:

Merge sort--you need to call the merge function to implement it. (Merge function time complexity O (n))? High-speed sequencing-once the left and right two sub-sequences have been sorted separately, the entire sequence naturally becomes an ordered sequence. (surprisingly simple, almost no additional work, eliminating the problem of the solution from the sub-problem to get the original solution of the process)

Study Questions

1, in the operation of the above-mentioned high-speed sequencing algorithm, the operation of the tracking program will find that if the initial input sequence is reduced order, the call Partition function for the division operation, subscript I to the right to look for greater than or equal to the reference element in the process will produce subscript out of bounds, why? How to change the program, To avoid the occurrence of such a situation?

A: This is because the original program on the right side of the sequence does not have a maximum value as a sentinel, the subscript I in the right to look for a value greater than or equal to the datum element, has not satisfied the condition of the element values, has not stopped until the bounds.

So just reserve a sentinel element at the end of the sequence and set its value to a maximum value. For example, Int_max can solve

2. Analyze the time complexity of the two sorting algorithms in the best, worst and average cases.

Two-way merge sort: Best, worst, average time complexity is O (NLOGN).

High-speed sequencing: The best, average time complexity is O (Nlogn), and the worst case is O (N2).

3, when the initial sequence is ascending or descending order, by improving the selection method of the main element (datum elements), it can improve the efficiency of high-speed sorting algorithm execution, and avoid the worst-case occurrence.

There are three ways to select the main elements. One is to take K (Left+right)/2 as the main element;

The second is to take the random integer j between Left~right and Kj as the principal element;

Three is to take Kleft, K (left+right)/2 and kright of the middle value of the main element.

The experimental procedure takes a different approach.



Example segment tree by divide-and-conquer method

When it comes to divide and conquer the first thought is definitely a binary search. As well as high-speed sequencing, two-way combined sorting, these are classic algorithms for solving this problem by using the divide-and-conquer strategy. What I'm going to introduce is a very handy data structure with the idea of division and administration--line tree

Segment tree is essentially a binary search tree, it is very convenient to conquer a very multi-interval operation problem. The segment tree is both a segment and a tree. Each node is a line segment, each segment of the left and right of the son segment of the line is the first half of the segment, and after the recursive definition is a line tree, first we need to know what this data structure with what to store, usually using a struct array:

struct tree//tree struct {int left, right; The tree's left and right subtree}tree[max];//max are usually set to 4 times times the number of nodes

now take a look at some of the functions in the base segment tree:

1. The build function, as the name implies, is a function that allows us to build a tree of line segments.

void Build (int l, int r, int step)//Achievements, step represents tree node number (below) {tree[step].left = l;    Assignment tree[step].right = r;    if (l ==r)//l = = R when the description extends to the leaf node, returns return;   int mid = (L + r) >> 1;        Two-point Build (L,mid, step<<1);  Recursive left subtree Build (Mid+1,r, (step<<1) +1); Recursive right sub-tree}

2. Update function. Used to update line segment trees

void Update (int l, int r, int value, int step) {if (tree[step].left== tree[step].right)//has been updated to leaf node returns return;    int mid = (Tree[step].left +tree[step].right) >> 1;    Assuming that the right endpoint of the point to be updated is less than mid or the left endpoint is greater than mid, then directly update the value of L to R if (r <= mid) update (l,r, value, step<<1);    else if (l> mid) Update (L,r, Value, (step<<1) +1);        Assuming that the point you want to update is on both sides of mid, update the else {update (L, Mid, Value, step<<1) separately on both sides;    Update (mid+1, R, Value, (step<<1) +1); }}

3. Query function, for querying interval values

int Query (int l, int r, int step) {//Find leaves return value if (l = = Tree[step].left && r ==tree[step].right) Retu    RN Tree[step]. value;    int mid = (Tree[step].left +tree[step].right) >> 1; Queries and updates are similar.    All are segmented operations if (R <=mid) return Query (L, R, Step<<1);    if (l >mid) return Query (L, R, (step<<1) +1); else return Query (L, Mid, step<<1) +query (mid+1, R, (step<<1) +1);}


The above three functions form the basic structure of the segment tree. We can see very clearly the idea of division and treatment. There are very many line-segment trees. For example, the value of a single point of update and the value of the interval update, and so on, we are here through an example of the simplest of the line segment tree application and line tree single point update, as the name implies, each time just update the value of a node to see this problem, from Hduoj 1166

Enemy soldiers

Problem Description

C State of the death of a country during this period of military exercises, so C State spy head Derek and his men tidy again began busy. Country A has a line of N engineering camps along the coastline, and Derek and tidy are tasked with monitoring the activities of these engineering camps. Because of some kind of advanced monitoring method. So the number of people in every engineering camp is clear, and the number of each engineering camp is likely to change, possibly adding or lowering a number of people, but these are just the surveillance of State C.
The CIA wants to study what tactics the enemy is practicing, so Tidy to report to Derek at any time about how many people there are in a continuous corps of engineers, such as Derek: "Tidy, immediately report to the 3rd camp to the 10th camp together how many people!" Tidy will immediately begin to calculate the total number of this section and report it. But the number of enemy barracks often changes, and Derek every time asked the paragraph is different. So tidy had to go to a camp every time to count, very quickly exhausted. Derek is increasingly dissatisfied with tidy's computational speed: "You're a dead fat boy, so slow, I'll fire you!" Tidy thought, "You can count on yourself, it's a tiring job!" I wish you would fire me! " Helpless under, tidy just good call to computer expert windbreaker for help, Windbreaker said: "Dead Fat Boy, call you usually do more ACM problem and see more points count the book." Now I have tasted the bitter fruit! " Tidy said: "I know the wrong ... "But Windbreaker already hung up the phone." Tidy very distressed, so he really will collapse, smart reader. Can you write a program to help him finish the work? Just assuming your program is not efficient enough, tidy will still be scolded by Derek.

Input

The first line is an integer t, which indicates that there is a T group of data.
The first line of each group of data is a positive integer n (n<=50000), indicating that the enemy has N engineering camps, followed by n positive integers, and the second positive integer AI represents the AI individual (1<=ai<=50) at the beginning of the field of the First battalion.
Next, there is one command in each line, with 4 forms of command:
(1) Add I j,i and J are positive integers, indicating that I camp add J person (J not more than 30)
(2) Sub i J, I and J are positive integers, indicating that the I camp lowers J person (J not more than 30);
(3) Query i J, I and J are positive integers, i<=j, which indicate the total number of persons who have inquired about the first and the J camps;
(4) End indicates that the command ends in each group of data;
Up to 40,000 commands per set of data

Output

For group I data, first output "case I:" and carriage return,
For each query, output an integer and enter it to indicate the total number of people in the segment you are asking for, which remains within Int.

Sample Input

1

10

1 2 3 4 5 6 7 8 9 10

Query 1 3

ADD 3 6

Query 2 7

Sub 10 2

ADD 6 3

Query 3 10

End

Sample Output

Case 1:

6

33

59

Topic Analysis: Test instructions very easy, is to give a range has three operations. Add indicates the number of people, the sub represents the decrement, and the query indicates how many people are in the search interval. For such a range of update query class problems. You can think of the line tree described above, the basic operation of the section will not write staring. As described above, see the AC code below

#include <cstdio> #include <cstring>int const MAX = 400000 + 10;struct tree     & nbsp;     //tree structure {    int left, right;     //tree Trees      int sum;            //tree values}tree[max];void Build (int l, int r, int step)  //Achievements, step represents the tree node number (below are) {    tree[step].left = l;         Tree[step].right = r;    tree[step].sum = 0;    if (L = = r)    //l = = r when the description stretches to Leaf node, return         return;    int mid = (L + R) >> 1;  //two points achievement &n bsp;   build (L, Mid, step<<1);    build (mid+1, R, (step<<1) +1);} void Update (int l, int r, int value, int step)  //update function {    tree[step].sum + = value;  //due to this Is the sum, so the number of points that are traversed directly is added to the value     if (tree[step].left = = Tree[steP].right)   //Update to leaf node return         return;    int mid = (tree[ Step].left + tree[step].right) >> 1;    if (R <= Mid)   //Assuming the right endpoint of the point to be updated is less than mid, Then directly update the values of L to R         update (L, R, Value, step<<1);    else if (L > MID)  //Assuming that the left endpoint of the point to be updated is greater than mid, then directly update the value of L to R     //Note that the above cannot be written r<mid and L>=mid are determined by the nature of the tree. Readers can draw to see         update (L, R, Value, (step<<1) +1);    else // Assuming that the point you want to update is on either side of mid, update the sides separately     {        update (L, Mid, value, step<<1 );        update (mid+1, R, Value, (step<<1) +1);    }}int Query (int l, int r, int step)  //Query function {    if (l = = Tree[step].left && r = = tree[step].right)//Find leaves return to leaf value & nbsp;       return tree[step].sum;    int mid= (Tree[step].left + tree[step].right) >> 1;//Similar update steps below, no longer elaborated     if (R <= mid)     & nbsp;   return Query (l, R, step<<1);    if (L > Mid)        & Nbsp;return query (L, R, (step<<1) +1);    else        return query ( L, Mid, step<<1) + Query (mid+1, R, (step<<1) +1);} int main () {    int t;    int A, B, n;    char cmd[6];     scanf ("%d", &t);    for (int i = 1; I <= T; i++)     {       & NBSP;SCANF ("%d", &n);         build (1,n,1); //1-n achievements         for (int j = 1; j <= N; J + +)         {            int temp;             scanf ("%d", &temp);             update (j,j,temp,1);  //update from ROOT to leaf          }        printf ("Case%d:\n", i);        while (scanf ("%s", cmd)! = EOF && strcmp (cmd, "End")! = 0)         {             scanf ("%d%d", &a, &b);            if (strcmp (cmd, "Query") = = 0)                  printf ("%d\n", Query (a,b,1));            else if (strcmp ( CMD, "Add") = = 0)  //plus the value of B is positive                 update ( a,a,b,1);            else if (strcmp (cmd, "Sub") = = 0)  //minus when the value of B is negative                 update (a,a,-b,1);        }    }} 

Through the concept of the line segment tree and the introduction of a single-point update, we can very clearly feel that it will be divided into the use of ideas, the problem through the form of a binary tree directly into a number of sub-zones, each interval completed corresponding updates, and finally summed up the question of the answer



South Mail algorithm Analysis and experiment design 1 divide and conquer

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.