好久沒有記錄東西了,今天整理記錄一些常用的算法
時間復雜度:算法運行的時間
空間復雜度:算法運行完所需內存的大小
是不是穩定的算法:根據排序是相同的數據會不會被移動
一.冒泡排序
1.什么是冒泡排序?
答:冒泡排序算法的運作如下:(從后往前)
- 1.比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。
- 2.對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最后一對。在這一點,最后的元素應該會是最大的數。
- 3.針對所有的元素重復以上的步驟,除了最后一個。
- 4.持續每次對越來越少的元素重復上面的步驟,直到沒有任何一對數字需要比較。
2.時間復雜度 和 空間復雜度
冒泡排序的時間復雜度:O(n2)
冒泡排序的空間復雜度:O(1)
3.代碼
NSMutableArray * array = [NSMutableArray arrayWithObjects: @"1",@"8",@"2",@"7",@"2",@"5",@"9",nil];
//選擇
for (int i =0; i<[array count]-1; i++) {
for (int j = i+1; j<[array count]; j++) {
if ([array[i] intValue]>[array[j] intValue]) {
//交換
[array exchangeObjectAtIndex:i withObjectAtIndex:j];
}
}
}
NSLog(@"%@",array);
4.是否是穩定算法:是
二.快速排序———》遞歸
1.什么是快速排序?
答:設要排序的
數組是A[0]……A[N-1],首先任意選取一個數據(通常選用數組的第一個數)作為關鍵數據,然后將所有比它小的數都放到它前面,所有比它大的數都放到它后面,這個過程稱為一趟快速排序
一趟快速排序的算法是:
-
1)設置兩個變量i、j, 排序開始的時候:i=0,j=N-1;2)以第一個數組元素作為關鍵數據,賦值給key,即key=A[0];3)從j開始向前搜索,即由后開始向前搜索(j--),找到第一個小於key的值A[j],將A[j]和A[i]互換;4)從i開始向后搜索,即由前開始向后搜索(i++),找到第一個大於key的A[i],將A[i]和A[j]互換;5)重復第3、4步,直到i=j;
- 6)然后,對k兩邊的數據,再分組分別進行上述的過程,直到不能再分組為止
注意:第一遍快速排序不會直接得到最終結果,只會把比k大和比k小的數分到k的兩邊。為了得到最后結果,需要再次對下標2兩邊的數組分別執行此步驟,然后再分解數組,直到數組不能再分解為止(只有一個數據),才能得到正確結果。
2.時間復雜度 和 空間復雜度
快速排序的時間復雜度:O(n2)
快速排序的空間復雜度:O(log 2 N)~O(log n)
3.代碼
- (void)quickSortArray:(NSMutableArray *)array withLeftIndex:(NSInteger)leftIndex andRightIndex:(NSInteger)rightIndex
{
if (leftIndex >= rightIndex) {//如果數組長度為0或1時返回
return ;
}
NSInteger i = leftIndex;
NSInteger j = rightIndex;
//記錄比較基准數
NSInteger key = [array[i] integerValue];
while (i < j) {
/**** 首先從右邊j開始查找比基准數小的值 ***/
while (i < j && [array[j] integerValue] >= key) {//如果比基准數大,繼續查找
j--;
}
//如果比基准數小,則將查找到的小值調換到i的位置
NSNumber *temp = array[i];
array[i] = array[j];
array[j] = temp;
NSLog(@"%@",array);
/**** 當在右邊查找到一個比基准數小的值時,就從i開始往后找比基准數大的值 ***/
while (i < j && [array[i] integerValue] <= key) {//如果比基准數小,繼續查找
i++;
}
//如果比基准數大,則將查找到的大值調換到j的位置
NSNumber *bigTemp = array[j];
array[j] = array[i];
array[i] = bigTemp;
NSLog(@"%@",array);
}
//將基准數放到正確位置
array[i] = @(key);
/**** 遞歸排序 ***/
//排序基准數左邊的
[self quickSortArray:array withLeftIndex:leftIndex andRightIndex:i - 1];
//排序基准數右邊的
[self quickSortArray:array withLeftIndex:i + 1 andRightIndex:rightIndex];
{
if (leftIndex >= rightIndex) {//如果數組長度為0或1時返回
return ;
}
NSInteger i = leftIndex;
NSInteger j = rightIndex;
//記錄比較基准數
NSInteger key = [array[i] integerValue];
while (i < j) {
/**** 首先從右邊j開始查找比基准數小的值 ***/
while (i < j && [array[j] integerValue] >= key) {//如果比基准數大,繼續查找
j--;
}
//如果比基准數小,則將查找到的小值調換到i的位置
NSNumber *temp = array[i];
array[i] = array[j];
array[j] = temp;
NSLog(@"%@",array);
/**** 當在右邊查找到一個比基准數小的值時,就從i開始往后找比基准數大的值 ***/
while (i < j && [array[i] integerValue] <= key) {//如果比基准數小,繼續查找
i++;
}
//如果比基准數大,則將查找到的大值調換到j的位置
NSNumber *bigTemp = array[j];
array[j] = array[i];
array[i] = bigTemp;
NSLog(@"%@",array);
}
//將基准數放到正確位置
array[i] = @(key);
/**** 遞歸排序 ***/
//排序基准數左邊的
[self quickSortArray:array withLeftIndex:leftIndex andRightIndex:i - 1];
//排序基准數右邊的
[self quickSortArray:array withLeftIndex:i + 1 andRightIndex:rightIndex];
}
4.是否是穩定算法:否
三. 二分查找(折半查找)
折半查找方法適用於不經常變動而查找頻繁的有序列表
1.什么是 二分查找?
答:給一個數,要求查找出來,前提這個數組是一個升序的數組,取數組的中間值,與此數比較,若相等,則返回這個數,若找的數比中間數小,則在中間數的左側中再找,放在再右側找,知道找到為止。
一趟快速排序的算法是:
-
1)數組為有序2)以第一個數組元素作為關鍵數據,賦值給key,即key=A[0];3)從j開始向前搜索,即由后開始向前搜索(j--),找到第一個小於key的值A[j],將A[j]和A[i]互換;4)從i開始向后搜索,即由前開始向后搜索(i++),找到第一個大於key的A[i],將A[i]和A[j]互換;5)重復第3、4步,直到i=j;
- 6)然后,對k兩邊的數據,再分組分別進行上述的過程,直到不能再分組為止
注意:第一遍快速排序不會直接得到最終結果,只會把比k大和比k小的數分到k的兩邊。為了得到最后結果,需要再次對下標2兩邊的數組分別執行此步驟,然后再分解數組,直到數組不能再分解為止(只有一個數據),才能得到正確結果。
2.時間復雜度 和 空間復雜度
二分查找的時間復雜度:O(log n)
快速排序的空間復雜度:O(1)
3.代碼
-(NSInteger)searchNumWithArray:(NSArray *)array Num:(int)num
{
if (array.count <= 0) {
return -1;
}
int low = 0;
int height = (int)array.count - 1;
while (low <= height) {
int middle = (height - low)/2 + low;
if (num == [array[middle] integerValue]) {
return middle;
}else if (num < [array[middle] integerValue]){
return middle-1;
}else{
return middle+1;
}
}
return -1;
{
if (array.count <= 0) {
return -1;
}
int low = 0;
int height = (int)array.count - 1;
while (low <= height) {
int middle = (height - low)/2 + low;
if (num == [array[middle] integerValue]) {
return middle;
}else if (num < [array[middle] integerValue]){
return middle-1;
}else{
return middle+1;
}
}
return -1;
}
四. 選擇排序
1.什么是選擇排序?
答:每次找到最小的數才會交換
2, 1, 5, 4, 9
第一次排序:1, 2, 5, 4, 9
第二次排序: 1, 2, 5, 4, 9
第三次排序: 1, 2, 4, 5, 9
第四次排序: 1, 2, 4, 5, 9
(1)每次排序的時候都需要尋找第n小的數據,並且和array[n-1]發生交換
(2)等到n個數據都排序好,那么選擇排序結束。
2.時間復雜度 和 空間復雜度
選擇排序的時間復雜度:O(n 2)
選擇排序的空間復雜度:O(1)
3.代碼
- (NSMutableArray *)SelectSortOC:(NSMutableArray *)arr
{
for (int i=0; i < [arr count]-1; i++) {
for (int j = i+1; j<[arr count]; j++) {
if ([arr[i] integerValue] > [arr[j] integerValue]) {
[arr exchangeObjectAtIndex:i withObjectAtIndex:j];
}
}
}
return arr;
{
for (int i=0; i < [arr count]-1; i++) {
for (int j = i+1; j<[arr count]; j++) {
if ([arr[i] integerValue] > [arr[j] integerValue]) {
[arr exchangeObjectAtIndex:i withObjectAtIndex:j];
}
}
}
return arr;
}
4.是否是穩定算法:否
五. 插入排序
1.什么是插入排序?
答:每步將一個待排序的紀錄,按其關鍵碼值的大小插入前面已經排序的文件中適當位置上,直到全部插入完為止。
2.時間復雜度 和 空間復雜度
插入排序的時間復雜度:O(n 2)
插入排序的空間復雜度:O(1)
3.代碼
- (NSMutableArray *)InsertSortOC:(NSMutableArray *)arr
{
for (int i=1; i < [arr count]; i++) {
for (int j=0; j < i ; j++) {
if ([arr[i] integerValue] < [arr[j] integerValue]) {
[arr exchangeObjectAtIndex:i withObjectAtIndex:j];
}
}
}
return arr;
{
for (int i=1; i < [arr count]; i++) {
for (int j=0; j < i ; j++) {
if ([arr[i] integerValue] < [arr[j] integerValue]) {
[arr exchangeObjectAtIndex:i withObjectAtIndex:j];
}
}
}
return arr;
}
4.是否是穩定算法:是
