經典排序演算法的實現(選擇,插入,shell,堆,快速,歸併排序)
阿新 • • 發佈:2018-12-02
1.選擇排序
//選擇排序 void selectSort(int * arr, int n) { for (int i = 0; i < n - 1; i++) { int min = arr[i]; int minPos = i; for (int j = i + 1; j < n; j++) { if (min > arr[j]) { min = arr[j]; minPos = j; } } int temp = arr[i]; arr[i] = arr[minPos]; arr[minPos] = temp; } }
2.插入排序
//插入排序
void insertSort(int * arr, int n) {
for (int i = 1; i < n; i++) {
int k = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > k) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = k;
}
}
3.shell排序
//shell排序,優化插排 void shellSort(int * arr, int n) { int step = n; while (step > 1) { step = step / 2; for (int i = step; i < n; i++) { int temp = arr[i]; int j = i; while (j - step >= 0 && temp <arr[j - step]) { arr[j] = arr[j-step]; j -= step; } arr[j] = temp; } } }
4.堆排序
//堆排序,優化選排 void headJust(int * arr, int start, int n) { int temp = arr[start]; int child = 2 * start + 1; while (child < n) { if (child+1 < n && arr[child] < arr[child+1]) { child++; } if (temp >= arr[child]) { break; } arr[start] = arr[child]; start = child; child = child * 2 + 1; } arr[start] = temp; } void headSort(int * arr, int n) { for (int i = n / 2; i >= 0; i--) { headJust(arr, i, n); } for (int i = 1; i < n; i++) { int temp = arr[0]; //首元素與最後元素進行交換 arr[0] = arr[n-i]; arr[n-i] = temp; headJust(arr, 0, n-i); //繼續調整為最大堆 } }
5.歸併排序
//歸併排序,分而治之
void merge(int * arr, int first, int mid, int last) {
int i = first, j = mid+1;
int m = mid, n = last;
int k = 0;
int temp[SIZE];
while (i <= m && j <= n) {
temp[k++] = (arr[i] <= arr[j])?arr[i++]:arr[j++];
}
while (i <= m) {
temp[k++] = arr[i++];
}
while (j <= n) {
temp[k++] = arr[j++];
}
for (int i = 0; i < k; i++) {
arr[i+first] = temp[i];
}
}
void mergeSort(int * arr, int start, int end) {
if (start < end) {
int mid = (start+end) / 2;
mergeSort(arr, start, mid);
mergeSort(arr, mid+1, end);
merge(arr, start, mid, end);
}
}
6.快速排序
//快速排序,挖坑填數分治法
void quickSort(int * arr, int left, int right) {
if (left < right) {
int i = left;
int j = right-1;
int temp = arr[i];
while (i < j) {
while (i < j && arr[j] >= temp)
j--;
if (i < j) {
arr[i++] = arr[j];
}
while (i < j && arr[i] < temp)
i++;
if (i < j) {
arr[j--] = arr[i];
}
}
arr[i] = temp;
quickSort(arr, left, i-1);
quickSort(arr, i+1, right);
}
}
具體實現如下
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define SIZE 200
//快速排序,挖坑填數分治法
void quickSort(int * arr, int left, int right) {
if (left < right) {
int i = left;
int j = right;
int temp = arr[i];
while (i < j) {
while (i < j && arr[j] >= temp)
j--;
if (i < j) {
arr[i++] = arr[j];
}
while (i < j && arr[i] < temp)
i++;
if (i < j) {
arr[j--] = arr[i];
}
}
arr[i] = temp;
quickSort(arr, left, i-1);
quickSort(arr, i+1, right);
}
}
//歸併排序,分而治之
void merge(int * arr, int first, int mid, int last) {
int i = first, j = mid+1;
int m = mid, n = last;
int k = 0;
int temp[SIZE];
while (i <= m && j <= n) {
temp[k++] = (arr[i] <= arr[j])?arr[i++]:arr[j++];
}
while (i <= m) {
temp[k++] = arr[i++];
}
while (j <= n) {
temp[k++] = arr[j++];
}
for (int i = 0; i < k; i++) {
arr[i+first] = temp[i];
}
}
void mergeSort(int * arr, int start, int end) {
if (start < end) {
int mid = (start+end) / 2;
mergeSort(arr, start, mid);
mergeSort(arr, mid+1, end);
merge(arr, start, mid, end);
}
}
//堆排序,優化選排
void headJust(int * arr, int start, int n) {
int temp = arr[start];
int child = 2 * start + 1;
while (child < n) {
if (child+1 < n && arr[child] < arr[child+1]) {
child++;
}
if (temp >= arr[child]) {
break;
}
arr[start] = arr[child];
start = child;
child = child * 2 + 1;
}
arr[start] = temp;
}
void headSort(int * arr, int n) {
for (int i = n / 2; i >= 0; i--) {
headJust(arr, i, n);
}
for (int i = 1; i < n; i++) {
int temp = arr[0]; //首元素與最後元素進行交換
arr[0] = arr[n-i];
arr[n-i] = temp;
headJust(arr, 0, n-i); //繼續調整為最大堆
}
}
//shell排序,優化插排
void shellSort(int * arr, int n) {
int step = n;
while (step > 1) {
step = step / 2;
for (int i = step; i < n; i++) {
int temp = arr[i];
int j = i;
while (j - step >= 0 && temp <arr[j - step]) {
arr[j] = arr[j-step];
j -= step;
}
arr[j] = temp;
}
}
}
//插入排序
void insertSort(int * arr, int n) {
for (int i = 1; i < n; i++) {
int k = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > k) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = k;
}
}
//選擇排序
void selectSort(int * arr, int n) {
for (int i = 0; i < n - 1; i++) {
int min = arr[i];
int minPos = i;
for (int j = i + 1; j < n; j++) {
if (min > arr[j]) {
min = arr[j];
minPos = j;
}
}
int temp = arr[i];
arr[i] = arr[minPos];
arr[minPos] = temp;
}
}
void initialArray(int * arr, int n) {
for (int i = 0; i < n; i++) {
arr[i] = rand() % 100 + 1;
}
}
void printNum(int * arr, int n) {
for (int i = 0; i < n; i++) {
if ((i+1) % 10 == 0) {
putchar('\n');
} else {
printf("%d\t", arr[i]);
}
}
}
int main(void)
{
srand((unsigned) time(NULL));
int num[SIZE];
printf("選擇排序前:\n");
initialArray(num, SIZE);
printNum(num, SIZE);
printf("選擇排序後:\n");
selectSort(num, SIZE);
printNum(num, SIZE);
printf("插入排序前:\n");
initialArray(num, SIZE);
printNum(num, SIZE);
printf("插入排序後:\n");
insertSort(num, SIZE);
printNum(num, SIZE);
printf("shell排序前:\n");
initialArray(num, SIZE);
printNum(num, SIZE);
printf("shell排序後:\n");
shellSort(num, SIZE);
printNum(num, SIZE);
printf("堆排序前:\n");
initialArray(num, SIZE);
printNum(num, SIZE);
printf("堆排序後:\n");
headSort(num, SIZE);
printNum(num, SIZE);
printf("歸併排序前:\n");
initialArray(num, SIZE);
printNum(num, SIZE);
printf("歸併排序後:\n");
mergeSort(num, 0, SIZE-1);
printNum(num, SIZE);
printf("快速排序前:\n");
initialArray(num, SIZE);
printNum(num, SIZE);
printf("快速排序後:\n");
quickSort(num, 0, SIZE-1);
printNum(num, SIZE);
return 0;
}