C + + Basic algorithm bubble method, Exchange method, selection method, implementation code set _c language

Source: Internet
Author: User

1. Bubble Method:


This is the most primitive, and also known as the slowest algorithm.
The origin of his name was because its work seemed to be bubbling:

Copy Code code as follows:

#include <iostream.h>
void Bubblesort (int* pdata,int Count)
{
int itemp;
for (int i=1;i<count;i++) {
for (int j=count-1;j>=i;j--) {
if (Pdata[j]<pdata[j-1]) {
ITEMP = Pdata[j-1];
PDATA[J-1] = Pdata[j];
PDATA[J] = itemp;
}
}
}
}
void Main () {
int data[] = {10,9,8,7,6,5,4};
Bubblesort (data,7);
for (int i=0;i<7;i++)
cout<<data<< "";
cout<< "\ n";
}

Reverse (worst case)
First round: 10,9,8,7->10,9,7,8->10,7,9,8->7,10,9,8 (Exchange 3 times)
Second round: 7,10,9,8->7,10,8,9->7,8,10,9 (Exchange 2 times)
First round: 7,8,10,9->7,8,9,10 (Exchange 1 times)
Cycle times: 6 Exchange times: 6 times
Others: First round: 8,10,7,9->8,10,7,9->8,7,10,9->7,8,10,9 (Exchange 2 times)
Second round: 7,8,10,9->7,8,10,9->7,8,10,9 (Exchange 0 times)
First round: 7,8,10,9->7,8,9,10 (Exchange 1 times) Cycle times: 6 Exchange times: 3 times above we gave the program section,
Now we analyze it: here, the main part that affects the performance of our algorithms is the loop and the exchange, and obviously the more times, the worse the performance.
From the above program we can see that the number of loops is fixed, for 1+2+...+n-1. Written as a formula is 1/2* (n-1) *n.
Now notice that we give the definition of the O method: If there is a constant K and a starting point n0, so that when n>=n0, there is f (n) <=k*g (n), then f (n) = O (g (n)).
Now let's look at 1/2* (n-1) *n, when K=1/2,n0=1,g (n) =n*n, 1/2* (n-1) *n<=1/2*n*n=k*g (n). So f (n) =o (g (n)) =o (n*n).
So the complexity of our program loop is O (n*n). Look at the exchange again. From the table following the program, you can see that the loops in both cases are the same and the exchange is different.
In fact, the exchange itself has a great relationship with the order of the data source, when the data is in reverse condition, the exchange times are the same as the cycle (each cycle of judgment will be exchanged), the complexity of O (n*n).
When the data is in positive order, there will be no exchange. The degree of complexity is O (0). Be in the middle state when disorderly order. It is for this reason that we usually compare the algorithms by the number of cycles.

2. Exchange Law:

The procedure for exchanging is the clearest and simplest, which is compared and exchanged each time with the following elements of the current element one by one.

Copy Code code as follows:

#include <iostream.h>
void Exchangesort (int* pdata,int Count)
{
int itemp;
for (int i=0;i<count-1;i++)
{
for (int j=i+1;j<count;j++)
{
if (Pdata[j]<pdata)
{
itemp = PData;
PData = Pdata[j];
PDATA[J] = itemp;
}
}
}
}

void Main ()
{
int data[] = {10,9,8,7,6,5,4};
Exchangesort (data,7);
for (int i=0;i<7;i++)
cout<<data<< "";
cout<< "\ n";
}

Reverse (worst case)
First round: 10,9,8,7->9,10,8,7->8,10,9,7->7,10,9,8 (Exchange 3 times)
Second round: 7,10,9,8->7,9,10,8->7,8,10,9 (Exchange 2 times)
First round: 7,8,10,9->7,8,9,10 (Exchange 1 times)
Cycle times: 6 times
Number of exchanges: 6 times

Other:
First round: 8,10,7,9->8,10,7,9->7,10,8,9->7,10,8,9 (Exchange 1 times)
Second round: 7,10,8,9->7,8,10,9->7,8,10,9 (Exchange 1 times)
First round: 7,8,10,9->7,8,9,10 (Exchange 1 times)
Cycle times: 6 times
Number of exchanges: 3 times

