
思路:比较相邻的两钢,如果前一钢辞么就交换两钢,直到有?p>
时间复杂度O(n^2),稳定性:这是一种稳定的算法。
代码实现:
void bubble_sort(int arr[],size_t len){
size_t i,j;
for(i=0;i<len;i++){
bool hasSwap = false; //优化,判断数组是翻有戌果有性提前退撤
for(j=1;j<len-i;j++){ //这里j<len-i是翌耗肯定都是最船不需要多进行比较
if(arr[j-1]>arr[j]){ //如果前一
swap(&arr[j-1],&arr[j]); //交换两篙
hasSwap = true;
}
}
if(!hasSwap){
break;
}
}
}
思路:把一钢插入一感,使之一直维持有戌对于应该我们进行排旋组,我们可以让它的前i钢有谢哄入i+1钢,插入至合适的位置让之一直保持有斜至所有的数字有?p>
时间复杂度:O(n^2) 稳定性:稳定的算法
代码实现:
void insert_sort(int arr[],int len){
int i,j;
for(i=1;i<len;i++){
int key = arr[i]; //记录当前需要插入的数据
for(j= i-1;i>=0&&arr[j]>key;j--){ //找到插入的位置
arr[j+1] = arr[j]; //把需要插入的元素耗元素往
}
arr[j+1] = key; //插入该元素
}
}
思路:本质上是插入排蝎是借助半分查找法找到插入的位置,让效率稍微快一点。
时间复杂度:O(n^2),稳定性:稳定的算法。

代码实现:
void half_insert_sort(int arr[],int len){
int i,j;
for(i=1;i<len;i++){
int key = arr[i];
int left = 0;
int right = i-1;
while(left<=right){ //半分查找找到插入的位置
int mid = (left+right)/2;
if(key<arr[mid]){
right = mid-1;
}else{
left = mid+1;
}
}
for(j=i-1;j>=left;j--){ //把耗元素往
arr[j+1]=arr[j];
}
arr[j+1] = key; //插入元素
}
}
思路:先取一耕数d1<n,把所有朽改数组元素放一组,组内进行直接插入排谢?<d1,重复上书和排斜到di=1,即所有记录放进一感排泄。
时间复杂度:O(n^1.3) ,算法强度上瘁高 。稳定性:不稳定的算法。
代码实现:
void shell_sort(int arr[],int len){ //本质上也是一种插入排熊免了待据的移动,在每一组排锌篙已经到了茨位置。
int i,j;
int step=0;
for(step = len/2;step>=1;step=step/2){ //分组 分为step组,对每组的元素进行插入排序
for(i=step;i<len;i++){
int key = arr[i];
for(j=i-step;j>=0&&arr[j]>key;j=j-step){
arr[j+step] = arr[j];
}
arr[j+step] = key;
}
}
}
思路:通过循环找到更殆在的位置,然侯赐最贺进行交换,通过循环直至所有的数据有斜间复杂度:O(n^2) 稳定性:不稳定的算法
代码实现:
void select_sort(int arr[],size_t len){
size_t i,j;
for(i=0;i<len-1;i++){
int max = 0; //最绰标
for(j=1;j<len-i;j++){
if(arr[max]<arr[j]){ //找到最茨下标
max = j;
}
}
if(max!=j-1){
swap(&arr[max],&arr[j-1]); //把最贺和最带行交换
}
}
}
思路:选曰种改进,一次循环直接找到更赐最小值的位置,把更赐最贺进行交换,最小值跟更前一肛进行交换,所以很外层的循环只应该执行len/2次即可

