iOS常用算法和數據結構


數據結構通常分為四類:

1.集合結構  線性結構  樹形結構  圖形結構

1.1、集合結構:就是一個集合,就是一個圓圈中有很多個元素,元素與元素之間沒有任何關系 。

1.2、線性結構 :就是一個條線上站着很多個人。 這條線不一定是直的。也可以是彎的。也可以是值的 相當於一條線被分成了好幾段的樣子。 線性結構是一對一的關系。

1.3、樹形結構 :做開發的肯定或多或少的知道xml 解析  樹形結構跟他非常類似。也可以想象成一個金字塔。樹形結構是一對多的關系

1.4、圖形結構:這個就比較復雜了。 無窮、無邊、 無向(沒有方向)圖形機構 你可以理解為多對多 類似於我們人的交集關系。

2. 數據結構的存儲

      數據結構的存儲一般常用的有兩種   順序存儲結構 和 鏈式存儲結構。

2.1  順序存儲結構

      舉個列子。數組。1-2-3-4-5-6-7-8-9-10。這個就是一個順序存儲結構 ,存儲是按順序的 棧。做開發的都熟悉。棧是先進后出 ,后進先出的形式。hello world 在棧里面從棧底到棧頂的邏輯依次為 h-e-l-l-o-w-o-r-l-d 這就是順序存儲 再比如 隊列 ,隊列是先進先出的對吧,從頭到尾 h-e-l-l-o-w-o-r-l-d 就是這樣排對的。

2.2 鏈式存儲結構

      1-2-3-4-5-6-7-8-9-10  鏈式存儲就不一樣了 1(地址)-2(地址)-7(地址)-4(地址)-5(地址)-9(地址)-8(地址)-3(地址)-6(地址)-10(地址)。每個數字后面跟着一個地址 而且存儲形式不再是順序 ,也就說順序亂了,1(地址) 1后面跟着的這個地址指向的是2,2后面的地址指向的是3,3后面的地址指向是誰你應該清楚了吧。他執行的時候是 1(地址)-2(地址)-3(地址)-4(地址)-5(地址)-6(地址)-7(地址)-8(地址)-9(地址)-10(地址),但是存儲的時候就是完全隨機的。

3. 單向鏈表\雙向鏈表\循環鏈表

 3.1 單向鏈表   

          A->B->C->D->E->F->G->H. 這就是單向鏈表  H 是頭 A 是尾  像一個只有一個頭的火車一樣 只能一個頭拉着跑

3.2  雙向鏈表

     H<- A->B->C->D->E->F->G->H. 這就是雙向鏈表。有頭沒尾。兩邊都可以跑  跟地鐵一樣 到頭了 可以倒着開回來

3.3 循環鏈表 

     A->B->C->D->E->F->G->H. 繞成一個圈。就像蛇吃自己的這就是循環。

4.二叉樹/平衡二叉樹

4.1 什么是二叉樹

      樹形結構下,兩個節點以內 都稱之為二叉樹 不存在大於2 的節點 分為左子樹 右子樹 有順序 不能顛倒。

二叉樹有五種表現形式

     1. 空的樹(沒有節點)可以理解為什么都沒 像空氣一樣

    2. 只有根節點。 (理解一個人只有一個頭 其他的什么都沒,說的有點恐怖)

    3. 只有左子樹 (一個頭 一個左手 感覺越來越寫不下去了)

    4. 只有右子樹

   5 、左右子樹都有

二叉樹可以轉換成森林 樹也可以轉換成二叉樹。

5.算法,冒泡排序、選擇排序、插入排序、快速排序、二分法查找、希爾排序、戴克斯特拉算法,快捷算法,動態規划,堆排序,歸並排序。

 5.1 冒泡排序

1. 首先將所有待排序的數字放入工作列表中。

 2. 從列表的第一個數字到倒數第二個數字,逐個檢查:若某一位上的數字大於他的下一位,則將它與它的下一位交換。

 3. 重復2號步驟(倒數的數字加1。例如:第一次到倒數第二個數字,第二次到倒數第三個數字,依此類推...),直至再也不能交換。

 平均時間復雜度:O(n^2)

平均空間復雜度:O(1)

