EKAlgorithms-常用数据结构Objective-C语言实现一数组排序
2015-12-01 11:23
791 查看
EKAlgorithms
EKAlgorithms is a set of computer exercises implemented inObjective-C. Data structures, well known algorithms, CS curiosities, you name it!
EKAgorithms
是一系列通过Objective-C语言实现的计算机代码。包含一些数据结构,众所周知的算法如排序,查找,字符串,二叉树,图
此文章只对该框架进行介绍,暂不讲解算法实现原理。
NSArray+EKStuff
1.获取数组中最大元素的索引
//返回数组最大值的下标 - (NSUInteger)indexOfMaximumElement { id maximumValue = [self firstObject]; <span style="color:#1d9421;"> //初始最大值下标为0 </span> NSUInteger indexOfMaximumValue = 0; NSUInteger count = [self count]; for (NSUInteger i = 1; i < count; i++) { id value = self[i]; if ([value compare:maximumValue] == NSOrderedDescending) { maximumValue = value; indexOfMaximumValue = i; } } return indexOfMaximumValue; }2.获取存储字符串数组的最长字符串
- (NSString *)longestString { NSString *returnValue = nil; for (NSString *string in self) { 4000 if (returnValue == nil || ([string length] > [returnValue length])) { returnValue = string; } } return returnValue; }3.求两个数组的交集
<span style="font-size:14px;"><strong>- (NSArray *)intersectionWithArray:(NSArray *)secondArray { NSMutableSet *intersection = [NSMutableSet setWithArray:self]; [intersection intersectSet:[NSSet setWithArray:secondArray]]; return [intersection allObjects]; }</strong></span>4.求两个数组的并集
- (NSArray *)unionWithoutDuplicatesWithArray:(NSArray *)secondArray { NSSet *firstSet = [NSSet setWithArray:self]; NSSet *secondSet = [NSSet setWithArray:secondArray]; NSMutableSet *resultSet = [NSMutableSet setWithSet:firstSet]; [resultSet unionSet:secondSet]; return [resultSet allObjects]; }5.获取数组中为字典的并集(指定的Key删除重复对象)
//获取数组中为字典的并集(指定的Key删除重复对象)</span> - (NSArray *)unionWithoutDuplicatesWithArray:(NSArray *)secondArray forKey:(NSString *)currentKey { NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:self]; [mutableArray addObjectsFromArray:secondArray]; NSArray *copy = [mutableArray copy]; NSUInteger index = [copy count] - 1; <span style="color:#009900;">//reverseObjectEnumerator倒序遍历</span> for (id object in [copy reverseObjectEnumerator]) { for (NSUInteger i = 0; i < index; i++) { if ([[mutableArray[i] valueForKey:currentKey] isEqualToString:[object valueForKey:currentKey]]){ [mutableArray removeObjectAtIndex:index]; break; } } index --; } return mutableArray; }6.检测数组中是否包含相同元素
- (BOOL)hasDuplicates { NSMutableDictionary *registry = [[NSMutableDictionary alloc] initWithCapacity:self.count]; for (id element in self) { NSNumber *elementHash = @([element hash]); if (registry[elementHash] == nil) { registry[elementHash] = element; } else { NSLog(@"-[NSArray hasDuplicates] found duplicate elements: %@ and %@", registry[elementHash], element); return YES; } } return NO; }
NSArray+EKSorting
7.判断数组元素是否有序排列
- (BOOL)isSorted { NSUInteger countMinusOne = self.count - 1; for (NSUInteger i = 0; i < countMinusOne; i++) { if ([self[i] compare:self[i + 1]] == NSOrderedDescending) { return NO; } } return YES; }8.数组逆置
- (NSMutableArray *)reverse { NSUInteger count = self.count; for (int i = 0; i < count / 2; i++) { [self exchangeObjectAtIndex:i withObjectAtIndex:(count - 1 - i)]; } return self; }9.冒泡排序
思想:设数组长度为N。
1.比较相邻的前后二个数据,如果前面数据大于后面的数据,就将二个数据交换。
2.这样对数组的第0个数据到N-1个数据进行一次遍历后,最大的一个数据就“沉”到数组第N-1个位置。
3.N=N-1,如果N不为0就重复前面二步,否则排序完成。
- (NSMutableArray *)naiveBubbleSort { NSUInteger count = [self count]; for (int i = 0; i < count; i++) { for (int j = 0; j < (count - 1); j++) { if ([self[j] compare:self[j + 1]] == NSOrderedDescending) { [self exchangeObjectAtIndex:j withObjectAtIndex:(j + 1)]; } } } return self; }10.插入排序
思想:每一步都将一个待排数据按其大小插入到已经排序的数据中的适当位置,直到全部插入完毕。
<span style="font-size:12px;">- (NSMutableArray *)insertionSort { NSUInteger count = self.count; for (int i = 1; i < count; i++) { for (int j = i; (j > 0) && ([self[j - 1] floatValue] > [self[j] floatValue]); j--) { [self exchangeObjectAtIndex:j withObjectAtIndex:(j - 1)]; } } return self; }</span>11.希尔排序
思想:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高。
- (NSMutableArray *)shellSort { NSUInteger count = [self count]; for (NSInteger i = count / 2; i > 0; i = i / 2) { for (NSInteger j = i; j < count; j++) { for (NSInteger k = j - i; k >= 0; k = k - i) { if ([self[k + 1] floatValue] >= [self[k] floatValue]) { break; } else { [self exchangeObjectAtIndex:k withObjectAtIndex:(k + i)]; } } } } return self; }12.归并排序
思想:利用递归和分而治之的技术将数据序列划分成为越来越小的半子表,再对半子表排序,最后再用递归步骤将排好序的半子表合并成为越来越大的有序序列
- (NSMutableArray *)mergeSort { NSUInteger count = [self count]; [self partitionArrayWithMinimalIndex:0 withMaximumIndex:(count - 1)]; return self; } - (void)partitionArrayWithMinimalIndex:(NSInteger)min withMaximumIndex:(NSInteger)max { NSInteger mid = 0; if (min < max) { mid = (min + max) / 2; [self partitionArrayWithMinimalIndex:min withMaximumIndex:mid]; [self partitionArrayWithMinimalIndex:mid + 1 withMaximumIndex:max]; [self mergeArrayWithMinimalIndex:min withMediumIndex:mid withMaximalIndex:max]; } } - (void)mergeArrayWithMinimalIndex:(NSInteger)min withMediumIndex:(NSInteger)mid withMaximalIndex:(NSInteger)max { NSMutableArray *temporaryArray = [NSMutableArray array]; NSUInteger count = [self count]; for (NSInteger i = 0; i < count; i++) { [temporaryArray addObject:[NSNull null]]; } NSInteger i = 0, j = 0, k = 0, m = 0; j = min; m = mid + 1; for (i = min; j <= mid && m <= max; i++) { if ([self[j] floatValue] <= [self[m] floatValue]) { temporaryArray[i] = self[j]; j++; } else { temporaryArray[i] = self[m]; m++; } } if (j > mid) { for (k = m; k <= max; k++) { temporaryArray[i] = self[k]; i++; } } else { for (k = j; k <= mid; k++) { temporaryArray[i] = self[k]; i++; } } for (k = min; k <= max; k++) { self[k] = temporaryArray[k]; } }13.选择排序
思想:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
- (NSMutableArray *)insertionSort { NSUInteger count = self.count; for (int i = 1; i < count; i++) { for (int j = i; (j > 0) && ([self[j - 1] floatValue] > [self[j] floatValue]); j--) { [self exchangeObjectAtIndex:j withObjectAtIndex:(j - 1)]; } } return self; }14.快速排序
思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列
- (NSMutableArray *)quickSortWithLeftIndex:(NSInteger)left withRightIndex:(NSInteger)right { NSInteger i = left; NSInteger j = right; id pivotalElement = nil; pivotalElement = self[(left + right) / 2]; do { while (([self[i] floatValue] < [pivotalElement floatValue]) && (i < right)) { i++; } while (([pivotalElement floatValue] < [self[j] floatValue]) && (j > left)) { j--; } if (i <= j) { [self exchangeObjectAtIndex:i withObjectAtIndex:j]; i++; j--; } } while (i <= j); if (left < j) { [self quickSortWithLeftIndex:left withRightIndex:j]; } if (i < right) { [self quickSortWithLeftIndex:i withRightIndex:right]; } return self; }15.基数排序
思想:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。
- (NSMutableArray *)radixSortForBase:(NSInteger)base { int max = [[self valueForKeyPath:@"@max.intValue"] intValue]; int numberOfSteps = (log(max) / log(base)) + 1; for (int i = 0; i < numberOfSteps; i++) { NSMutableArray *radixTable = [NSMutableArray makeRadixTableForArray:self forBase:base forDigit:i]; [self setArray:[NSMutableArray makeArrayFromRadixTable:radixTable]]; } return self; } + (NSMutableArray *)makeArrayFromRadixTable:(NSMutableArray *)radixTable { NSMutableArray *theArray = [NSMutableArray new]; for (SSRadixNode *bucketNode in radixTable) { SSRadixNode *bucket = bucketNode.next; while (bucket) { [theArray addObject:@(bucket.data)]; bucket = bucket.next; } } return theArray; } + (NSMutableArray *)makeRadixTableForArray:(NSMutableArray *)theArray forBase:(NSInteger)base forDigit:(NSInteger)digit { NSMutableArray *radixTable = [self getTableOfEmptyBucketsForSize:base]; for (int i = 0; i < theArray.count; i++) { NSInteger value = [theArray[i] integerValue]; NSInteger radixIndex = [self getExaminedNumber:value withBase:base atDigit:digit]; SSRadixNode *current = (SSRadixNode *)radixTable[radixIndex]; if (current.next) { while (current.next) { current = [current next]; } } SSRadixNode *newEntry = [SSRadixNode new]; newEntry.data = [theArray[i] intValue]; current.next = newEntry; } return radixTable; } + (NSMutableArray *)getTableOfEmptyBucketsForSize:(NSInteger)size { NSMutableArray *empty = [NSMutableArray new]; for (NSInteger i = 0; i < size; i++) { [empty addObject:[SSRadixNode new]]; } return empty; } + (NSInteger)getExaminedNumber:(NSInteger)number withBase:(NSInteger)base atDigit:(NSInteger)digit { NSInteger divisor = (digit == 0) ? 1 : (pow(base, digit)); return (number / divisor) % base; }16.堆排序
思想:利用堆的性质进行的一种选择排序
- (NSMutableArray *)heapSort { NSUInteger count = self.count; [self heapifyArrayWithSize:count]; NSInteger end = count - 1; while (end > 0) { [self exchangeObjectAtIndex:end withObjectAtIndex:0]; [self siftDownArrayWithStart:0 end:end - 1]; end--; } return self; } - (void)siftDownArrayWithStart:(NSInteger)startIndex end:(NSInteger)endIndex { NSInteger root = startIndex; while ((root * 2 + 1) <= endIndex) { NSInteger child = root * 2 + 1; if (chi 818b ld + 1 <= endIndex && [self[child] floatValue] < [self[child + 1] floatValue]) { child++; } if ([self[root] floatValue] < [self[child] floatValue]) { [self exchangeObjectAtIndex:root withObjectAtIndex:child]; root = child; } else { return; } } } - (void)heapifyArrayWithSize:(NSInteger)size { NSInteger start = (size - 2) / 2; while (start >= 0) { [self siftDownArrayWithStart:start end:size - 1]; start--; } }
相关文章推荐
- 《大话数据结构》之二叉树的四种遍历
- 浅谈算法和数据结构: 九 平衡查找树之红黑树
- [数据结构]队列的基本操作
- 【数据结构】建立和平衡AVL二叉树
- JavaScript数据结构 --- 散列
- 数据结构之栈
- 分治算法
- 数据结构例程——基数排序
- 数据结构例程——简单的计数排序
- 数据结构例程——归并排序
- 数据结构例程——选择排序之堆排序
- 枚举法的简单心得
- 【数据结构】栈结构操作示例
- 【数据结构】链表操作示例
- 【Educational Codeforces Round 2E】【STL-map 启发式合并 or 线段树动态开节点 】Lomsat gelral 一棵树每点一个颜色问每个节点子树的颜色众数之和
- 数据结构与算法-----队列-使用链表(链式结构)实现
- 第十二周--数据结构--非连通图的遍历之三
- 第九周 数据结构实践项目——数组和广义表【项目3.2-- 稀疏矩阵相加】
- 第十二周--数据结构--非连通图的遍历之二
- 【第14周-查找项目1-1——验证折半查找算法】