Introduction to Algorithmic learning using C language to achieve the basic sorting algorithm _c language

Source: Internet
Author: User
Tags joins

First look at some of the relevant concepts of the sorting algorithm:
1, stable sort and unstable sort
Simply put, all the equal numbers, after some sort of sorting method, can still keep their relative order before they are sorted, we say this sort of method is stable. On the contrary, it is not stable.
For example: A group of numbers before the order is A1,A2,A3,A4,A5, where a2=a4, after some sort of a1,a2,a4,a3,a5, then we say this sort is stable, because A2 sort before A4 before, sort it still in front of A4. If it turns into A1,A4,A2,A3,A5, it's not stable.

2, internal sorting and outside sorting
In the sort process, all the numbers that need to be sorted are in memory and the order of their storage is adjusted in memory, called inner ordering;
In the sort process, only a portion of the number is transferred into memory, with the help of the memory adjustment number in the stored order ordering method called the outer sort.

3, the time complexity of the algorithm and the complexity of space
The time complexity of the so-called algorithm refers to the computational work required to perform the algorithm.
The spatial complexity of an algorithm generally refers to the memory space needed to execute this algorithm.

Next we actually look at a few large sorting algorithm specific C language implementation:

Bubble sort (Bubble sort)

If the sequence is well arranged from small to large, then any two adjacent elements should satisfy the a[i-1] <= a[i] relationship. In bubble sort, we traverse the array from right to left, comparing the two adjacent elements. If the order of the two elements is wrong, then exchange the two elements. If the order of the two elements is correct, no exchange is made. After one traversal, we can guarantee that the smallest element (bubble) is in the leftmost position.

After one traversal, the bubble sort does not guarantee that all elements have been arranged in a small to large order. So we need to iterate over the elements of the array from right to left and bubble sort. This time traversal, we do not have to consider the leftmost element. Then proceed to the traversal of up to n-1 times.

If the elements are not exchanged during a traversal, the array is sorted so that the stop order can be aborted. The worst case scenario is that in the starting array, the largest element is at the far left, so the bubble algorithm must traverse the n-1 to arrange the array in order to not finish the sorting ahead of time.

/*by vamei*/
/*swap The neighbors if out of order*/
void bubble_sort (int a[], int ac)
{
  /*use swap*/
  I NT I,j;
  int sign;
  for (j = 0; J < Ac-1; J + +) {
    sign = 0;
    for (i = ac-1 i > J; i--)
    {
      if (A[i-1] > A[i]) {
        sign = 1;
        Swap (a+i, a+i-1);
      }
    }
    if (sign = = 0) break;
  }

Insert sort (Insertion sort)

Suppose that when the freshmen report, we will be the freshmen in line (ie sort) by height. If a student joins us at this time, we will join the student at the end of the team. If the student is lower than the previous student, let the student swap positions with the students in the front. The student will eventually change to the position he should be in. This is the rationale for insertion sequencing.

For the starting array, we think that initially, there was a student, the leftmost element (i=0), that formed an orderly team.

Then a second student (I=1) joins the team, and the second student is exchanged to where it should be; then the third student joins the team and the third student exchanges to where it should be. When n students join the team, our sorting is done.

/*by vamei*/
/*insert the next element into 
 the sorted part*/
void insert_sort (int a[], int ac)
{
  /*u SE swap*/
  int i,j;  
  for (J=1 J < AC; j + +) 
  {
    i = j-1;
    while ((i>=0) && (a[i+1] < a[i])) 
    {
      swap (a+i+1, a+i);
      i--
    }}
  }


Select sort (Selection sort)

The final result of the sort: any element is not much more than the element (A[i] <= a[j] on its right, if I <= j). So, in an ordered sequence, the smallest element is placed in the leftmost position, and the second small element is in the I=1 position ... The largest element is at the end.

Select the sort by first finding the smallest element in the starting array, swapping it to i=0, and then looking for the smallest element in the remaining element, swapping it to the i=1 position ... Until you find the second largest element, swap it to the n-2 position. At this point, the entire array is sorted complete.

/*by vamei*/
/*find The smallest of the rest,
 then append to the sorted part*/
void select_sort (int a[], int a c) 
{
  /*use swap*/
  int i,j;
  int min_idx;
  for (j = 0; J < Ac-1; J + +) 
  {
    min_idx = j;
    for (i = j+1 i < AC; i++) 
    {
      if (A[i] < A[MIN_IDX]) 
      {
        min_idx = i;
      }
    }
    Swap (a+j, A+MIN_IDX);
  }  
}

Hill sort (Shell sort)

We mentioned in the bubble sort that the worst-case scenario occurs when the large element is at the beginning of the array. These large elements at the beginning of the array need to be traversed multiple times to exchange to the end of the queue. Such elements are called turtles (turtle).

The reason for the turtle element is that the bubbling sort is always compared and exchanged between the adjacent two elements. So every time you traverse from right to left, large elements can only move one bit to the right. (Small elements at the end of the team, called the Rabbit (rabbit) element, they can be exchanged quickly to the head of the team.) )

