快速排序(快拍)
快速排序的思想是分治,平均时间复杂度O(nlogn),当然快速排序的时间复杂度并不是稳定的,最大时间复杂度是n^2。当然在用C语言实现的快速排序中,快速排序是原地排序,所有排序中空间复杂最低。
代码
基于数组的快速排序(递归) 
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
 | void qSort(int *a, int low, int high){     if(low > high) return;     int first = low;     int last = high;     int key = a[first];     while(first < last){         while(first < last && a[last] >= key) --last;         if(first < last) a[first] = a[last];          while(first < last && a[first] <= key) ++first;         if(first < last) a[last] = a[first];         }     a[first] = key;     Qsort(a, low, first-1);     Qsort(a, first+1, high); }
 | 
这个版本可能便于理解
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
 | void swap(int *x, int *y) {     int t = *x;     *x = *y;     *y = t; } void quick_sort_recursive(int arr[], int start, int end) {     if (start >= end)         return;     int mid = arr[end];     int left = start, right = end - 1;     while (left < right) {         while (arr[left] < mid && left < right)             left++;         while (arr[right] >= mid && left < right)             right--;         swap(&arr[left], &arr[right]);     }     if (arr[left] >= arr[end])         swap(&arr[left], &arr[end]);     else         left++;     if (left)         quick_sort_recursive(arr, start, left - 1);     quick_sort_recursive(arr, left + 1, end); } void quick_sort(int arr[], int len) {     quick_sort_recursive(arr, 0, len - 1); }
 | 
php的快速排序
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
 | function qSort(&$envelopes, $start, $end ) {         if($end <= $start)         {             return;         }         $i = $start;         $j = $end;         while($i < $j)         {             while($i < $end && $envelopes[$i] <= $envelopes[$start])             {                 $i++;             }             while($j > $start && $envelopes[$j] >  $envelopes[$start])             {                 $j--;             }             if($i < $j)             {                 $tmp = $envelopes[$i];                 $envelopes[$i] = $envelopes[$j];                 $envelopes[$j] = $tmp;             }         }                  if($envelopes[$i] < $envelopes[$start]) {             $tmp = $envelopes[$start];             $envelopes[$start] = $envelopes[$j];             $envelopes[$i] = $tmp;         }         qSort($envelopes, $start, $i-1);         qSort($envelopes, $i+1, $end); }
 | 
基于链表的快速排序
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
 | struct Node    {       int key;       Node* next;   };      void swap(int* a, int* b) {     int tmp = *a ;     *a = *b;     *b = tmp; }   Node* GetPartion(Node* pBegin, Node* pEnd)   {       int key = pBegin->key;       Node* p = pBegin;       Node* q = p->next;          while(q != pEnd)       {           if(q->key < key)           {               p = p->next;               swap(p->key,q->key);           }              q = q->next;       }       swap(&p->key,&pBegin->key);       return p;   }      void QuickSort(Node* pBeign, Node* pEnd)   {       if(pBeign != pEnd)       {           Node* partion = GetPartion(pBeign,pEnd);           QuickSort(pBeign,partion);           QuickSort(partion->next,pEnd);       }   }
 | 
并归排序
并归排序的思想是分治的思想,时间复杂度 O(nlogn)。
- 如果一个链表(数组)只有一个元素或者为空直接返回。
- 如果链表(数组)可以分成尽可能相等两部分,将其分成尽可能相等两部分。
- 对于两个被分开的两个部分进行整个归并排序
- 把两个拍好序的链表(数组)进行合并。
 与快拍的区别是:快排是先处理完再递归而归并排序是先递归在处理
基于链表的并归排序。
代码
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
 |  struct ListNode * merge(struct ListNode *l1,struct ListNode *l2)  {      if(l1 == NULL) return l2;      if(l2 == NULL) return l1;      if( (l1==NULL) &&(l2==NULL) ) return NULL;            struct ListNode *head=NULL;      if(l1->val < l2->val)     {         head=l1;         l1=l1->next;     }      else       {          head=l2;          l2=l2->next;      }            struct ListNode *p=head;      while(l1 != NULL && l2 != NULL)      {          if(l1->val < l2->val)          {              p->next=l1;              l1=l1->next;          }          else          {              p->next=l2;              l2=l2->next;          }          p=p->next;      }            if(l1 != NULL) p->next=l1;      if(l2 != NULL) p->next=l2;      return head;  }   struct ListNode* sortList(struct ListNode* head) {     if(head == NULL || head->next == NULL) return head;     struct ListNode *slow=head;     struct ListNode *fast=head;     struct ListNode *pre=NULL;               while(fast!= NULL && fast->next != NULL)     {         pre=slow;         slow=slow->next;         fast=fast->next->next;     }     pre->next=NULL;               struct ListNode *l1=sortList(head);     struct ListNode *l2=sortList(slow);               return merge(l1,l2); }
 | 
基于数组的并归排序(递归)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 | void merge_sort_recursive(int arr[], int reg[], int start, int end) {     if (start >= end)         return;     int len = end - start, mid = (len >> 1) + start;     int start1 = start, end1 = mid;     int start2 = mid + 1, end2 = end;     merge_sort_recursive(arr, reg, start1, end1);     merge_sort_recursive(arr, reg, start2, end2);     int k = start;     while (start1 <= end1 && start2 <= end2)         reg[k++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++];     while (start1 <= end1)         reg[k++] = arr[start1++];     while (start2 <= end2)         reg[k++] = arr[start2++];     for (k = start; k <= end; k++)         arr[k] = reg[k]; } void merge_sort(int arr[], const int len) {     int reg[len];     merge_sort_recursive(arr, reg, 0, len - 1); }
 | 
基于数组的并归排序(迭代)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
 | int min(int x, int y) {     return x < y ? x : y; } void merge_sort(int arr[], int len) {     int* a = arr;     int* b = (int*) malloc(len * sizeof(int));     int seg, start;     for (seg = 1; seg < len; seg += seg) {         for (start = 0; start < len; start += seg + seg) {             int low = start, mid = min(start + seg, len), high = min(start + seg + seg, len);             int k = low;             int start1 = low, end1 = mid;             int start2 = mid, end2 = high;             while (start1 < end1 && start2 < end2)                 b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++];             while (start1 < end1)                 b[k++] = a[start1++];             while (start2 < end2)                 b[k++] = a[start2++];         }         int* temp = a;         a = b;         b = temp;     }     if (a != arr) {         int i;         for (i = 0; i < len; i++)             b[i] = a[i];         b = a;     }     free(b); }
 | 
冒泡排序
时间复杂度与空间复杂度
时间复杂度O(n^2)
代码
c语言冒泡排序
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 | void bubbleSort(int *nums, int lenNums) { int i,j; int flag = 1; for(i = 0; i < lenNums; i++) {     flag = 0;     for(j=0; j< lenNums - i -1; j++)     {                  if(nums[j] > nums[j+1])         {             nums[j] = nums[j+1] + nums[j];             nums[j+1] = nums[j] - nums[j+1];             nums[j] = nums[j] - nums[j+1];             flag = 0;         }     }     if(flag == 1)      {         break;     } } }
 | 
插入排序
时间复杂度与空间复杂度
时间复杂度O(n^2),空间复杂度O(1)
代码
| 1 2 3 4 5 6 7 8 9 10 11 12 13
 | void insertSort(int *nums, int numsLen) {     int tmp;     for(int i = 1; i< numsLen; i++)     {         tmp = nums[i];         for(int j = i; j>0 && nums[j] < nums[j-1]; j--)         {             nums[j] = nums[j-1];         }         nums[j] = tmp;     }  }
 | 
基数排序
基数排序是将 需要排序的所有数字统一为固定位数的数字(如果位数不足向前补0),然后按照位数切割,分别对每一个位数进行比较。从最低位开始,依次进行一次排序。这样排完以后就会变成一个有序序列。
时间复杂度与空间复杂度
代码
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
 | function radixsort($nums) {     $maxNum = max($nums);     $wei = 0;     for($exp =1 ; intval(($maxNum/$exp ))> 0; $exp*=10 )     {     	$nums = countSort($nums,$exp);     	var_dump($nums);     } } function countSort($nums,$exp) { 	for ($i=0; $i < 10; $i++) {  		$count[$i] = 0; 	}     for($i = 0; $i< count($nums); $i++)     {     	$key = intval(($nums[$i]/$exp)%10);     	$count[intval(($nums[$i]/$exp)%10)]++;     }     for($i = 1; $i < 10; $i++)     {     	$count[$i] += $count[$i - 1];     }     for($i = count($nums)-1; $i >= 0; $i--)     {     	$output[$count[intval(($nums[$i]/$exp)%10) ] -1] = $nums[$i];     	$count[intval((($nums[$i]/$exp)%10))]--;     }     for ($i=0; $i < count($nums) ; $i++) {      	$nums[$i] = $output[$i];     }     return $nums; } $a = [1,3,4,5,12,412,534,122]; radixsort($a);
 | 
堆排序
以最大堆为例,最大堆就是一个特殊二叉树,父节点大于子节点。
当前算法是以层序遍历,将二叉树存入数组中。
- 堆排序每次把处于堆顶的最大值取出
- 然后对堆进行排序
- 一次循环,直至堆变为0
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
 | <?php function heapSort($nums) {          $n = count($nums);     for($i = intval($n/2) -1 ; $i >= 0; $i--)     {         heapify($nums, $n, $i);     }     for($i = $n-1; $i >= 0; $i--)     {     	$tmp = $nums[0];     	$nums[0] = $nums[$i] ;     	$nums[$i] = $tmp;     	heapify($nums, $i, 0);     }     var_dump($nums); } function heapify(&$nums, $n, $i) {     $largest = $i;     $l = $i * 2 +1;     $r = $i * 2 +2;     if($l < $n && $nums[$largest] < $nums[$l])     {     	$largest = $l;     }     if($r < $n && $nums[$largest] < $nums[$r])     {     	$largest = $r;     }     if($largest != $i)     {     	$tmp = $nums[$i];     	$nums[$i] = $nums[$largest];     	$nums[$largest] = $tmp;     	heapify($nums, $n, $largest);     } } $a = [1,3,4,5,12,412,534,122,534,0,77,88,99,78,56,35,34,1]; heapSort($a); }
 | 
桶排序