冒泡排序
void bubbleSort(int *nums,int numsSize){
int i,j,k,flag;
for(i=0;i<numsSize;i++){
flag = 0;
for(j=0;j<numsSize-i-1;j++){
if(nums[j]>nums[j+1]){
k = nums[j];
nums[j] = nums[j+1];
nums[j+1] = k;
flag = 1;
}
}
if(flag == 0)
break;
}
}
选择排序
void selectionSort(int* nums,int numsSize){
int i,j,k,n;
for(i=0;i<numsSize;i++){
k = i;
for(j=i;j<numsSize;j++){
if(nums[j] < nums[k]){
k = j;
}
}
n = nums[k];
nums[k] = nums[i];
nums[i] = n;
}
}
插入排序
void insertionSort(int* nums,int numsSize){
int i,j,key;
for(i=0;i<numsSize;i++){
key = nums[i];//哨兵
for(j=i-1;j>=0&&key<nums[j];j--)
nums[j+1] = nums[j];
nums[j+1] = key;
}
}
希尔排序
void shellSort(int* nums,int numsSize){
int i,j,k,l;
for(l=numsSize>>1;l>0;l>>=1)
{
for(i=l;i<numsSize;i++){
k = nums[i];
for(j=i-l;j>=0&&k<nums[j];j-=l)
nums[j+l] = nums[j];
nums[j+l] = k;
}
}
}
快速排序
void quickSort(int* nums,int numsSize){
if(numsSize<=1)
return;
int left,right,key;
key=nums[0];left=0;right=numsSize-1;
while(left<right){
while(left<right && key < nums[right]) right--;
nums[left] = nums[right];
while(left<right && key >= nums[left]) left++;
nums[right] = nums[left];
}
nums[left] = key;
quickSort(nums,left);
quickSort(nums+left+1,numsSize-left-1);
}
归并排序
void mergeSort(int* nums,int len){
if(len<=1)
return;
int mid_len = len/2;
mergeSort(nums,mid_len);
mergeSort(nums+mid_len,len-mid_len);
int *nums2 = malloc(sizeof(int) * len);
int i,j,k;
for(i=0,j=mid_len,k=0;i<mid_len&&j<len;){
if(nums[i] < nums[j])
nums2[k++] = nums[i++];
else
nums2[k++] = nums[j++];
}
while(i<mid_len)
nums2[k++] = nums[i++];
while(j<len)
nums2[k++] = nums[j++];
memmove(nums,nums2,sizeof(int) * len);
free(nums2);
}
堆排序
void heap_push(int *nums,int *numsSize,int key)//构造堆
{
int parent,child;
child = *numsSize;
(*numsSize)++;
parent = (child-1)/2;
while(child!=0){
if(nums[parent] < key){
nums[child] = nums[parent];
child = parent;
parent = (child-1)/2;
}else{
break;
}
}
nums[child] = key;
}
void heap_balance(int *nums,int numsSize)//平衡堆
{
if(numsSize<=0)
return;
int parent,child,key;
key = nums[0];
parent = 0;
child = parent*2+1;
if(child+1<numsSize && nums[child+1] > nums[child])
child++;
while(child < numsSize && key < nums[child]){
nums[parent] = nums[child];
parent = child;
child = parent*2+1;
if(child+1<numsSize && nums[child+1] > nums[child])
child++;
}
nums[parent] = key;
}
void heap_pop(int*nums,int numsSize){
}
void heapSort(int *nums,int numsSize)
{
int i,j;
int *heap = nums;
int heapSize = 0;
for(i=0;i<numsSize;i++)
heap_push(heap,&heapSize,nums[i]);
for(i=numsSize-1;i>0;i--){
j = nums[0];
nums[0] = nums[i];
nums[i] = j;
heap_balance(heap,--heapSize);
}
}
各种排序算法效率
int swap(int *a,int *b){
int c;
c = *a;
*a = *b;
*b = c;
}
int main(){
srand(time(NULL));
int *nums = NULL,*nums2;
int len = 100000;
int i,j;
time_t t1,t2;
nums = malloc(sizeof(int)*len);
nums2 = malloc(sizeof(int)*len);
for(i=0,j=0;i<len/2;i++,j++)
nums[i] = j;
for(i=len/2,j=0;i<len;i++,j++)
nums[i] = j;
for(i=len-1;i>0;i--)
{
j = rand()%i;
swap(&nums[i-1],&nums[j]);
}
memcpy(nums2,nums,sizeof(int)*len);
memcpy(nums,nums2,sizeof(int)*len);
t1 = time(NULL);
bubbleSort(nums,len);
t2 = time(NULL);
printf("bubbleSort seconds: %d\n",t2-t1);
memcpy(nums,nums2,sizeof(int)*len);
t1 = time(NULL);
selectionSort(nums,len);
t2 = time(NULL);
printf("selectionSort seconds: %d\n",t2-t1);
memcpy(nums,nums2,sizeof(int)*len);
t1 = time(NULL);
insertionSort(nums,len);
t2 = time(NULL);
printf("insertionSort seconds: %d\n",t2-t1);
memcpy(nums,nums2,sizeof(int)*len);
t1 = time(NULL);
shellSort(nums,len);
t2 = time(NULL);
printf("shellSort seconds: %d\n",t2-t1);
memcpy(nums,nums2,sizeof(int)*len);
t1 = time(NULL);
quickSort(nums,len);
t2 = time(NULL);
printf("quickSort seconds: %d\n",t2-t1);
memcpy(nums,nums2,sizeof(int)*len);
t1 = time(NULL);
mergeSort(nums,len);
t2 = time(NULL);
printf("mergeSort seconds: %d\n",t2-t1);
memcpy(nums,nums2,sizeof(int)*len);
t1 = time(NULL);
heapSort(nums,len);
t2 = time(NULL);
printf("heapSort seconds: %d\n",t2-t1);
}
100000排序
bubbleSort seconds: 87
selectionSort seconds: 35
insertionSort seconds: 28
shellSort seconds: 0
quickSort seconds: 1
mergeSort seconds: 0
heapSort seconds: 0
-------------------------------
bubbleSort seconds: 88
selectionSort seconds: 34
insertionSort seconds: 29
shellSort seconds: 0
quickSort seconds: 0
mergeSort seconds: 0
heapSort seconds: 0
-------------------------------
bubbleSort seconds: 87
selectionSort seconds: 35
insertionSort seconds: 29
shellSort seconds: 0
quickSort seconds: 0
mergeSort seconds: 0
heapSort seconds: 0
10000000排序
shellSort seconds: 18
quickSort seconds: 5
mergeSort seconds: 7
heapSort seconds: 14
-------------------------------
shellSort seconds: 18
quickSort seconds: 5
mergeSort seconds: 7
heapSort seconds: 14
-------------------------------
shellSort seconds: 17
quickSort seconds: 5
mergeSort seconds: 8
heapSort seconds: 13
基数排序,一般用来排序字符串,比如车牌号这些
基数排序,从后到前,只能用在等长字符串上
//从后往前,只能相同长度的字符串
void radixSort(char** s,int size,int length){
int count[128] = {0};
char **s_tmp = malloc(sizeof(char*)*size);
int i,j;
for(i=length-1;i>=0;i--){
memset(count,0,sizeof(count));
for(j=0;j<size;j++){
count[s[j][i]+1]++;
}
for(j=1;j<128;j++)
count[j] += count[j-1];
for(j=0;j<size;j++){
s_tmp[count[s[j][i]]++] = s[j];
}
for(j=0;j<size;j++){
s[j] = s_tmp[j];
}
}
free(s_tmp);
}
基数排序,从前到后,可用在不等长字符串上
//从前往后,不要求字符串等长
void radixSort(char** s,int size,int index){
if(size <= 1)
return;
int count[128] = {0};
char **s_tmp = malloc(sizeof(char*)*size);
int i,j;
for(i=0;i<size;i++){
count[s[i][index]+1]++;
}
for(i=1;i<128;i++)
count[i] += count[i-1];
for(i=0;i<size;i++){
s_tmp[count[s[i][index]]++] = s[i];
}
for(i=0;i<size;i++){
s[i] = s_tmp[i];
}
free(s_tmp);
for(i=1;i<128;i++){
radixSort(&s[count[i-1]],count[i]-count[i-1],index+1);
}
}
kmp算法,字符串查找
参考 https://oi-wiki.org/string/kmp/
int *generateNext(char *p,int p_len){
int *next = malloc(sizeof(int) * p_len);
next[0] = -1;
int i,j;
for(i=0,j=-1;i<p_len-1;){
if(j==-1||p[i] == p[j]){
next[++i] = ++j;
}else{
j = next[j];
}
}
return next;
}
int strStr(char* s,char* p){
if(s==NULL || p == NULL ||s[0]=='\0'||p[0]=='\0')
return -1;
int s_len = strlen(s);
int p_len = strlen(p);
int *next = generateNext(p,p_len);
int i,j;
for(i=0,j=0;i<s_len&&j<p_len;){
if(j==-1 || s[i] == p[j]){
i++;
j++;
}else{
j = next[j];
}
}
free(next);
if(j == p_len)
return i-j;
else
return -1;
}