Hill sort is to compare and exchange elements at greater intervals so that large elements can move more than one position to the right in exchange for faster movement of turtle elements. For example, you can divide an array into 4 sub arrays (i=4k, i=4k+1, i=4k+2, i=4k+3) to bubble-sort each child array. such as the i=0,4,8,12 of the child array .... At this point, the interval for each Exchange is 4.

The order of the arrays is not necessarily arranged after the sorting of the four sub arrays is completed. The hill sort will continue to reduce the interval, to form the sub array, and to bubble sort the array ... When the interval is reduced to 1 o'clock, it is equivalent to a bubble sort of the entire array. The order of the arrays is then arranged.

The

Hill sort can be sorted not only with bubbling, but also with other sorting methods.

/*by vamei*//*quickly sort the turtles at the tail of the array*/void shell_sort (int a[
  ], int ac) {int step;
  int i,j;
  int nsub;

  int *sub;
  /* Initialize Step/step = 1;

  While [Step < AC] Step = 3*step + 1; /* When step becomes 1, it's equivalent to the bubble sort*/while (step > 1) {/* step is down to 1 at most
    * * Step = STEP/3 + 1;  For (i=0 i<step; i++) {/* Pick a element every step, and combine into a sub-array */nsub = (AC-      
      I-1)/step + 1;
      Sub = (int *) malloc (sizeof (int) *nsub); 
      For (j=0 j<nsub; j + +) {Sub[j] = A[i+j*step]; 
       }/* Sort the sub-array by bubble sorting.
      It could be the other sorting methods * * Bubble_sort (Sub, nsub);
      /* Put back the sub-array*/for (j=0 j<nsub; j + +) {A[i+j*step] = sub[j];
    /* Free Sub-array */free (sub); }  
  }
}

The Shell sorting depends on the selection of the interval (step). A common option is to set this interval to the 1/1.3 of the last interval. See reference books.

Merge sorts (merge sort)

If we're going to sort a poker by number size. Two people have already ordered half of them separately before. So we can put these two stacks of poker up, assuming the small cards are on top. At this point, we will see the top two cards in the stack.

We took the two cards and put them in our hands. Two cards in the heap is two cards exposed to the top, continue to take the small one in the hands ... Until all the cards are in their hands, the whole deck is sorted. This is the merge sort.

In the following implementation, recursion is used:

