内排序:不需要申请太多空间
外排序:与排序数量成正比
希尔排序
需要排序的数据
[N/2]
1与N/2+1, 2与N/2+2, 经过N/2次对比
[N/2/2]
[1]
归并排序
#include <stdio.h> #define DATA_ARRAY_LENGTH 12 void merge(int *data, int *temp, int start, int middle, int end) { int i = start, j = middle + 1, k = start; while (i <= middle && j <= end) { if (data[i] > data[j]) { temp[k++] = data[j++]; }else { temp[k++] = data[i++]; } } while (i <= middle){ temp[k++] = data[i++]; } while (j <= end) { temp[k++] = data[j++]; } for (i = start; i < end; i++){ data[i] = temp[i]; } } int merge_sort(int *data, int *temp, int start, int end) { int middle; if (start < end) { middle = start + (end - start) / 2; merge_sort(data, temp, start, middle); merge_sort(data, temp, middle + 1, end); merge(data, temp, start, middle, end); } } int main() { int data[DATA_ARRAY_LENGTH] = { 23, 64, 24, 12, 9, 16, 53, 57, 71, 79, 87, 97 }; int temp[DATA_ARRAY_LENGTH] = { 0 }; merge_sort(data, temp, 0, DATA_ARRAY_LENGTH-1);
return 0;
}
快速排序
1.快排为什么比冒泡排序速度快?如何选取快排的枢轴?怎样选效率会高一些?
2.请使用快排把数组从低到高排序,如数组 [10, 0, 3, 9, 2, 14, 8, 27, 1, 5, 8, -1, 26]
比哨兵大的放在后面,比哨兵小的放在前面
比哨兵大的集合里,再找一个哨兵
比哨兵小的集合里,再找一个哨兵
void quick(int *data, int start, int end) { if (start >= end) return; int i = start; int j = end; int key = data[start]; while (i < j){ while (i < j && key <= data[j]) { j--; } data[i] = data[j]; while (i < j && key >= data[i]){ i++; } data[j] = data[i]; } data[i] = key; quick(data, start, i - 1); quick(data, i + 1, end); } int quick_sort(int *data, int length) { quick(data, 0, length-1); return 0; } #define DATA_ARRAY_LENGTH 12 int main() { int data[DATA_ARRAY_LENGTH] = { 23, 64, 24, 12, 9, 16, 53, 57, 71, 79, 87, 97 }; quick_sort(data, DATA_ARRAY_LENGTH);
return 0;
}
堆排序
将数据看成二叉树,根据二叉树进行排序
https://www.bilibili.com/video/av841118899
KMP
如何在10G日志进行查找
for(i = 0; i < text_length; i++) { if(strcmp(text[i], pattern, pattern_length)) { } }
O(text_length * pattern_length)
O(M * N)
KMP算法能够使O(M * N) 成为 O(M + N)
回溯的步长,一定跟前后缀公共单元的长度有关系
void make_next(const char *pattern, int *next) { int q, k; int m = strlen(pattern); for (q = 1, k = 0; q < m; q++) { if (k > 0 && pattern[q] != pattern[k]) { k = next[k - 1]; } if (pattern[q] == pattern[k]) { k++; } next[q] = k; } } int kmp(const char *text, const char *pattern, int *next) { int n = strlen(text); int m = strlen(pattern); make_next(pattern, next); int i, q; for (i = 0, q = 0; i < n; i++) { while (q > 0 && pattern[q] != text[i]) { q = next[q - 1]; } if (pattern[q] == text[i]) { q++; } if (q == m) { break; } } return i - q + 1; } int main() { int i; int next[20] = { 0 }; const char *text = "ababxbababababcdababcabddcadfdsss"; const char *pattern = "abcabd"; int idx = kmp(text, pattern, next); printf("match pattern: %d ", idx); for (i = 0; i < strlen(pattern); i++) { printf("%4d", next[i]); } printf(" "); return 0; }
栈
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <assert.h> #define ALLOC_SIZE 512 typedef int KEY_TYPE; typedef struct _stack { KEY_TYPE *base; int top; int stack_size; } stack; void init_stack(stack *s) { s->base = (KEY_TYPE*)calloc(ALLOC_SIZE, sizeof(KEY_TYPE)); assert(s->base); s->top = 0; s->stack_size = ALLOC_SIZE; } void destroy_stack(stack *s) { assert(s); free(s->base); s->base = NULL; s->stack_size = 0; s->top = 0; } void push_stack(stack *s, KEY_TYPE data) { assert(s); if (s->top >= s->stack_size) { s->base = realloc(s->base, (s->stack_size + ALLOC_SIZE) * sizeof(KEY_TYPE)); assert(s->base); s->stack_size += ALLOC_SIZE; } s->base[s->top] = data; s->top ++; } void pop_stack(stack *s, KEY_TYPE *data) { assert(s); *data = s->base[--s->top]; } int empty_stack(stack *s) { return s->top == 0 ? 0 : 1; } int size_stack(stack *s) { return s->top; } int main() { stack s; init_stack(&s); int i = 0; for (i = 0;i < 1000;i ++) { push_stack(&s, i+1); } while (empty_stack(&s)) { int data; pop_stack(&s, &data); printf("%4d", data); } printf(" "); destroy_stack(&s); }