时间复杂度:O(n^2) 稳定性:不稳定的算法
代码实现:
void cocktail_sort(int arr[],size_t len){
size_t i,j;
for(i=0;i<len/2;i++){
int max = i; //最绰标
int min = i; //最小值下标
for(j=i+1;j<len-i;j++){
if(arr[max]<arr[j]){ //找到最绰标
max = j;
}
if(arr[min]>arr[j]){ //找到最小值下标
min = j;
}
}
if(max!=j-1){
swap(&arr[max],&arr[j-1]); //交换最赐未进行排蓄贺
}
if(min == j-1){ //如果最小值在未进行排蓄好,那么经过最茨交换,已经交换到了最殆在的位置
min = max; //把最小值的坐标进行改变
}
if(min!=i){
swap(&arr[i],&arr[min]); //交换最小值和未进行排蓄前的元素
}
}
}
思路:把数据进行疮,然何交换堆顶(最春妥詈?在让堆顶重新疮,最悍过吴便有旋程:
最川Max Heapify):将堆的末端子节点,使得子节点永远小于父节点构建更川Build Max Heap):将堆中的所有数据再次排晓
堆排衑apSort):移除位在第一篙的根结点c语言链表冒泡排序,并啄递归运算时间复杂度:O(nlgn) 稳定性:不稳定的算法
实现代码:
void re_heap(int arr[],size_t index,size_t len){
size_t child = 2*index+1; //足坐标
int key = arr[index]; //当前节点值
while(child<len){
if(child+1<len&&arr[child]<arr[child+1]){ //如果右节点存在且右节点的值比足辞就child记录较蹿点的坐标
child++;
}
if(arr[child]>key){ //如节点的值比根节点的值大
arr[index] = arr[child]; //改变根节点的值
}else{
break;
}
index = child;
child = 2*index+1;
}
arr[index] = key; //插入记录好的值
}
void heap_sort(int arr[],size_t len){
int i;
for(i=len/2;i>=0;i--){
re_heap(arr,i,len); //对第i岗点进行疮
}
for(i=len-1;i>0;i--){
swap(&arr[0],&arr[i]); //交换第一割贺
re_heap(arr,0,i); //对第一肛进行疮
}
}
思路:通过一趟排歇排旋据分割成独立的两部份,其中一部分的所有数据都比另外一部分的所有数据都应小,然捍此方式对这两个别数据分毙快速排宣柑可以递归进行,以此达到整篙变成有行。过程:
(1)首先设置一哥值,通过该分界值将变量分成捉部分

(2)将蹿分界值的数据集中至数组右边,小于分界值的数据集中至数组的祝此时,卓分中肛都大于悔分界值,而右侧部分中肛都蹿分界值。
(3)然跟后面的数据可以独立排性于啄数组数据,又可以取一哥值,将该个别数据分成捉部分,同样在着置较小值,右边放置较矗右侧的数组数据也可以灼处理。
(4)重复上侍,可以看斥是一搁定义。通过递归将卓分排好鞋再递归排好右侧部分的顺斜滓两钢篙排猩蝴搁的排型完成了。时间复杂度:O(nlog2n) 稳定性:不稳定的算法
代码实现:
void quick_sort(int arr[],size_t left,size_t right){
if(left>=right){ //如果只有一肛,那就是有鞋返回
return;
}
int i = left;
int j = right;
int key = arr[left]; //基准值
while(i<j){ //找到基准值的位置,使得基准值右边的元素都比基准值茨元素都比基准值小
while(i<j&&arr[j]>=key){ //从右边找一根准值小的数,
--j;
}
arr[i] = arr[j];//把这概到基准值的位置处
while(i<j&&arr[i]<=key){ //从滓一根准值待
++i;
}
arr[j] = arr[i]; //把这肛放到j的位置
}
arr[i] = key;
if(i-left>1) //元素噶少两给行递归惮这样可以少一次递归
quick_sort(arr,left,i-1); //对基准值啄元素进行排序
if(right-i>1)
quick_sort(arr,i+1,right); //对基准值右边的元素进行排序
}
思路:对于两赣鞋可以把他们合并在一其成一改完全有鞋议并排徐排差不多,都是递归的进行。时间复杂度:O(nlog2n) 稳定性:稳定的算法代码实现:
void merge(int arr[],int left,int right){
int i,j,k;
int mid = (left+right)/2;
int len = mid-left+1;
int *temp = malloc(sizeof(arr[0])*len);
for(i=0;i<len;i++){
temp[i] = arr[i+left]; //把这搁的所有元素都复制到临时数组中
}
i=0,j=mid+1,k=left;
while(i<len&&j<=right){
if(temp[i]<arr[j]){ //把临时数组的元素和 [mid+1,right]这部分的元素一给行比较,如果谁小,那么arr里就存放谁的元素
arr[k++] = temp[i++];
}else{
arr[k++] = arr[j++];
}
}
while(i<len){ //如果temp这搁的元素还没有全部遍历完,那就把temp耗元素都复制到arr里面去,
//襯r[mid+1,right] 这部分的元素本来就是arr嚎分的有歇素,所以如果arr[mid+1,right]这部分没有遍历完也没关系的,
arr[k++] = temp[i++];
}
free(temp);
}
void merge_sort(int arr[],int left,int right){
if(left>=right){ //如果只有一肛说眯有星就返回
return;
}
int mid = (left+right)/2; //对两庚组进行排
merge_sort(arr,left,mid); //对[left,mid]这镐的元素进行排序
merge_sort(arr,mid+1,right); //对[mid+1,right]这镐内的元素进行排序
merge(arr,left,right); //这感的[left,mid]为有衃mid+1,right]也为有
}
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-137382-1.html
王建煊很有观察力
及时发扬国际主义精神