From a2d615a9fc5e612c7cfee46fb5078ec34e096d4f Mon Sep 17 00:00:00 2001 From: nonstriater <410495266@qq.com> Date: Tue, 1 Dec 2015 12:51:40 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=93=BE=E8=A1=A8=E9=A2=98?= =?UTF-8?q?=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 开源项目中用到的算法/README.md | 9 ++-- 算法问题选编/堆和栈.md | 99 ++++++++++++++++++++++++---------- 算法问题选编/字符串.md | 12 ++++- 算法问题选编/链表.md | 10 ++-- 4 files changed, 90 insertions(+), 40 deletions(-) diff --git a/开源项目中用到的算法/README.md b/开源项目中用到的算法/README.md index e3f0c02..5b7030f 100644 --- a/开源项目中用到的算法/README.md +++ b/开源项目中用到的算法/README.md @@ -1,6 +1,7 @@ +## 开源项目中用到的算法 -数据结构往往是一个项目系统的核心,理解项目的数据结构和算法,才能真正理解项目的工作原理。这里聊聊常用`开源系统`中用到的数据结构和算法。 +数据结构往往是一个项目系统的核心,理解项目的数据结构和算法,才能真正理解项目的工作原理。这里聊聊常用`开源项目`中用到的数据结构和算法。 每一条说清楚: @@ -12,7 +13,7 @@ ### 项目简介 -YYCache 是iOS系统上一套线程安全的Key-Value缓存实现,使用Objective-C语言实现。YYCache使用双向链表+hash表结构实现。 +YYCache 是iOS系统上一套线程安全的Key-Value缓存实现,使用Objective-C语言实现。YYCache使用双向链表队列+hash表结构实现。 ### 用到的算法介绍 @@ -45,8 +46,8 @@ YYCache 是iOS系统上一套线程安全的Key-Value缓存实现,使用Object BOOL _releaseAsynchronously; } ``` -_dic 就是存储缓存节点的hash结构。 - +_dic 就是存储缓存节点的hash结构 +_head 指向链表的头部,_tail指向链表的尾部,组成一个队列结构 ## [cocos2d-objc](https://github.com/cocos2d/cocos2d-objc) diff --git a/算法问题选编/堆和栈.md b/算法问题选编/堆和栈.md index 6d39860..ea32f4f 100644 --- a/算法问题选编/堆和栈.md +++ b/算法问题选编/堆和栈.md @@ -1,21 +1,69 @@ +##堆和栈 + + +栈的数据结构结构 + +``` +typede int Value; +typedef struct Entry{ + Entry *next; + Value value; +}Entry; + +typedef struct Stack{ + Entry *head;/*添加和删除都在这个节点指针上*/ + int length; + int capacity; +}Stack; + +Stack create(unsigned int size); +void push(Stack,Value); +Value pop(Stack); + +``` + +队列的数据结构结构 + +``` +typede int Value; +typedef struct Entry{ + Entry *next; + Value value; +}Entry; + +typedef struct Queue{ + Entry *front;/*删除都在这个节点指针上*/ + Entry *rear;/*添加在这个节点指针上*/ + int length; +}Stack; + +void enqueue(Queue,Value); +void dequeue(Queue); +``` + + 这里的题目是有关栈和队列的问题。 #### 循环队列中元素个数 -如果用一个循环数组q[0..m-1]表示队列时,该队列只有一个队列头指针front不设队列尾指针rear,求这个队列中从队列头到队列尾的元素个数(包含队列头、队列尾) +如果用一个循环数组q[0..m-1]表示队列时,该队列只有一个队列头指针front,不设队列尾指针rear,求这个队列中从队列头到队列尾的元素个数(包含队列头、队列尾) 分析: + 有rear指针时: -if rear>front count = rear-front+1 -else count = rear-front+m+1 -综合,count = (rear-front+m+1)%m - -不用rear指针的话: -数据结构中加一个 int count来计数。 +``` +if (rear>front) + count = rear-front+1 +else + count = rear-front+m+1 +``` +综合: `count = (rear-front+m+1)%m` +不用rear指针的话: +数据结构中加一个 `int count`来计数。 @@ -38,46 +86,43 @@ a < f(top),把 a push 到 辅助栈中 - - #### 栈的push、pop序列 题目:输入两个整数序列。其中一个序列表示栈的push顺序,判断另一个序列有没有可能是对应的pop顺序。为了简单起见,我们假设push序列的任意两个整数都是不相等的。 -比如输入的push序列是1、2、3、4、5,那么4、5、3、2、1就有可能是一个pop系列。 +比如输入的push序列是[1、2、3、4、5] ,那么[4、5、3、2、1]就有可能是一个pop序列 + 因为可以有如下的push和pop序列: -push 1,push 2,push 3,push 4,pop,push 5,pop,pop,pop,pop, -这样得到的pop序列就是4、5、3、2、1。 -但序列4、3、5、1、2就不可能是push序列1、2、3、4、5的pop序列。 +【push 1,push 2,push 3,push 4,pop,push 5,pop,pop,pop,pop】 + +这样得到的pop序列就是【4、5、3、2、1】。 + +但序列【4、3、5、1、2】就不可能是push序列【1、2、3、4、5】的pop序列。 这里只是要判断是不是pop序列,并没有要求所有的pop序列 需要一个辅助栈(需要一个写好的栈结构辅助,如果是C语言,还要包装一个栈结构) -对序列A中的A[0]入栈,比较B[0] -如果不相等,A[1]入栈 -直到A[i] = B[0] -栈顶出栈,开始匹配B[1] -如果A[i-1]!=B[1],那就继续入栈A[i+1] +1. 对序列A中的A[0]入栈,比较B[0] +2. 如果不相等,A[1]入栈 +3. 直到A[i] = B[0] +4. 栈顶出栈,开始匹配B[1] +5. 如果A[i-1]!=B[1],那就继续入栈A[i+1] -循环往复~ -如果最后,栈为空,就是一个pop序列;如果栈不为空,或者B数组都没有遍历到尾部,就肯定不是pop序列了 +6 .循环往复~ +7. 如果最后,栈为空,就是一个pop序列;如果栈不为空,或者B数组都没有遍历到尾部,就肯定不是pop序列了 - - -### 颠倒栈 +#### 颠倒栈 题目:用递归颠倒一个栈。例如输入栈{1, 2, 3, 4, 5},1在栈顶。颠倒之后的栈为{5, 4, 3, 2, 1},5处在栈顶。 -思路一:所有元素pop出来,放到一个数组里,然后在从第一个元素开始入栈,空间复杂度需要 O(N) - +思路一:所有元素pop出来,放到一个数组里,然后在从第一个元素开始入栈,空间复杂度需要 O(N) 思路二: 递归方法。把栈看出2部分 :1 和 {2,3,4,5} , 把栈{2,3,4,5}颠倒过来,然后把1放到底部,那整个栈就颠倒过来了。 ``` -void reverseStack(){ - +void reverseStack(){ stack.pop(); reverseStack(); addTopToStackBottom(); diff --git a/算法问题选编/字符串.md b/算法问题选编/字符串.md index b75e19e..2bba6ee 100644 --- a/算法问题选编/字符串.md +++ b/算法问题选编/字符串.md @@ -10,7 +10,6 @@ * 子串 - #### 翻转句子中单词的顺序 题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。句子中单词以空格符隔开。 @@ -18,7 +17,7 @@ 例如输入“I am a student.”,则输出“student. a am I”。 ``` -char *revert(const char *source,char *dest); +char *revert_by_word(const char *source,char *dest); ``` 思路一:反向拷贝 @@ -35,6 +34,15 @@ b = a - b; a = a - b; ``` +最终示例代码: + +``` +char *revert_by_word(const char *source,char *dest){ + +} +``` + + 类似的题目还有: 不开辟用于交换数据的临时空间,如何完成字符串的逆序(在技术一轮面试中,有些面试官会这样问) diff --git a/算法问题选编/链表.md b/算法问题选编/链表.md index 9656279..a521e95 100644 --- a/算法问题选编/链表.md +++ b/算法问题选编/链表.md @@ -136,8 +136,7 @@ struct ListNode 输入一个链表的头结点,从尾到头反过来输出每个结点的值。链表结点定义如下: ``` -struct ListNode -{ +struct ListNode{ int m_nKey; ListNode* m_pNext; }; @@ -152,11 +151,9 @@ struct ListNode 题目:给定链表的头指针和一个结点指针,在O(1)时间删除该结点。链表结点的定义如下: ``` -struct ListNode -{ +struct ListNode{ int m_nKey; ListNode* m_pNext; - }; //函数的声明如下: @@ -174,8 +171,7 @@ void DeleteNode(ListNode* pListHead, ListNode* pToBeDeleted); 有双向循环链表结点定义为: ``` -struct node -{ +struct node{ int data; struct node *front,*next; };