目录
冒泡排序
思路:
n-1趟比较,每次从前往后依次两两比较,逆序则交换。
void bubble_sort(int arr[], int len) {
int i, j, temp;
for(i = 0; i < len - 1; i++) // i表示当前已排序好的元素个数
for(j = 0; j < len - 1 - i; j++)
if(arr[j] > arr[j+1]) {
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
改进:
如果当前数组已经有序,则退出循环。(改进由于每一层循环都要加入一次判断,因此不一定能降低运行时间)
void bubble_sort(int arr[], int len) {
int i, j, temp;
for(i = 0; i < len - 1; i++) {
bool isSorted = true;
for(j = 0; j < len - 1 - i; j++)
if(arr[j] > arr[j+1]) {
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
isSorted = false;
}
if(isSorted)
break;
}
}
选择排序
思路:
- 将数组划分为有序数组与无序数组
- 每次遍历无序数组的全部数据,找出所需数据
- 将数据插入有序数组末尾
void swap(int *a,int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
void selection_sort(int arr[], int len) {
int i,j;
for (i = 0 ; i < len - 1 ; i++) {
int min = i;
for (j = i + 1; j < len; j++)
if (arr[j] < arr[min])
min = j;
swap(&arr[min], &arr[i]);
}
}
插入排序
直插排序
思路:
每次从未排序的序列中取出一个元素,将其插入到已排好序的序列中。
void insertion_sort(int arr[], int len){
for (int i = 1; i < len; i++){
int key = arr[i];
int j = i - 1;
while((j >= 0) && (arr[j] > key)) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
希尔排序
思路:
先设置分组间隔,通过间隔将序列分成若干组,每组分别进行插入排序。
- 将数组分成gap组 初始值:gap = n / 2;
- 对每个组进行遍历;
- 两层循环,对组内元素进行插入排序。
void shellSort(int n, int* a) {
for(int gap = n/2; gap >= 1; gap /= 2)
for(int i = 0; i < gap; i++)
for(int j = i + gap; j < n; j += gap)
for(int k = j; k > 0; k--)
if(a[j - gap] < a[j]) swap(a[j], a[j - gap]);
else break;
}
快速排序
思路:
选择序列的第一个元素作为关键值pivot,将比pivot大的数放到pivot的一边,比pivot小的数放到另一边,最后当low和high相同时,将pivot放到中间位置。最后递归左右序列进行排序。
递归版
void quickSort(int low, int high) {
int pivotkey = a[low], start = low, end = high;
if(low < high) {
while(low < high) {
while(high > low) {
if(a[high] >= pivotkey)
high--;
else {
a[low++] = a[high];
break;
}
}
while(low < high) {
if(a[low] < pivotkey)
low++;
else {
a[high--] = a[low];
break;
}
}
}
a[low] = pivotkey;
quickSort(start, low - 1);
quickSort(low + 1, end);
}
}
归并排序
思路:
- 将数组序列一分为二,递归分下去,直到单个序列长度为1
- 对于每个子序列,两两合并,直到合并为一个有序序列
非递归版
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 * 2) {
int low = start, mid = min(start + seg, len), high = min(start + seg * 2, 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);
}
递归版
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);
}