-(void)maoPao{//冒泡排序

    NSMutableArray *arr=[NSMutableArray arrayWithArray:@[@"17",@"28",@"36",@"15",@"29",@"39"]];

    for (int i=0;i<arr.count;i++) {

        for (int j=0; j<arr.count-1-i; j++) {

            if ([arr[j] intValue]>[arr[j+1] intValue]) {

                int temp=[arr[j] intValue];

                arr[j]=arr[j+1];

                arr[j+1]=[NSString stringWithFormat:@"%d",temp];

            }

        }

    }

    NSLog(@"%@",arr);

}

5.2 選擇排序

1. 設數組內存放了n個待排數字,數組下標從1開始,到n結束。

 2. i=1

 3. 從數組的第i個元素開始到第n個元素,尋找最小的元素。(具體過程為:先設arr[i]為最小,逐一比較,若遇到比之小的則交換)

 4. 將上一步找到的最小元素和第i位元素交換。

 5. 如果i=n-1算法結束,否則回到第3步

 平均時間復雜度:O(n^2)

 平均空間復雜度:O(1)

-(void)xuanZe{//選擇排序

    NSMutableArray *arr=[NSMutableArray arrayWithArray:@[@"17",@"28",@"36",@"15",@"29",@"39"]];

    for (int i=0;i<arr.count-1;i++) {

        for (int j=i+1; j<arr.count; j++) {

            if ([arr[i] intValue]>[arr[j] intValue]) {

                int temp=[arr[i] intValue];

                arr[i]=arr[j];

                arr[j]=[NSString stringWithFormat:@"%d",temp];

            }

        }

    }

    NSLog(@"%@",arr);

}

5.3 插入排序

 1. 從第一個元素開始,認為該元素已經是排好序的。 

 2. 取下一個元素,在已經排好序的元素序列中從后向前掃描。

 3. 如果已經排好序的序列中元素大於新元素,則將該元素往右移動一個位置。

 4. 重復步驟3,直到已排好序的元素小於或等於新元素。

 5. 在當前位置插入新元素。

 6. 重復步驟2。

 平均時間復雜度:O(n^2) 

 平均空間復雜度:O(1)

-(void)chaRu{//插入排序

    NSMutableArray *arr=[NSMutableArray arrayWithArray:@[@"17",@"28",@"36",@"15",@"29",@"39"]];

    for (int i=1;i<arr.count;i++) {

        int j=i;

        NSInteger temp=[[arr objectAtIndex:i]integerValue];

        while (j>0&&temp<[[arr objectAtIndex:j-1]integerValue]) {

            [arr replaceObjectAtIndex:j withObject:[arr objectAtIndex:(j-1)]];

            j--;

        }

        [arr replaceObjectAtIndex:j withObject:[NSNumber numberWithInteger:temp]];

    }

    NSLog(@"%@",arr);

}

5.4 希爾排序

-(void)xiEr{//希爾排序

    NSMutableArray *arr=[NSMutableArray arrayWithArray:@[@"17",@"28",@"36",@"15",@"29",@"39"]];

    NSInteger gap=arr.count/2;

    while (gap>=1) {

        for (NSInteger i=gap; i<arr.count; i++) {

            NSInteger temp=[[arr objectAtIndex:i] integerValue];

            NSInteger j=i;

            while (j>=gap&&temp<[[arr objectAtIndex:(j-gap)] integerValue]) {\

                [arr replaceObjectAtIndex:j withObject:[arr objectAtIndex:j-gap]];

                j-=gap;

            }

            [arr replaceObjectAtIndex:j withObject:[NSNumber numberWithInteger:temp]];

        }

        gap=gap/2;

    }

    NSLog(@"%@",arr);

}

5.5  二分法查找

當數據量很大適宜采用該方法。 采用二分法查找時,數據需是排好序的。 

 基本思想:假設數據是按升序排序的,對於給定值x,從序列的中間位置開始比較,如果當前位置值等於x,則查找成功;若x小於當前位置值,則在數列的前半段 中查找;若x大於當前位置值則在數列的后半段中繼續查找,直到找到為止。

- (NSInteger)BinarySearch:(NSArray *)array target:(id)key{//二分法查找

    NSInteger left = 0;    

    NSInteger right = [array count] - 1;

    NSInteger middle = [array count] / 2;

    while (right >= left) {

        middle = (right + left) / 2;

        if (array[middle] == key) {

            return middle;

        }

        if (array[middle] > key) {

            right = middle - 1;

        }

        else if (array[middle] < key) {

            left = middle + 1;

            

        }        

    }

    return -1;

}

