【0001】排序法与查找方式
0001、选择排序法
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <time.h> 4 #define N 20 5 6 7 void main() 8 { 9 time_t ts; 10 srand((unsigned int)time(&ts)); 11 12 int a[N] = { 0 }; 13 14 for (int i = 0; i < N; i++) 15 { 16 printf("%4d", a[i] = rand() % 300); 17 } 18 19 int intmax = 0; 选择法找极值(极大值和极小值) 20 for (int i = 0; i < N; i++) 21 { 22 if (intmax < a[i]) 23 intmax = a[i]; 24 } 25 printf("\nintmax=%d \n", intmax); // intmax=261 26 27 28 system("pause"); 29 }
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <time.h> 4 #define N 20 5 6 7 void main001() 8 { 9 time_t ts; 10 srand((unsigned int)time(&ts)); 11 12 int a[N] = { 0 }; 13 14 for (int i = 0; i < N; i++) 15 { 16 printf("%4d", a[i] = rand() % 300); 17 } 18 19 20 for (int i = 0; i < N - 1; i++) 21 { 22 int imax = i; 23 for (int j = i + 1; j < N; j++) 24 { 25 if (a[imax] < a[j]) 26 imax = j; 27 } 28 if (imax != i) 29 { 30 int temp = a[imax]; 31 a[imax] = a[i]; 32 a[i] = temp; 33 } 34 } 35 36 37 putchar('\n'); 38 for (int i = 0; i < N; i++) 39 printf("%4d", a[i]); 40 41 putchar('\n'); 42 43 system("pause"); 44 } 45 46 /* 47 9 49 261 110 64 160 83 215 58 163 29 101 131 88 56 255 104 186 44 165 48 261 255 215 186 165 163 160 131 110 104 101 88 83 64 58 56 49 44 29 9 49 */
0002、冒泡排序法
1 #include <stdio.h> 2 #include <stdlib.h> 3 #define N 10 4 5 void main() 6 { 7 int a[N] = { 3,5,18,9,23,5,2,1,0,2 }; 8 9 for (int i = 0; i < N - 1; i++) // 沉底极大值 10 { 11 if (a[i] > a[i + 1]) 12 { 13 int temp = a[i]; 14 a[i] = a[i + 1]; 15 a[i + 1] = temp; 16 } 17 18 for (int i = 0; i < N; i++) 19 printf("%3d", a[i]); 20 21 putchar('\n'); 22 } 23 24 /* 25 3 5 18 9 23 5 2 1 0 2 26 3 5 18 9 23 5 2 1 0 2 27 3 5 9 18 23 5 2 1 0 2 28 3 5 9 18 23 5 2 1 0 2 29 3 5 9 18 5 23 2 1 0 2 30 3 5 9 18 5 2 23 1 0 2 31 3 5 9 18 5 2 1 23 0 2 32 3 5 9 18 5 2 1 0 23 2 33 3 5 9 18 5 2 1 0 2 23 34 */ 35 36 system("pause"); 37 }
1 #include <stdio.h> 2 #include <stdlib.h> 3 #define N 10 4 5 6 void main() 7 { 8 int a[N] = { 3,5,18,9,23,5,2,1,0,2 }; 9 10 for (int i = 0; i < N - 1; i++) 11 { 12 for (int j = 0; j < N - 1 - i; j++) // 每沉底一次,就向上冒泡一次 13 { 14 if (a[j] > a[j + 1]) 15 { 16 int temp = a[j]; 17 a[j] = a[j + 1]; 18 a[j + 1] = temp; 19 } 20 } 21 22 for (int i = 0; i < N; i++) 23 printf("%3d", a[i]); 24 25 putchar('\n'); 26 } 27 28 /* 29 3 5 9 18 5 2 1 0 2 23 30 3 5 9 5 2 1 0 2 18 23 31 3 5 5 2 1 0 2 9 18 23 32 3 5 2 1 0 2 5 9 18 23 33 3 2 1 0 2 5 5 9 18 23 34 2 1 0 2 3 5 5 9 18 23 35 1 0 2 2 3 5 5 9 18 23 36 0 1 2 2 3 5 5 9 18 23 37 0 1 2 2 3 5 5 9 18 23 38 */ 39 40 system("pause"); 41 }
0003、双向冒泡型快速排序法、分治快速排序、快速排序函数调用
单线程下,最快速的排序方法:
快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod),该方法的基本思想是:
1.先从数列中取出一个数作为基准数。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。
虽然快速排序称为分治法,但分治法这三个字显然无法很好的概括快速排序的全部步骤。因此我的对快速排序作了进一步的说明:挖坑填数+分治法。
#include <stdio.h> #include <stdlib.h> void show(int *arr, int length) { for (int i = 0; i < length; i++) { printf("%4d", arr[i]); } printf("\n"); } void swap(int *pi, int *pj) { int temp = *pi; *pi = *pj; *pj = temp; }
void quick_sortbyBidirectionalBubbling(int *arr, int iLeft, int iRight) { int i = iLeft, j = iRight, key = arr[iLeft]; if (i >= j) return; else { while (i<j) { while (i < j&&key < arr[j]) // 从右向左 j--; if (i < j) { swap(arr + i, arr + j); i++; } while (i < j&&key > arr[i]) // 从左向右 i++; if (i < j) { swap(arr + i, arr + j); j--; } } } quick_sortbyBidirectionalBubbling(arr, iLeft, i - 1); quick_sortbyBidirectionalBubbling(arr, i + 1, iRight); }
void quick_sort(int *arr, int begin, int end) { int key = arr[begin]; int i = begin; if (begin >= end) { return; } else { for (int j = i + 1; j <= end; j++) { if (key > arr[j]) { i++; swap(&arr[i], &arr[j]); } } swap(&arr[begin], &arr[i]); } quick_sort(arr, begin, i - 1); quick_sort(arr, i + 1, end); }
int compared(const void *p1, const void *p2) { const int *pint1 = p1; const int *pint2 = p2; if (*pint1 == *pint2) return 0; else if (*pint1 > *pint2) return 1; else return -1; } void main() { int a[10] = { 10,11,9,17,8,29,5,39,6,102 }; show(a, 10); //quick_sort(a, 0, 9); //quick_sortbyBidirectionalBubbling(a, 0, 9); qsort(a, 10, sizeof(int), compared); show(a, 10); system("pause"); }
#include <stdlib.h> #include <stdio.h> struct LinkNode { int data; struct LinkNode *pNext; }; typedef struct LinkNode Node; void quickSortLinkList(Node *pbegin, Node *pend) { if (pbegin == pend) return; else { int key = pbegin->data; Node *pNode = pbegin; for (Node *qNode = pbegin->pNext; qNode != pend; qNode = qNode->pNext) { if (qNode->data < key) { pNode = pNode->pNext; int temp = pNode->data; pNode->data = qNode->data; qNode->data = temp; } } int temp = pNode->data; pNode->data = pbegin->data; pbegin->data = temp; quickSortLinkList(pbegin, pNode); quickSortLinkList(pNode->pNext, pend); } }
0004、二分查找和拉格朗日定理
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <time.h> #include <Windows.h> #define N 1024 void search(int a[N], int num) // 二分查找 { int head = 0, tail = N - 1, middle; int flag = -1, count=0; if (num<a[head]) { printf("要查找的值%d小于数组中的最小值%d,共查找了1次 \n", num, a[head]); } else if (num>a[tail]) { printf("要查找的值%d大于数组中的最大值%d,共查找了1次 \n", num, a[tail]); } else { while (head <= tail) { middle = (head + tail) / 2; printf("head=%d, middle=%d, tail=%d, count=%d \n", head, middle, tail, ++count); if (a[middle] == num) { flag = 1; printf("找到了,是a[%d]=%d, 一共查找了%d次 \n", middle, num, count); break; } else if (a[middle] > num) tail = middle - 1; else head = middle + 1; } if (flag == -1) printf("一共查找了%d次,未找到数据%d \n", count, num); } } void main() { int a[N], b[N]; srand((unsigned int)(time(NULL))); for (int i = 0; i < N; i++) { a[i] = i; b[i] = a[i] + rand() % 300; Sleep(rand() % 10); } for (int i = 0; i < N - 1; i++) { for (int j = 0; j < N - 1 - i; j++) { if (b[j] > b[j + 1]) { int temp = b[j]; b[j] = b[j + 1]; b[j + 1] = temp; } } } for (int i = 0; i < N; i++) printf("%d ", b[i]); int num; scanf("%d", &num); search(a, num); search(b, num); system("pause"); }
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <time.h> #include <Windows.h> #define N 1024 void search(int a[N], int num) // 二分查找 { int head = 0, tail = N - 1, middle; int flag = -1, count=0; if (num<a[head]) { printf("要查找的值%d小于数组中的最小值%d,共查找了1次 \n", num, a[head]); } else if (num>a[tail]) { printf("要查找的值%d大于数组中的最大值%d,共查找了1次 \n", num, a[tail]); } else { while (head <= tail) { middle = (head + tail) / 2; printf("head=%d, middle=%d, tail=%d, count=%d \n", head, middle, tail, ++count); if (a[middle] == num) { flag = 1; printf("找到了,是a[%d]=%d, 一共查找了%d次 \n", middle, num, count); break; } else if (a[middle] > num) tail = middle - 1; else head = middle + 1; } if (flag == -1) printf("一共查找了%d次,未找到数据%d \n", count, num); } } void searchByLagrange(int a[N], int num) { int head = 0, tail = N - 1, middle; int flag = -1, count = 0; if (num<a[head]) { printf("要查找的值%d小于数组中的最小值%d,共查找了1次 \n", num, a[head]); } else if (num>a[tail]) { printf("要查找的值%d大于数组中的最大值%d,共查找了1次 \n", num, a[tail]); } else { while (head <= tail) { /* middle = (head + tail) / 2; // 二分查找 middle = head + (tail - head) / 2; */ middle = head + (tail - head)*1.0*(num - a[head]) / (a[tail] - a[head]); /* 拉格朗日差值定理 ((num - a[head]) / (a[tail] - a[head])) 比例不等于0.5 */ printf("head=%d, middle=%d, tail=%d, count=%d \n", head, middle, tail, ++count); if (a[middle] == num) { flag = 1; printf("找到了,是a[%d]=%d, 一共查找了%d次 \n", middle, num, count); break; } else if (a[middle] > num) tail = middle - 1; else head = middle + 1; } if (flag == -1) printf("一共查找了%d次,未找到数据%d \n", count, num); } } void main() { int a[N], b[N]; srand((unsigned int)(time(NULL))); for (int i = 0; i < N; i++) { a[i] = i; b[i] = a[i] + rand() % 300; Sleep(rand() % 10); } for (int i = 0; i < N - 1; i++) { for (int j = 0; j < N - 1 - i; j++) { if (b[j] > b[j + 1]) { int temp = b[j]; b[j] = b[j + 1]; b[j + 1] = temp; } } } for (int i = 0; i < N; i++) printf("%d ", b[i]); int num; scanf("%d", &num); search(a, num); search(b, num); searchByLagrange(a, num); searchByLagrange(b, num); system("pause"); }
0005、插入排序法
#include <stdio.h> #include <stdlib.h> #include <time.h> #define N 20 void main() { srand((unsigned int)(time(NULL))); int a[N + 1] = { 0 }; for (int i = 0; i < N; i++) a[i] = rand() / 100; a[N] = 77; for (int i = 0; i < N + 1; i++) printf("%5d", a[i]); putchar('\n'); for (int i = 0; i < N; i++) // 冒泡排序(前N个元素) { for (int j = 0; j < N - 1 - i; j++) { if (a[j] > a[j + 1]) { int temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } } for (int i = 0; i < N + 1; i++) printf("%5d", a[i]); putchar('\n'); int temp = a[N]; int j = N; while (j > 0 && a[j - 1]>temp) { a[j] = a[j - 1]; // 数组元素向后平移 j--; } a[j] = temp; // 将temp插入到适合的位置 for (int i = 0; i < N + 1; i++) printf("%5d", a[i]); putchar('\n'); system("pause"); }
#include <stdio.h> #include <stdlib.h> #include <time.h> #define N 20 void main() { srand((unsigned int)(time(NULL))); int a[N + 1] = { 0 }; for (int i = 0; i < N; i++) a[i] = rand() / 100; a[N] = 77; for (int i = 0; i < N + 1; i++) printf("%5d", a[i]); putchar('\n'); for (int i = 1; i < N + 1; i++) // 整体插入排序 { int j = i; int temp = a[j]; while (j > 0 && a[j - 1]>temp) { a[j] = a[j - 1]; j--; } a[j] = temp; // 将temp插入到适合的位置 } for (int i = 0; i < N + 1; i++) printf("%5d", a[i]); putchar('\n'); system("pause"); }