From the table that runs, swapping is almost as bad as bubbling. This is true indeed. The number of cycles is also 1/2* (n-1) *n, so the complexity of the algorithm is still O (n*n). Since we cannot give all the information, we can only tell you that they are equally bad in exchange (in some cases slightly better, in some cases slightly worse). p# subtitle #e#

3. Choice of law:

Now we can finally see a little hope: Selection method, this method improves a bit of performance (in some cases) this method is similar to our artificial sorting habits: Select the smallest in the data with the first value exchange, in the saved part of the smallest and second exchange, so reciprocating.

Copy Code code as follows:

#include <iostream.h>
void Selectsort (int* pdata,int Count)
{
int itemp;
int IPos;
for (int i=0;i<count-1;i++)
{
itemp = PData;
IPos = i;
for (int j=i+1;j<count;j++)
{
if (pdata[j]<itemp)
{
ITEMP = Pdata[j];
IPos = j;
}
}
Pdata[ipos] = PData;
PData = itemp;
}
}

void Main ()
{
int data[] = {10,9,8,7,6,5,4};
Selectsort (data,7);
for (int i=0;i<7;i++)
cout<<data<< "";
cout<< "\ n";
}

Reverse (worst case)
First round:10,9,8,7-> (itemp=9) 10,9,8,7-> (itemp=8) 10,9,8,7-> (itemp=7) 7,9,8,10 (Exchange 1 times)
Second round: 7,9,8,10->7,9,8,10 (itemp=8)-> (itemp=8) 7,8,9,10 (Exchange 1 times)
First round:7,8,9,10-> (itemp=9) 7,8,9,10 (Exchange 0 times)
Cycle times: 6 times
Number of exchanges: 2 times

Other:
First round:8,10,7,9-> (itemp=8) 8,10,7,9-> (itemp=7) 8,10,7,9-> (itemp=7) 7,10,8,9 (Exchange 1 times)
Second round:7,10,8,9-> (itemp=8) 7,10,8,9-> (itemp=8) 7,8,10,9 (Exchange 1 times)
First round:7,8,10,9-> (itemp=9) 7,8,9,10 (Exchange 1 times)
Cycle times: 6 times
Number of exchanges: 3 times
Unfortunately, the algorithm needs the number of cycles is still 1/2* (n-1) *n. Therefore the algorithm complexity is O (n*n).
We came to see his exchange. Because each outer loop produces only one exchange (a minimum value). So f (n) <=n
So we have f (n) =o (n). Therefore, when the data is more chaotic, you can reduce the number of exchanges. 4. Insert Method:
The insertion method is more complex, its basic principle is to draw the card, in front of the card to find the appropriate position to insert, and then continue to the next one

Copy Code code as follows:

#include <iostream.h>
void Insertsort (int* pdata,int Count)
{
int itemp;
int IPos;
for (int i=1;i<count;i++)
{
itemp = PData;
IPos = i-1;
while ((ipos>=0) && (Itemp<pdata[ipos])
{
PDATA[IPOS+1] = Pdata[ipos];
ipos--;
}
PDATA[IPOS+1] = itemp;
}
}


void Main ()
{
int data[] = {10,9,8,7,6,5,4};
Insertsort (data,7);
for (int i=0;i<7;i++)
cout<<data<< "";
cout<< "\ n";
}

Reverse (worst case)
First round: 10,9,8,7->9,10,8,7 (Exchange 1 times) (1 cycles)
Second round: 9,10,8,7->8,9,10,7 (Exchange 1 times) (2 cycles)
First round: 8,9,10,7->7,8,9,10 (Exchange 1 times) (3 cycles)
Cycle times: 6 times
Number of exchanges: 3 times

Other:
First round: 8,10,7,9->8,10,7,9 (Exchange 0 times) (1 cycles)
Second round: 8,10,7,9->7,8,10,9 (Exchange 1 times) (2 cycles)
First round: 7,8,10,9->7,8,9,10 (Exchange 1 times) (1 cycles)
Cycle times: 4 times
Number of exchanges: 2 times

The behavioral analysis at the end of this article actually creates an illusion that this algorithm is the best in a simple algorithm, but it is not, because the number of cycles is not fixed, we can still use the O method. From the results above, it can be seen that the number of cycles f (n) <=1/2*n* (n-1) <=1/2*n*n. So its complexity is still O (n*n) (this explains, in fact, if not to show the difference between these simple sorts, the number of exchanges can still be inferred). Now look at the exchange, from the outward appearance, the number of exchanges is O (n) (deduce similar selection method), but each time we want to do with the inner loop of the same number of ' = ' operations. A normal exchange we need three times ' = ' and there's obviously a little more here, so we're wasting time. Finally, I personally think that in the simple sorting algorithm, the selection method is the best. Insert Sort

Copy Code code as follows:

#include <iostream>
using namespace Std;

void Coutstream (int a[],int n) {
for (int i=0;i!=n;i++)
cout<<a<< "";
}

void Insertsort (int a[],int n) {
int temp;
for (int i=1;i<n;i++)
{
int j=i;
Temp=a; First, save the data for position a.
while (J>0&&temp<a[j-1])
{
A[J]=A[J-1];
j--;
}
A[j]=temp;
}
}

int main ()
{
int a[5]={1,6,4,8,4};
Insertsort (a,5);//Insert Sort
Coutstream (a,5);
return 0;
}

Second, the Advanced sorting algorithm:

In the advanced sort algorithm we will only introduce this one, and at the same time I know (in the data I read) the fastest. Its work still looks like a binary tree. First we select an intermediate value middle program we use the middle value of the array, and then put smaller than it on the left, large on the right side (the specific implementation is to find from both sides, found a pair after the exchange). Then use this process on both sides (the easiest way-recursion).
1. Quick sort:

Copy Code code as follows:

#include <iostream.h>

void Run (int* pdata,int left,int right)
{
int i,j;
int middle,itemp;
i = left;
j = right;
Middle = pdata[(left+right)/2]; Find Middle Value
do{
while ((Pdata<middle) && (i<right))//left-scan is greater than the median value
i++;
while ((Pdata[j]>middle) && (j>left))//scan from right is greater than the median value
j--;
if (I<=J)//found a pair of values
{
Exchange
itemp = PData;
PData = Pdata[j];
PDATA[J] = itemp;
i++;
j--;
}
}while (I<=J)//If the subscript scanned on both sides is staggered, stop (once)

When the left part has a value (left<j), recursive left half
if (LEFT<J)
Run (PDATA,LEFT,J);
When the right part has a value (right>i), recursive right half
if (right>i)
Run (pdata,i,right);
}

void QuickSort (int* pdata,int Count)
{
Run (pdata,0,count-1);
}

void Main ()
{
int data[] = {10,9,8,7,6,5,4};
QuickSort (data,7);
for (int i=0;i<7;i++)
cout<<data<< "";
cout<< "\ n";
}

Here I do not give an analysis of behavior, because this is very simple, we directly to analyze the algorithm: First of all, we consider the ideal situation
1. The size of an array is a power of 2, which can always be divisible by 2. Suppose to be 2 K-th side, i.e. K=LOG2 (n).
2. Each time we choose a value that is just an intermediate value, the array can be divided equally.
First-level recursion, cyclic n-times, second-layer cyclic 2* (N/2) ...
So altogether n+2 (N/2) +4 (N/4) +...+n* (n/n) = N+N+N+...+N=K*N=LOG2 (n) *n
So the complexity of the algorithm is O (log2 (n) The other situation is only worse than this, the worst case is that each selection to the middle is the minimum or maximum, then he will become the Exchange method (because of the use of recursion, the situation is worse). But how likely do you think this is going to happen? Oh, you don't have to worry about it at all. Practice has proved that in most cases, a quick sort is always the best. If you're worried about this, you can use heap sorting, which is a stable O (log2 (n) *n) algorithm, but usually slower than fast sorting (because you want to regroup the heap)

Third, other sort

1. Bidirectional bubbling:
The usual bubbling is one-way, and this is two-way, which means you have to work backwards.
The code looks complicated, and it's clear that it's a way to shake back and forth.
The author of this code thinks it can reduce some of the exchange on a bubbling basis (I don't think so, maybe I was wrong).
Anyway, I think it's an interesting piece of code that's worth looking at.

Copy Code code as follows:

#include <iostream.h>
void Bubble2sort (int* pdata,int Count)
{
int itemp;
int left = 1;
int right =count-1;
int t;
Todo
{
The positive part
for (int i=right;i>=left;i--)
{
if (Pdata<pdata[i-1])
{
itemp = PData;
PData = Pdata[i-1];
Pdata[i-1] = itemp;
t = i;
}
}
left = t+1;

The reverse part
for (i=left;i<right+1;i++)
{
if (Pdata<pdata[i-1])
{
itemp = PData;
PData = Pdata[i-1];
Pdata[i-1] = itemp;
t = i;
}
}
right = T-1;
}while (Left<=right);
}

void Main ()
{
int data[] = {10,9,8,7,6,5,4};
Bubble2sort (data,7);
for (int i=0;i<7;i++)
cout<<data<< "";
cout<< "\ n";
}

Quick Sort

Copy Code code as follows:

#include <iostream>
using namespace Std;
Class QuickSort
{
Public
void Quick_sort (int* x,int low,int High)
{
int PivotKey;
if (Low {
Pivotkey=partion (X,low,high);
Quick_sort (x,low,pivotkey-1);
Quick_sort (X,pivotkey+1,high);
}
}
int partion (int* x,int low,int High)
{
int PivotKey;
Pivotkey=x[low];
while (Low {
while (Low --high; There is also a while loop that only executes this sentence
X[low]=x[high];
while (Low ++low; There is also a while loop that only executes this sentence
X[high]=x[low];
}
X[low]=pivotkey;
return to Low;
}
};
int main ()
{
int x[10]={52,49,80,36,14,58,61,97,23,65};
QuickSort QS;
Qs.quick_sort (x,0,9);
cout << "sorted sequence of numbers for:" <<endl;
for (int i=0;i <10;i++)
{
printf ("%d", x);
}
return 0;
}

2.SHELL sorting


This sort of sorting is very complex, see the program will know.
First you need a descending step, where we use 9, 5, 3, 1 (the last step must be 1).
It works by first sorting all the contents of 9-1 separate elements, and then using the same method to sort the 5-1 elements separated by the second analogy.

Copy Code code as follows:

#include <iostream.h>
void Shellsort (int* pdata,int Count)
{
int step[4];
Step[0] = 9;
STEP[1] = 5;
STEP[2] = 3;
STEP[3] = 1;

int itemp;
int k,s,w;
for (int i=0;i<4;i++)
{
K = step;
s =-K;
for (int j=k;j<count;j++)
{
ITEMP = Pdata[j];
W = j-k;//The subscript for the step element
if (S ==0)
{
s =-K;
s++;
Pdata[s] = itemp;
}
while ((itemp<pdata[w) && (w>=0) && (W<=count))
{
PDATA[W+K] = pdata[w];
W = w-k;
}
Pdata[w+k] = itemp;
}
}
}

void Main ()
{
int data[] = {10,9,8,7,6,5,4,3,2,1,-10,-1};
Shellsort (data,12);
for (int i=0;i<12;i++)
cout<<data<< "";
cout<< "\ n";
}

The program looks a bit sore. However, it is not difficult to remove the s==0 block is much easier, here is to avoid the use of 0 steps to create a program exception and write code. This code is worth looking at. The algorithm is named because its inventor's name is D.l.shell. According to the reference, "because of complex mathematical reasons to avoid the use of 2 power step, it can reduce the efficiency of the algorithm." In addition the complexity of the algorithm is 1.2 power of N. Also because it is very complex and "beyond the scope of this book" (I do not know the process), we have only the result. Bubble sort Performance Optimized version #include <iostream>

Copy Code code as follows:

using namespace Std;
void Maopao (int *list,int N)
{
int i=n,j,temp;
BOOL exchange;//exit loop when data is already lined up
for (i=0;i<n;i++)
{
Exchange=false;
for (j=0;j<n-i-1;j++)
{
if (list[j]>list[j+1])
{
TEMP=LIST[J];
LIST[J]=LIST[J+1];
List[j+1]=temp;
Exchange=true;
}

}
if (!exchange)
{
Return
}
}
}
int main ()
{
int a[7]={32,43,22,52,2,10,30};
Maopao (a,7);
for (int i=0;i<7;i++)
cout<<a<< "";
return 0;
}

Related Article

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.