算法基础部分整理-《图解算法》

2019你好!好好生活,好好工作!

1、二分查找法

基本思路:获取数组的中间值,将数组分割成两份,利用中间值跟指定的值进行比较,如果中间值大于指定的值,就在数组的左边进行查找;如果中间值小于指定值,就在数组的右边进行查找。如此循环的执行下去,最终找到符合的值。

优点:

1.速度快 2.比较次数少 3.性能好  

缺点也很明显:

1.必须是一个有序的数组(升序或者降序)

2.适用范围:适用不经常变动的数组

运行时间:O(logn)

 1 - (NSInteger)binary_searchInt:(NSArray *)array input:(NSInteger)input
 2 {
 3     
 4     NSInteger low = 0;
 5     NSInteger high = array.count - 1;
 6     while (low <= high) {
 7         NSInteger mid = (low + high)/2;
 8         NSNumber *tempNum = array[mid];
 9         if ([tempNum intValue] == input) {
10             return [tempNum intValue];
11             
12         }else if ([tempNum intValue] < input){
13             low = mid + 1;
14         }else if ([tempNum intValue] > input){
15             high = mid - 1;
16         }
17     }
18     return -1;
19     
20 }
OC实现
 1 int binary_search(int a[],int iPut , int high){
 2     int low = 0;
 3     while (low <= high){
 4         int mid = (low + high)/2;
 5         int tempNum = a[mid];
 6         if (tempNum == iPut) {
 7             return tempNum;
 8         }else if (tempNum > iPut){
 9             high = mid - 1;
10 
11         }else if(tempNum < iPut){
12             low = mid + 1;
13         }
14 
15     }
16     return -1;
17 }
C实现

2、选择排序

工作原理:

初始时在序列中找到最小(大)元素,放到序列的起始位置作为已排序序列;然后,再从剩余未排序元素中继续寻找最小(大)元素,放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

优点:移动数据的次数已知(n-1 次);

缺点:比较次数多,费时

运行时间:O(n*n)

 1 - (NSArray *)ocChoiceSort:(NSArray *)array
 2 {
 3     
 4     NSMutableArray *mutArray = [NSMutableArray arrayWithArray:array];
 5     for (int i = 0; i < mutArray.count - 1; i++) {
 6         for (int j = i+1; j<mutArray.count; j++) {
 7             if ([mutArray[i] intValue] > [mutArray[j] intValue]) {
 8                 NSNumber *tempNum = mutArray[i];
 9                 [mutArray replaceObjectAtIndex:i withObject:mutArray[j]];
10                 [mutArray replaceObjectAtIndex:j withObject:tempNum];
11             }
12         }
13     }
14 
15     return [mutArray copy];
16 }
OC选择排序
 1 void choiceSort(int a[],int len)
 2 {
 3     int i,j,temp;
 4     for (i=0; i<len-1; i++) {
 5         for (j=i+1; j<len; j++) {
 6             if (a[i]>a[j]) {
 7                 temp = a[i];
 8                 a[i]= a[j];
 9                 a[j]= temp;
10             }
11         }
12     }
13 }
C语言选择排序

3、冒泡排序

工作原理:

从第一个数开始,依次和后面的数作比较,数值小的往上浮。例如:一共五个数,那么第一个数依次和后面四个数作比较。如果第一个数大于后面的数后,交换之后再比较。依次类推。

优点: 简单

缺点:效率不高 

运行时间:O(n*n)

void maoPaoSort(int a[],int len)
{
    
    for(int i =0;i < len - 1; i++)
    {
        for(int j = 0;j < len - 1-i; j++)
        {
            if(a[j] < a[j+1])
            {
                int temp = a[j];
                a[j] = a[j+1];
                a[j+1] = temp;
            }
        }
    }
        
}
C语言冒泡

备注:冒泡和选择排序相似

4、快速排序

工作原理:

通过一轮的排序将序列分割成独立的两部分,其中一部分序列的关键字(这里主要用值来表示)均比另一部分关键字小。继续对长度较短的序列进行同样的分割,最后到达整体有序。在排序过程中,由于已经分开的两部分的元素不需要进行比较,故减少了比较次数,降低了排序时间。

详细描述:首先在要排序的序列 a 中选取一个中轴值,而后将序列分成两个部分,其中左边的部分 b 中的元素均小于或者等于 中轴值,右边的部分 c 的元素 均大于或者等于中轴值,而后通过递归调用快速排序的过程分别对两个部分进行排序,最后将两部分产生的结果合并即可得到最后的排序序列。

优点:极快,数据移动少.

缺点:不稳定

运行时间:O(logn)

这个算法也涉及到了递归调用

 1 //left是数组开始排序的下标,right是结尾的下标
 2 void quick_sort(int a[],int left,int right)
 3 {
 4     if (left >= right) {
 5         return;
 6     }
 7     int i = left,j = right, key = a[left];
 8     while (i < j) {
 9         //第一层while循环结束 表示y会根据key比较了一轮
10         
11         //寻找的条件是:1、找到一个小于或者等于key的值(小于或大于取决于想升序还是降序)2、i==j
12         while (i<j && key<=a[j]) {
13             //由最后向前寻找
14             j--;
15         }
16         a[i] = a[j];//填i坑,挖出j坑:找到这样一个数后把它赋值给前面的被拿走的i的值
17         //这个
18         while (i<j && key>=a[i]) {
19             //由最前向后寻找
20             i++;
21         }
22         a[j] = a[i];
23     }
24     a[i] = key;
25     //递归调用
26     quick_sort(a, left, i-1);
27     quick_sort(a, i+1, right);
28 }
C语言快速排序

5、递归

基本思想:

把规模大的问题转化为规模小的相似的子问题来解决。特别地,在函数实现时,因为解决大问题的方法和解决小问题的方法往往是同一个方法,所以就产生了函数调用它自身的情况,这也正是递归的定义所在。格外重要的是,这个解决问题的函数必须有明确的结束条件,否则就会导致无限递归的情况。

递归的三要素:

1、明确递归终止条件;

2、给出递归终止时的处理办法;

3、提取重复的逻辑,缩小问题规模。

递归的应用场景:

   在我们实际学习工作中,递归算法一般用于解决三类问题:

   (1). 问题的定义是按递归定义的(Fibonacci函数,阶乘,…);

   (2). 问题的解法是递归的(有些问题只能使用递归方法来解决,例如,汉诺塔问题,…);

   (3). 数据结构是递归的(链表、树等的操作,包括树的遍历,树的深度,…)。

猜你喜欢

转载自www.cnblogs.com/lisaloveyou1900/p/10206046.html