主逻辑: 两个指针,指向头部和末尾,而后作交换,交换完成后头部指针向后移动,尾部指针向前移动,继续交换,直到头部指针地址大于尾部指针地址。node
char *begin = cha;
char *end = cha + strlen(cha) - 1;
while (begin < end) {
// 核心逻辑 -- 换值 移动
char ws_tmp = *begin;
*(begin++) = *end;
*(end--) = ws_tmp;
}
复制代码
主逻辑: 假设原链表为A->B->C->D->NULL,那么咱们须要新建一个链表NULL,而后对原链表就行遍历,让每个元素的Next指向新的链表。具体流程:先遍历到A,而后新链表变为A->NULL,再遍历到B,新链表变为B->A->NULL,以此类推...,最终获得翻转链表D->C->B->A->NULL算法
// 定义一个链表
struct WSNode {
int index;
struct WSNode *next;
}
复制代码
// 建立链表
struct WSNode* constructList(void)
{
// 头结点定义
struct WSNode *head = NULL;
// 记录当前尾结点
struct WSNode *cur = NULL;
for (int i = 1; i < 5; i++) {
struct WSNode *node = malloc(sizeof(struct WSNode));
node->index = i;
// 头结点为空,新结点即为头结点
if (head == NULL) {
head = node;
}
// 当前结点的next为新结点
else{
cur->next = node;
}
// 设置当前结点为新结点
cur = node;
}
return head;
}
复制代码
// 反转链表
struct WSNode* reverseList(struct WSNode *head)
{
// 定义遍历指针,初始化为头结点
struct WSNode *p = head;
// 反转后的链表头部
struct WSNode *newH = NULL;
// 遍历链表
while (p != NULL) {
// 记录下一个结点
struct WSNode *temp = p->next;
// 当前结点的next指向新链表头部
p->next = newH;
// 更改新链表头部为当前结点
newH = p;
// 移动p指针
p = temp;
}
// 返回反转后的链表头结点
return newH;
}
复制代码
主逻辑: 假设有数组A、B,新建数组C,长度为A+B,定义两个指针p和q,用来遍历A和B,再定义一个下标i来记录当前C的存储位置,开始遍历,若是A[p]<=B[q],那么把A[p]存放在C的i下标,而后p++,不然就是把B[q]存放到C的i下标,进行p++,最后A或者B遍历完后,将另一个未遍历完的剩余的数据添加到C的尾部。数组
//有序数组的合并,五个参数分别表明 数组A A的长度 数组B B的长度 数组C
void mergeList(int a[], int aLen, int b[], int bLen, int result[])
{
int p = 0; // 遍历数组a的指针
int q = 0; // 遍历数组b的指针
int i = 0; // 记录当前存储位置
// 任一数组没有到达边界则进行遍历
while (p < aLen && q < bLen) {
// 若是a数组对应位置的值小于b数组对应位置的值
if (a[p] <= b[q]) {
// 存储a数组的值
result[i] = a[p];
// 移动a数组的遍历指针
p++;
}
else{
// 存储b数组的值
result[i] = b[q];
// 移动b数组的遍历指针
q++;
}
// 指向合并结果的下一个存储位置
i++;
}
// 若是a数组有剩余
while (p < aLen) {
// 将a数组剩余部分拼接到合并结果的后面
result[i] = a[p++];
i++;
}
// 若是b数组有剩余
while (q < bLen) {
// 将b数组剩余部分拼接到合并结果的后面
result[i] = b[q++];
i++;
}
}
复制代码
主逻辑: 使用哈希,char类型是8位,因此有2^8种可能,创建一个256位的数组来记录每一个字符出现的次数,下标为字符对应的ASCII码值,值为对应出现的次数,而后进行字符串遍历,对数组进行设定。bash
char findFirstChar(char* cha)
{
char result = '\0';
// 定义一个数组 用来存储各个字母出现次数
int array[256];
// 初始化
for (int i=0; i<256; i++) {
array[i] = 0;
}
// 定义一个指针 指向当前字符串头部
char* p = cha;
// 遍历每一个字符
while (*p != '\0') {
// 在字母对应存储位置 进行出现次数+1操做,
// *(p++)为哈希函数,计算对应的index
array[*(p++)]++;
}
// 将p指针从新指向字符串头部
p = cha;
// 遍历每一个字母的出现次数
while (*p != '\0') {
// 遇到第一个出现次数为1的字符,打印结果
if (array[*p] == 1)
{
result = *p;
break;
}
// 反之继续向后遍历
p++;
}
return result;
}
复制代码
主逻辑: 先分别遍历获得视图A和视图B的全部的父视图Array,而后逆向遍历两个Array(逆序比正序少几回遍历比较),以下图,从D开始遍历函数
// 获取view的父视图数组
- (NSArray *)getSuperViewArrayWithView:(UIView *)view {
NSMutableArray *superArr = NSMutableArray.array;
UIView *temp = view.superview;
while (temp) {
[superArr addObject:temp];
temp = temp.superview;
}
return superArr;
}
复制代码
// 获取两个view的公共父视图数组
- (NSArray *)getCommonSuperViewWith:(UIView *)viewA andView:(UIView *)viewB {
NSMutableArray *commonArr = NSMutableArray.array;
NSArray *AArray = [self getSuperViewArrayWithView:viewA];
NSArray *BArray = [self getSuperViewArrayWithView:viewB];
for (int i = AArray.count - 1; i >= 0; i--) {
Class targetClass = AArray[i];
for (int j = BArray.count - 1; j >= 0; j--) {
if (targetClass == BArray[j]) {
[commonArr addObject:targetClass];
}
}
}
return commonArr;
}
复制代码
上面的算法是进行了两个for循环的嵌套,咱们来简化一下算法:ui
for (int i = AArray.count - 1; i >= 0; i--) {
Class targetClass = AArray[i];
if ([BArray containsObject:targetClass]) {
[commonArr addObject:targetClass];
}
}
复制代码
有一组数据:X1,X2...Xnspa
将它按从小到大的顺序排序为:X1,X2,...Xn指针
则当n为奇数时中位数为:X(n+1)/2 ;当N为偶数时中位数为(Xn/2 + X(n/2+1))/2code
主逻辑: :参考快速排序的逻辑,假设有n个数,随机选取一个数m,而后定义两个指针分别指向头和尾,左边指针取值跟m对比,比m小的话,指针日后移,右边指针也跟m对比,比m大的话,指针往前移,这样一次结束以后,比它小的就会放到左边,比它大的就会放到右边,记录此时头指针的下标,跟n/2相比较,若是大于n/2,那么就继续从左边这部分继续进行上面的遍历,若是小于n/2,就从右边继续遍历,直到最终头指针的下标位置 = n/2,说明找到了中位数。cdn
// 求一个无序数组的中位数
float ws_findMid(int a[], int aLen)
{
int low = 0;
int high = aLen - 1;
int mid = (aLen + 1) / 2 - 1; //减一是由于下标是从0开始,奇数跟偶数这里的mid都是同样的算法
int currentHeader = ws_partSort(a, low, high);
while (currentHeader != mid)
{
if (mid < currentHeader)
{
//左半区间找
currentHeader = ws_partSort(a, low, currentHeader - 1);
}
else
{
//右半区间找
currentHeader = ws_partSort(a, currentHeader + 1, high);
}
}
//找到了
float midNum = a[mid];
//奇偶判断
if(aLen %2 != 0)
return midNum;
float anotherMid = a[mid+1];
return (midNum + anotherMid)/2.0;
}
int ws_partSort(int a[], int start, int end)
{
int low = start;
int high = end;
//选取关键字
int key = a[start];
while (low < high)
{
//左边找比key大的值
while (low < high && a[low] < key)
{
++low;
}
//右边找比key小的值
while (low < high && a[high] > key)
{
--high;
}
if (low < high)
{
//找到以后交换左右的值
int temp = a[low];
a[low] = a[high];
a[high] = temp;
}
}
return low;
}
复制代码