5.6 快速排序

 1. 從數列中挑出一個元素,稱為 "基准"(pivot),

 2. 重新排序數列,所有元素比基准值小的擺放在基准前面,所有元素比基准值大的擺在基准的后面(相同的數可以到任一邊)。在這個分割之后,該基准是它的最后位置。這個稱為分割(partition)操作。

 3. 遞歸地(recursive)把小於基准值元素的子數列和大於基准值元素的子數列排序。

 遞回的最底部情形,是數列的大小是零或一,也就是永遠都已經被排序好了。雖然一直遞回下去,但是這個算法總會結束,因為在每次的迭代(iteration)中,它至少會把一個元素擺到它最后的位置去。

 平均時間復雜度:O(n^2)

 平均空間復雜度:O(nlogn)       O(nlogn)~O(n^2)

- (NSMutableArray *)QuickSorkOC:(NSMutableArray *)array Count:(NSInteger)count{//快速排序

    NSInteger i = 0;

    NSInteger j = count - 1;

    id pt = array[0];

    if (count > 1) {

        while (i < j) {

            for (; j > i; --j) {

                if (array[j] < pt) {

                    array[i++] = array[j];

                    break;

                }

            }

            for (; i < j; ++i) {

                if (array[i] > pt) {

                    array[j--] = array[i];

                    break;

                }

            }

            array[i] = pt;

            [self QuickSorkOC:array Count:i];

            [self QuickSorkOC:array Count:count - i - 1];

        }

    }

    return array;

}

5.7 歸並排序

把序列分成元素盡可能相等的兩半。  

把兩半元素分別進行排序。

把兩個有序表合並成一個。

- (void)megerSortAscendingOrderSort:(NSMutableArray *)ascendingArr

{

    NSMutableArray *tempArray = [NSMutableArray arrayWithCapacity:1];

    for (NSNumber *num in ascendingArr) {

        NSMutableArray *subArray = [NSMutableArray array];

        [subArray addObject:num];

        [tempArray addObject:subArray];

    }

    while (tempArray.count != 1) {

        NSInteger i = 0;

        while (i < tempArray.count - 1) {

            tempArray[i] = [self mergeArrayFirstList:tempArray[i] secondList:tempArray[i + 1]];

            [tempArray removeObjectAtIndex:i + 1];

            

            i++;

        }

    }

    NSLog(@"歸並升序排序結果:%@", ascendingArr);

}

 

- (NSArray *)mergeArrayFirstList:(NSArray *)array1 secondList:(NSArray *)array2 {

    NSMutableArray *resultArray = [NSMutableArray array];

    NSInteger firstIndex = 0, secondIndex = 0;

    while (firstIndex < array1.count && secondIndex < array2.count) {

        if ([array1[firstIndex] floatValue] < [array2[secondIndex] floatValue]) {

            [resultArray addObject:array1[firstIndex]];

            firstIndex++;

        } else {

            [resultArray addObject:array2[secondIndex]];

            secondIndex++;

        }

    }

    while (firstIndex < array1.count) {

        [resultArray addObject:array1[firstIndex]];

        firstIndex++;

    }

    while (secondIndex < array2.count) {

        [resultArray addObject:array2[secondIndex]];

        secondIndex++;

    }

    return resultArray.copy;

}

5.8 基數排序

- (void)radixAscendingOrderSort:(NSMutableArray *)ascendingArr

{

    NSMutableArray *buckt = [self createBucket];

    NSNumber *maxnumber = [self listMaxItem:ascendingArr];

    NSInteger maxLength = numberLength(maxnumber);

    for (int digit = 1; digit <= maxLength; digit++) {

        // 入桶

        for (NSNumber *item in ascendingArr) {

            NSInteger baseNumber = [self fetchBaseNumber:item digit:digit];

            NSMutableArray *mutArray = buckt[baseNumber];

            [mutArray addObject:item];

        }

        NSInteger index = 0;

        for (int i = 0; i < buckt.count; i++) {

            NSMutableArray *array = buckt[i];

            while (array.count != 0) {

                NSNumber *number = [array objectAtIndex:0];

                ascendingArr[index] = number;

                [array removeObjectAtIndex:0];

                index++;

            }

        }

    }

    NSLog(@"基數升序排序結果:%@", ascendingArr);

}

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM