1、冒泡排序
冒泡排序是我们学习的第一个排序,原理是相邻两个数比较大小,从而决定是否交换
void BubbleSort1(int* a, int n)
{for (int j = 0; j < n; j++){int flag = 0;for (int i = 1; i < n - j; i++){if (a[i - 1] > a[i]){Swap(&a[i - 1], &a[i]);flag = 1;}}if (flag){break;}}
}
2、插入排序
插入排序的原理是:从数组第二个元素开始,依次与前面的元素进行对比,假如我们需要把这个无顺序的数组排序成有序升序数组,就将这个元素与前面的元素比较大小,如果这个元素更小,就插入到另一个元素的前面,依次类推。。。
void InsertSort1(int* a, int n)
{for (int i = 0; i < n - 1; i++){int end = i;int tmp = a[end + 1];while (end >= 0){if (tmp > a[end]){a[end + 1] = a[end];--end;}else{break;}}a[end+1] = tmp;}
}
3、选择排序
这个排序方法的思路是:每一次从待排序的数据中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据全部排完
void SelectSort(int* a, int n)
{int begin = 0, end = n - 1;while (begin < end){int mini = begin, maxi = begin;for (int i = begin + 1; i <= end; ++i){if (a[i] < a[mini]){mini = i;}if (a[i] > a[maxi]){maxi = i;}}Swap(&a[begin], &a[mini]);if (maxi == begin){maxi = mini;}Swap(&a[maxi], &a[end]);begin++;end--;}
}
4、快速排序
快速排序的基本思想是:任取待排序元素序列中的某元素作为基准值,按照该排序码将排序集合分裂成两子序列,左子序列中所有元素小于基准值,右子序列中所有元素均大于该基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应的位置上为止
快速排序有三个不同的版本:
1、hoare版本
int PartSort1(int* a, int left, int right)
{int key = left;while (left < right){while (left < right && a[right] >= a[key]){right--;}while (left < right && a[left] <= a[key]){left++;}if(left < right)Swap(&a[left], &a[right]);}Swap(&a[left], &a[key]);return left;}
2、挖坑法
int PartSort2(int* a, int left, int right)
{int key = a[left];int hole = left;while (left < right){while (left < right && a[right] >= key){right--;}a[hole] = a[right];hole = right;while (left < right && a[left] <= key){left++;}a[hole] = a[left];hole = left;}a[hole] = key;return hole;
}
3、前后指针法
int PartSort3(int* a, int left, int right)
{int key = left;int prev = left;int cur = left + 1;while (cur <= right){if (a[cur] <= a[key] && ++prev != cur){Swap(&a[cur], &a[prev]);}cur++;}Swap(&a[key], &a[prev]);return prev;
}
4、快速排序递归实现
void QuickSort(int* a, int left, int right)
{if (right - left <= 1)return;int div = PartSort(a, left, right);QuickSort(a, left, div);QuickSort(a, div + 1, right);
}
5、快速排序的非递归实现
void QuickSortNonR(int* a, int left, int right)
{Stack st;StackInit(&st);StackPush(&st, left);StackPush(&st,right);while (StackEmpty(&st) != 0){right = StackTop(&st);StackPop(&st);left = StackTop(&st);StackPop(&st);if (right - left <= 1)continue;int div = PartSort(a, left, right);StackPush(&st, div + 1);StackPush(&st, right);StackPush(&st, left);StackPush(&st, div);}StackDestroy(&st);
}
5、归并排序
归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序列的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
void _MergeSort(int* a, int begin, int end, int* tmp)
{if (begin >= end)return;int mid = (begin + end) / 2;_MergeSort(a, begin, mid, tmp);_MergeSort(a, mid + 1, end, tmp);int begin1 = begin, end1 = mid;int begin2 = mid + 1, end2 = end;int i = begin;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){tmp[i++] = a[begin1++];}else{tmp[i++] = a[begin2++];}}while (begin1 <= end1){tmp[i++] = a[begin1++];}while (begin2 <= end2){tmp[i++] = a[begin2++];}memcpy(a + begin, tmp + begin, sizeof(int) * (end - begin + 1));
}
void MergeSort(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail");return;}_MergeSort(a, 0, n - 1, tmp);free(tmp);
}
6、计数排序
计数排序的过程是:1、统计相同元素出现的次数 2、根据统计的结果将序列回收到原来的序列中
void CountSort(int* a, int n)
{int min = a[0], max = a[0];for (int i = 1; i < n; i++){if (a[i] < min){min = a[i];}if (a[i] > max){max = a[i];}}int range = max - min + 1;int* count = (int*)calloc(range, sizeof(int));if (count == NULL){perror("calloc fail");return;}//统计次数for (int i = 0; i < n; i++){count[a[i] - min]++;}//循环int i = 0;for (int j = 0; j < range; j++){while (count[j]--){a[i++] = j + min;}}
}