/*by vamei*/
/*recursively merge two sorted arrays*/
void merge_sort (int *a, int ac)
{
  int i, j, K;  
  int AC1, AC2;
  int *ah1, *AH2;
  int *container;

  /*base case*/  
  if (AC <= 1) return;

  /*split the array into two*/
  ac1 = AC/2;
  AC2 = AC-AC1;
  AH1 = a + 0;
  AH2 = a + Ac1;

  /*recursion*/
  Merge_sort (AH1, AC1);
  Merge_sort (AH2, AC2);
 
  /*merge*/
  i = 0;
  j = 0;
  k = 0;
  container = (int *) malloc (sizeof (int) *ac);
  while (I<ac1 && j<ac2) {
    if (Ah1[i] <= ah2[j]) {
      container[k++] = ah1[i++]; 
    else {
      container[k++] = ah2[j++];
    }
  }
  while (I < AC1) {
    container[k++] = ah1[i++];
  }
  while (J < AC2) {
    container[k++] = ah2[j++];
  }

  /*copy back the sorted array*/for
  (i=0; i<ac; i++) {
    a[i] = Container[i];
  }
  /*free space*/free
  (container);
}

Fast sort (Quick sort)

We still consider sorting the students according to their height. In the quick sort, we randomly pick out a student to refer to the student's height (pivot). Then let the student stand on the right side of the student, and the rest stand on the student's left.

It is clear that all the students are divided into two groups. The students on the right are taller than the students on the left side of the student's height.

We went on to pick out one of the students in the lower-height student group and divide the students in the lower-height group into two groups (very low and not so low). Similarly, the High student group is divided into two groups (not so high and very high).

So continue to subdivide until there is only one student in the group. Sorting is done when there is only one student in all the groups.

In the following implementation, recursion is used:

/*by vamei*//*select Pivot, put elements (<= pivot) to the left*/void Quick_sort (int a[], int ac) {/*use swap*/
  /* Pivot is a position, the elements before pivot are smaller or equal to pvalue/int pivot;

  /* The position of the element to be tested against pivot */INT sample; 
    /* Select a pvalue.
    Median is supposed to being a good choice, but that would itself take time.
  Here, the Pvalue are selected in a very simple WAYI:A[AC/2]//////* store pvalue at a[0] */swap (a+0, A+AC/2); 

  Pivot = 1; * Test each element */for (sample=1 sample<ac; sample++) {if (a[sample) < a[0]) {swap (A+pivot, A+sa
      Mple);
    pivot++;

  }/* Swap an element (which <= pvalue) with a[0] */swap (A+0,A+PIVOT-1); /* Base case, if only two elements are in the array, the above pass has already the "array */if (sorted) re
  Turn
    else {/* recursion * * Quick_sort (A, pivot);
  Quick_sort (A+pivot, Ac-pivot);

}
} 

The ideal pivot is to take the median number of grouped elements. However, the algorithms for finding the median need to be implemented separately. You can also randomly select elements as pivot, and random selection also needs to be implemented separately. For simplicity, I use the middle position element as the pivot every time.

Heap sort (Heap sort)

The heap (heap) is a common data structure. It is a prioritized queue. The most common implementation of the heap is a limited-operation complete Binary tree. This complete Binary tree retains the properties of the heap, that is, the parent node is greater than the child node (children). Therefore, the root node of the heap is the smallest of all heap elements. The heap definition has the Insert node and deletes the root node operation, both of which maintain the heap's attributes.

We can form a heap of unordered arrays, and then we keep taking out the root node, which eventually forms an ordered array.

For a more detailed description of the heap please read the bibliography.

The following is the data structure of the heap, as well as inserting nodes and deleting root node operations. You can easily build the heap and take out the root node to form an ordered array.

/* by Vamei use a big array to implement heap Declare:int heap[maxsize] in calling function Heap[0]: Total node s in the heap for a node I, its children are i*2 and i*2+1 (if exists) it parent is i/2/void insert (int new, int
  Heap[]) {int childidx, PARENTIDX;
  Heap[0] = heap[0] + 1;
  
  Heap[heap[0]] = new;
/* Recover Heap Property */percolate_up (heap);
  } static void percolate_up (int heap[]) {int lightidx, PARENTIDX;
  Lightidx = heap[0];
  Parentidx = LIGHTIDX/2; /* Lightidx is root? && swap?  */while ((Parentidx > 0) && (Heap[lightidx] < Heap[parentidx]) {/* swap */swap (heap + lightidx, 
    Heap + parentidx);
    Lightidx = Parentidx;
  Parentidx = LIGHTIDX/2;
  int delete_min (int heap[]) {int min;
    if (Heap[0] < 1) {/* delete element from a empty heap/printf ("Error:delete_min from a empty heap.");
  Exit (1);
}/* Delete root move the last leaf to the root * * min = heap[1];  Swap (heap + 1, heap + heap[0]);

  Heap[0]-= 1;
 
  /* Recover Heap Property */Percolate_down (heap);
return min;
  } static void Percolate_down (int heap[]) {int heavyidx;
  int childIdx1, CHILDIDX2, Minidx; int sign; /* state variable, 1:swap;
  0:no Swap * * Heavyidx = 1;
    Do {sign = 0;
    childIdx1 = heavyidx*2;
    CHILDIDX2 = childIdx1 + 1; 
    if (ChildIdx1 > Heap[0]) {/* Both children are null */break;
    else if (ChildIdx2 > Heap[0]) {/* right children is null */minidx = childIdx1;
             } else {minidx = (Heap[childidx1] < HEAP[CHILDIDX2])?
    CHILDIDX1:CHILDIDX2;
      } if (Heap[heavyidx] > Heap[minidx]) {/* Swap with Child */swap (heap + heavyidx, heap + minidx);
      Heavyidx = Minidx;
    sign = 1;
} while (sign = 1);

 }

Summarize

In addition to the above algorithm, there are also such as bucket sorting, radix sorting involved. I will add the relevant algorithm in the future to the article. The time complexity analysis of correlation algorithms can be found in bibliography. I did a rough analysis myself. If the blog can support the display of mathematical formulas, I will post my analysis process for the lure of jade.

The code above is written by myself, and it's just a simple test. If there are errors and omissions, thank you for your correction first.

Finally, the exchange functions used in the above are:

/* by Vamei
/* Exchange The values pointed
by PA and pb*/void swap (int *pa, int *pb)
{
  int tmp;
  TMP = *PA;
  *pa = *PB;
  *PB = tmp;
}

Comparison and selection of several sorting algorithms
1. Select the factors to consider for the sorting method:
(1) The number of elements to be sorted n;
(2) The amount of information in the element itself;
(3) The structure and distribution of keywords;
(4) The condition of the language tool, the size of the auxiliary space and so on.

2. Some recommendations:
   (1) If n is small (n <= 50), you can use direct insertion sort or direct selection. Because the record-moving operation required by direct insertion sort is more than direct selection order, it is better to use direct selection when the information of record itself is large.
   (2) If the initial state of the file has been ordered according to the keyword, it is advisable to choose a direct insert or bubble sort.
   (3) If n is large, a sort method of time complexity O (nlog2n) should be used: quick sort, heap sort, or merge sort. Fast sorting is considered to be the best method in the current comparison based internal sorting method. The
   (4) is based on the comparison sort method, each time you compare the size of two keywords, only two possible transitions occur, so you can use a binary tree to describe the comparison decision process, which proves that when the n keywords of a file are randomly distributed, any use of the "comparison" The sorting algorithm requires at least O (nlog2n) time.
   (5) A linked list can be used as a storage structure to avoid time-consuming movement of records when the record itself has a large amount of information.

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.