算法的基本思想和OC代码实现
一 、冒泡排序 (平均时间复杂度 o(N*N))
基本思想:两个数比较大小,较大的数下沉,较小的数冒起来。
过程:比较相邻的两个数据,如果第二个数小,就交换位置 从后向前两两比较,一直到比较最前两个数据。最终最小数被交换到起始的位置,这样第一个最小数的位置就排好了。
继续重复上述过程,依次将第2,3,….,n-1个最小数排好位置。
int arr[5]={23,21,45,23,64}; int temp; for (int i=0; i<4; i++) { for (int j=4; j>i; j--) { if (arr[j]<arr[j-1]) { temp=arr[j]; arr[j]=arr[j-1]; arr[j-1]=temp; } } } for (int i=0; i<5; i++) { NSLog(@" %d",arr[i]); } }
对冒泡排序进行优化(针对问题):数据的顺序排好之后,冒泡算法依然会继续进行下一轮的比较,直到arr.length-1次,后面的比较是没有意义的。
方案:设置参数flag,如果发生了交换,则将boolean类型的flag设置为ture;如果没有交换位置,则为false。这样当一轮比较没有发生交换,说明顺序并未发生变化,这轮比较就没有意义。
int temp; Boolean flag; int arr[5]={23,21,45,23,64}; for (int i=0; i<4; i++) { flag=false; for (int j=4; j>i; j--) { if (arr[j]<arr[j-1]) { temp=arr[j]; arr[j]=arr[j-1]; arr[j-1]=temp; flag=true; } } if (!flag) { break; } } for (int i=0; i<5; i++) { NSLog(@"%d",arr[i]); }
二、选择排序 (平均时间复杂度 o(N*N))
基本思想:在长度为N的无序数组汇总,第一次遍历n-1个数,找到最小的数值与第一个元素交换;第二次遍历n-2个数,找到最小的数值与第二个元素交换。。。。第n-1次遍历,找到最小的数值与第n-1个元素交换,完成排序。
int arr[5]={23,21,45,23,64}; for (int i=0; i<4; i++) { int minIndex=i; for (int j=i+1; j<5; j++) { if (arr[j]<arr[minIndex]) { minIndex=j; } } if (minIndex!=i) { int temp=arr[i]; arr[i]=arr[minIndex]; arr[minIndex]=temp; } } for (int i=0; i<5; i++) { NSLog(@"%d",arr[i]); }
三、插入排序 (平均时间复杂度 o(N*N))
基本思想:在要排序的一组中,假定前n-1个数已经排好序,现在将第n个数插到前面的有序数列中,使这n个数也是排好顺序的。如此反复循环,知道最后排好顺序。
int temp; int arr[5]={23,21,45,23,64}; for (int i=0; i<4; i++) { for (int j=i+1; j>0; j--) { if (arr[j]<arr[j-1]) { temp=arr[j-1]; arr[j-1]=arr[j]; arr[j]=temp; } else{ break; } } } for (int i=0; i<5; i++) { NSLog(@"%d",arr[i]); }
四、希尔排序
基本思想:在要排序的一组数中,根据某一增量分为若干个子序列,并对子序列分别进行插入排序。然后将增量减小,并重复上述过程,直至增量变为1,西施数据序列基本有序,最后进行插入排序。
int arr[5]={23,21,45,23,64}; int temp=0; int incre=5; while (true) { incre=incre/2; for (int k=0; k<5; k++) { for (int i=k+incre;i<5; i+=incre) for (int j=i; j>k; j-=incre) { if (arr[j]<arr[j-incre]) { temp=arr[j-incre]; arr[j-incre]=arr[j]; arr[j]=temp; } else{ break; } } } if (incre==1) { break; } } for (int i=0; i<5; i++) { NSLog(@"%d",arr[i]); }
五、快速排序 (平均时间复杂度 o(NlogN))
基本思想:1.先从数列中取出一个数作为key值
2.将比这个数小得数全部放在它的左边,大于它的数放在右边
3. 对左右两个小数列重复进行前两部操作,直至各区间只有1个数。
六、归并排序 (平均时间复杂度 o(NlogN))
基本思想:归并排序是建立在归并操作上的一种有效的排序算法。该算法是采取分治法的一个典型应用。
首先考虑下如何将2个有序数列合并。只要从比较2个数列的第一个数,谁小就先取谁,,取了之后舅子对应数列中删除这个数。然后进行再次比较,如果有数列为空,那直接将另一个数列的数据一次排列取出。
其余还有堆排序和基数排序,感兴趣的朋友可以上网查询相关思想及用法。