排序
一. 冒泡排序
如果数组是有序的,那么这种方法最快
代码:
void Bubble2(int* arr,int len) { int pMark = 0; for(int i = 0 ; i < len-1;i++) { pMark = 0; for(int j = 0; j < len - i - 1 ;j++) { if(arr[j] > arr[j+1]) { int k = arr[j]; arr[j] = arr[j+1]; arr[j+1] = k; pMark = j+1; } } if(pMark == 0) break; i = len - pMark -1; } }
进行了两次优化,每次将pMark置为0,如果判断后pMark仍然为零,那么没有交换数组元素,说明数组是有序的,则跳出循环。
第二次优化:如果数组是部分有序的,即后面元素是有序的,那么pMark记录有序的第一个元素下标,i减少循环次数,j随i的变化而变化。
二.选择排序
每次选出数组中最大的元素,然后从后向前依次放置
代码:
void Select(int* arr,int len ) { int max = 0; for(int i = 0; i < len - 1;i++) { max = 0; for(int j = 0; j < len - i ; j++) { if(arr[max] < arr[j]) max = j; } if(max != len-i-1) { arr[len-i-1] = arr[len-i-1]^arr[max]; arr[max] = arr[len-i-1]^arr[max]; arr[len-i-1] = arr[len-i-1]^arr[max]; } } }
找到数组中最小的,放在指定位置:(逻辑简单一些)
void SelectSort(int arr[],int nLength) { if(arr == NULL || nLength <=0)return; int nMin; int i; int j; for(i = 0;i<nLength-1;i++) { nMin = i; for(j = i;j<nLength;j++) { if(arr[nMin] > arr[j]) { nMin = j; } } //找到的最小值放前面 if(i != nMin) { arr[i] = arr[i]^arr[nMin]; arr[nMin] = arr[i]^arr[nMin]; arr[i] = arr[i]^arr[nMin]; } } }
三.插入排序
将数组分为:有序和无序两个部分
代码:
void InsertSort(int* arr,int len) { int j = 0;//有序的最后一个 int tmp = 0; //i 为无序的第一个 for(int i = 1; i < len;i++) { j = i-1; tmp = arr[i]; while(arr[j] > tmp && j>=0) { arr[j+1] = arr[j]; j--; } arr[j+1] = tmp; } }
四.计数排序不太好)
找到数组中最大值和最小值,然后开辟一个最大值-最小值长度的数组
数组下标表示该元素,值表示出现了多少次,
最后将原数组更新即可。
需要注意的是,这种方法只能用来排序数字,不能用来排序结构体,因为在最后覆盖的时候就会覆盖了我们还没用的地址。
void CountSort(int *arr,int len) { int min = arr[0]; int max = arr[0];
//找到最大值和最小值,用来申请数组 for(int i = 0; i < len; i++) { if(arr[i] > max) max = arr[i]; if(arr[i] < min) min = arr[i]; } int * tmp = (int*)malloc(sizeof(int)*(max-min+1)); //统计数量 for(int i = 0; i < len; i++) { tmp[arr[i]-min]++; } //放回数组 int j = 0; for(int i = 0;i < max-min+1; i++) { while(tmp[i] != 0) { arr[j] = i+min; j++; tmp[i]--; } } free(tmp); tmp = NULL; }