From b8ab39aca9f1841375325910449f995929124e7a Mon Sep 17 00:00:00 2001 From: jinshaohui Date: Sun, 7 Oct 2018 12:00:34 -0400 Subject: [PATCH 01/69] add by j00322883 for dlist lru --- c-cpp/06_linkedlist/Dlist/Dlist.c | 220 ++++++++++++++++++++++++++++++ c-cpp/06_linkedlist/Dlist/Dlist.h | 23 ++++ 2 files changed, 243 insertions(+) create mode 100644 c-cpp/06_linkedlist/Dlist/Dlist.c create mode 100644 c-cpp/06_linkedlist/Dlist/Dlist.h diff --git a/c-cpp/06_linkedlist/Dlist/Dlist.c b/c-cpp/06_linkedlist/Dlist/Dlist.c new file mode 100644 index 00000000..d41cb456 --- /dev/null +++ b/c-cpp/06_linkedlist/Dlist/Dlist.c @@ -0,0 +1,220 @@ +/************************************************************************* + > File Name: Dlist.c + > Author: jinshaohui + > Mail: jinshaohui789@163.com + > Time: 18-10-07 + > Desc: + ************************************************************************/ +#include +#include +#include "./Dlist.h" + + + +void dlist_init(stDlistHead *dlist) +{ + dlist->size = 0; + dlist->head = NULL; + dlist->tail = NULL; + return; +} + +void dlist_destory(stDlistHead *dlist) +{ + stDlistNode *pNode = NULL; + + while(dlist->size > 0) + { + pNode = dlist->head; + dlist->head = dlist->head->next; + free(pNode); + dlist->size--; + } + + memset(dlist,0,sizeof(stDlistHead)); + + return; +} + +int dlist_insert_head(stDlistHead *dlist,stDlistNode *pNode,int data) +{ + if(pNode == NULL) + { + pNode = (stDlistNode *)malloc(sizeof(stDlistNode)); + if (pNode == NULL) + { + return -1; + } + } + + pNode->data = data; + pNode->prev = NULL; + pNode->next = NULL; + + if (dlist->size == 0) + { + dlist->head = pNode; + dlist->tail = pNode; + } + else + { + pNode->next = dlist->head; + dlist->head->prev = pNode; + dlist->head = pNode; + } + + dlist->size++; + return 0; +} + +stDlistNode * dlist_remove_tail(stDlistHead *dlist) +{ + stDlistNode *pNode = NULL; + + if(dlist->size == 0) + { + return NULL; + } + + pNode = dlist->tail; + if(dlist->size > 1) + { + dlist->tail = dlist->tail->prev; + dlist->tail->next = NULL; + } + else + { + dlist->head = NULL; + dlist->tail = NULL; + } + dlist->size--; + return pNode; +} + +void dlist_remove_node(stDlistHead * dlist,stDlistNode *pNode) +{ + if ((dlist == NULL)||(pNode == NULL)) + { + return; + } + + if (dlist->head == pNode) + { + dlist->head = dlist->head->next; + } + else if (dlist->tail == pNode) + { + dlist->tail = pNode->prev; + + dlist->tail->next = NULL; + } + else + { + pNode->prev->next = pNode->next; + pNode->next->prev = pNode->prev; + } + dlist->size--; + pNode->prev = NULL; + pNode->next = NULL; + + if (dlist->size == 0) + { + memset(dlist,0,sizeof(stDlistHead)); + } + + return; +} +stDlistNode * dlist_search(stDlistHead * dlist,int data) +{ + stDlistNode *pNode = dlist->head; + while(pNode != NULL) + { + if (pNode->data == data) + { + return pNode; + } + pNode = pNode->next; + + } + return NULL; +} + +void dlist_dump(stDlistHead *dlist) +{ + int no = 0; + stDlistNode *pNode = dlist->head; + while(pNode != NULL) + { + printf("\r\n [%d] = %d",no++,pNode->data); + pNode = pNode->next; + } + + return; +} + + +void Lru_dlist(stDlistHead *dlist,int data) +{ + stDlistNode *pNode = NULL; + + pNode = dlist_search(dlist,data); + if (pNode != NULL) + { + dlist_remove_node(dlist,pNode); + } + else if(dlist->size >= 4) + { + pNode = dlist_remove_tail(dlist); + + } + + dlist_insert_head(dlist ,pNode,data); + + return; +} + +int main() +{ + stDlistHead dlist = {0}; + stDlistNode * pNode = NULL; + + dlist_init(&dlist); + + printf("\r\n inset 1,2,3"); + dlist_insert_head(&dlist,NULL,1); + dlist_insert_head(&dlist,NULL,2); + dlist_insert_head(&dlist,NULL,3); + + dlist_dump(&dlist); + + pNode = dlist_remove_tail(&dlist); + if(pNode != NULL) + { + printf("\r\n remove %d",pNode->data); + } + dlist_insert_head(&dlist,pNode,4); + dlist_dump(&dlist); + + Lru_dlist(&dlist,5); + dlist_dump(&dlist); + Lru_dlist(&dlist,6); + dlist_dump(&dlist); + Lru_dlist(&dlist,7); + dlist_dump(&dlist); + Lru_dlist(&dlist,5); + dlist_dump(&dlist); + + + + while(dlist.size > 0) + { + pNode = dlist_remove_tail(&dlist); + if(pNode != NULL) + { + printf("\r\n remove %d",pNode->data); + free (pNode); + } + } + + return 0; +} diff --git a/c-cpp/06_linkedlist/Dlist/Dlist.h b/c-cpp/06_linkedlist/Dlist/Dlist.h new file mode 100644 index 00000000..1721692f --- /dev/null +++ b/c-cpp/06_linkedlist/Dlist/Dlist.h @@ -0,0 +1,23 @@ +/************************************************************************* + > File Name: Dlist.c + > Author: jinshaohui + > Mail: jinshaohui789@163.com + > Time: 18-10-07 + > Desc: + ************************************************************************/ +#include + +typedef struct DlistNode +{ + struct DlistNode *prev; + struct DlistNode *next; + int data; +}stDlistNode; + +typedef struct Dlisthead +{ + int size; + stDlistNode *head; + stDlistNode *tail; +}stDlistHead; + From 435174ee7e10f518139fa0bc443692cb25d27c26 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Mon, 8 Oct 2018 14:37:16 +0800 Subject: [PATCH 02/69] [git] update ignore scheme. --- .gitignore | 3 +++ c-cpp/.gitignore | 1 + 2 files changed, 4 insertions(+) create mode 100644 c-cpp/.gitignore diff --git a/.gitignore b/.gitignore index a1c2a238..31f5f1e9 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,6 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* + +# editor files +.vscode diff --git a/c-cpp/.gitignore b/c-cpp/.gitignore new file mode 100644 index 00000000..cba7efc8 --- /dev/null +++ b/c-cpp/.gitignore @@ -0,0 +1 @@ +a.out From 0f4ddb2410cdfe687751f024631699a62b96917f Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Mon, 8 Oct 2018 14:37:50 +0800 Subject: [PATCH 03/69] [07_linkedlist] impl of linked list node in Cxx. --- c-cpp/07_linkedlist/linked_list.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 c-cpp/07_linkedlist/linked_list.h diff --git a/c-cpp/07_linkedlist/linked_list.h b/c-cpp/07_linkedlist/linked_list.h new file mode 100644 index 00000000..2c118aa9 --- /dev/null +++ b/c-cpp/07_linkedlist/linked_list.h @@ -0,0 +1,27 @@ +/** + * 0) 遍历单链表 + * 1) 单链表反转 + * 2) 链表中环的检测 + * 3) 两个有序的链表合并 + * 4) 删除链表倒数第n个结点 + * 5) 求链表的中间结点 + * + * Author: Liam Huang (Liam0205) + */ + +#ifndef LINKEDLIST_LINKED_LIST_H_ +#define LINKEDLIST_LINKED_LIST_H_ + +#include + +template +struct Node { + using ptr_t = std::shared_ptr>; + T data; + ptr_t next; + + Node(T data_) : data(data_), next(nullptr) {} + Node() : next(nullptr) {} +}; + +#endif From 9c304af039b216c18ac777c76e17fa4a64e94626 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Mon, 8 Oct 2018 14:48:59 +0800 Subject: [PATCH 04/69] [07_linkedlist] impl of linked list operations in Cxx. --- c-cpp/.gitignore | 5 + c-cpp/07_linkedlist/linked_list_algo.hpp | 135 +++++++++++++++++++++++ c-cpp/07_linkedlist/main.cc | 21 ++++ 3 files changed, 161 insertions(+) create mode 100644 c-cpp/07_linkedlist/linked_list_algo.hpp create mode 100644 c-cpp/07_linkedlist/main.cc diff --git a/c-cpp/.gitignore b/c-cpp/.gitignore index cba7efc8..fe63436b 100644 --- a/c-cpp/.gitignore +++ b/c-cpp/.gitignore @@ -1 +1,6 @@ +# executives a.out + +# objective files +*.o +*.obj diff --git a/c-cpp/07_linkedlist/linked_list_algo.hpp b/c-cpp/07_linkedlist/linked_list_algo.hpp new file mode 100644 index 00000000..33fe0cb6 --- /dev/null +++ b/c-cpp/07_linkedlist/linked_list_algo.hpp @@ -0,0 +1,135 @@ +/** + * 0) 遍历单链表 + * 1) 单链表反转 + * 2) 链表中环的检测 + * 3) 两个有序的链表合并 + * 4) 删除链表倒数第n个结点 + * 5) 求链表的中间结点 + * + * Author: Liam Huang (Liam0205) + */ + +#ifndef LINKEDLIST_LINKED_LIST_ALGO_HPP_ +#define LINKEDLIST_LINKED_LIST_ALGO_HPP_ + +#include +#include + +#include "linked_list.h" + +template +void traverse(typename Node::ptr_t head, UnaryFunc do_traverse) { + auto sentry = std::make_shared>(); + sentry->next = head; + decltype(sentry) work = sentry; + while (work = work->next) { + do_traverse(work); + } +} + +template +typename Node::ptr_t reverse(typename Node::ptr_t head) { + if (nullptr == head or nullptr == head->next) { + return head; + } + decltype(head) prev = nullptr, curr = head, next = head->next; + while (nullptr != next) { + curr->next = prev; + prev = curr; + curr = next; + next = curr->next; + } + curr->next = prev; + return curr; +} + +template +bool check_circle(typename Node::ptr_t head) { + if (nullptr == head or nullptr == head->next) { + return false; + } + decltype(head) slow = head, fast = head; + while (nullptr != fast and nullptr != fast->next) { + slow = slow->next; + fast = fast->next->next; + if (slow == fast) { + return true; + } + } + return false; +} + +template +typename Node::ptr_t merge_two_sorted_lists(typename Node::ptr_t lhs, typename Node::ptr_t rhs) { + if (nullptr == lhs) { return rhs; } + if (nullptr == rhs) { return lhs; } + + decltype(lhs) l = lhs, r = rhs, head = nullptr, work = nullptr; + + if (l->data < r->data) { + head = l; + l = l->next; + } else { + head = r; + r = r->next; + } + work = head; + + while (nullptr != l and nullptr != r) { + if (l->data < r->data) { + work->next = l; + l = l->next; + } else { + work->next = r; + r = r->next; + } + work = work->next; + } + + if (nullptr != l) { + work->next = l; + } else { + work->next = r; + } + + return head; +} + +template +typename Node::ptr_t deleth_last_Kth(typename Node::ptr_t head, size_t n) { + decltype(head) sentry = std::make_shared>(); + sentry->next = head; + decltype(head) prev = sentry, curr = sentry->next, fast = sentry->next; + for (size_t i = 0; i != n; ++i) { + if (nullptr != fast) { + fast = fast->next; + } else { + return sentry->next; + } + } + while (nullptr != fast) { + prev = curr; + curr = curr->next; + fast = fast->next; + } + prev->next = curr->next; + return sentry->next; +} + +template +typename Node::ptr_t find_middle_node(typename Node::ptr_t head) { + if (nullptr == head or nullptr == head->next) { + return head; + } + decltype(head) slow = head, fast = head; + while (nullptr != fast and nullptr != fast->next) { + slow = slow->next; + fast = fast->next->next; + if (slow == fast) { + return nullptr; + } + } + return slow; +} + +#endif diff --git a/c-cpp/07_linkedlist/main.cc b/c-cpp/07_linkedlist/main.cc new file mode 100644 index 00000000..a6f41174 --- /dev/null +++ b/c-cpp/07_linkedlist/main.cc @@ -0,0 +1,21 @@ +#include +#include "linked_list.h" +#include "linked_list_algo.hpp" + +int main() { + typename Node::ptr_t head = nullptr; + head = std::make_shared>(1); + head->next = std::make_shared>(2); + head->next->next = std::make_shared>(3); + // head->next->next->next = head->next; // circle + + auto print_node = [&](typename Node::ptr_t node) { std::cout << node->data << ' '; }; + + traverse(head, print_node); + std::cout << std::endl; + auto mid = find_middle_node(head); + traverse(mid, print_node); + std::cout << std::endl; + + return 0; +} From da5e01e864c330457e9c0971857e0cc26474da4f Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Mon, 8 Oct 2018 14:51:53 +0800 Subject: [PATCH 05/69] [07_linkedlist] prittification of linked list operations in Cxx. --- c-cpp/07_linkedlist/linked_list_algo.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/c-cpp/07_linkedlist/linked_list_algo.hpp b/c-cpp/07_linkedlist/linked_list_algo.hpp index 33fe0cb6..f6a94ff1 100644 --- a/c-cpp/07_linkedlist/linked_list_algo.hpp +++ b/c-cpp/07_linkedlist/linked_list_algo.hpp @@ -60,7 +60,8 @@ bool check_circle(typename Node::ptr_t head) { } template -typename Node::ptr_t merge_two_sorted_lists(typename Node::ptr_t lhs, typename Node::ptr_t rhs) { +typename Node::ptr_t merge_two_sorted_lists(typename Node::ptr_t lhs, + typename Node::ptr_t rhs) { if (nullptr == lhs) { return rhs; } if (nullptr == rhs) { return lhs; } @@ -96,7 +97,8 @@ typename Node::ptr_t merge_two_sorted_lists(typename Node::ptr_t lhs, type } template -typename Node::ptr_t deleth_last_Kth(typename Node::ptr_t head, size_t n) { +typename Node::ptr_t deleth_last_Kth(typename Node::ptr_t head, + size_t n) { decltype(head) sentry = std::make_shared>(); sentry->next = head; decltype(head) prev = sentry, curr = sentry->next, fast = sentry->next; From 5d841d46af375fbfb79ce2be8485fc13632190a9 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Mon, 8 Oct 2018 15:27:12 +0800 Subject: [PATCH 06/69] [07_linkedlist] remove iostream in hpp. --- c-cpp/07_linkedlist/linked_list_algo.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/c-cpp/07_linkedlist/linked_list_algo.hpp b/c-cpp/07_linkedlist/linked_list_algo.hpp index f6a94ff1..7d5666cb 100644 --- a/c-cpp/07_linkedlist/linked_list_algo.hpp +++ b/c-cpp/07_linkedlist/linked_list_algo.hpp @@ -12,7 +12,6 @@ #ifndef LINKEDLIST_LINKED_LIST_ALGO_HPP_ #define LINKEDLIST_LINKED_LIST_ALGO_HPP_ -#include #include #include "linked_list.h" From f4911a7612e72ae64ac4f75d53daf50025c4f65f Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Mon, 8 Oct 2018 15:28:08 +0800 Subject: [PATCH 07/69] [07_linkedlist] updated comments. --- c-cpp/07_linkedlist/linked_list.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/c-cpp/07_linkedlist/linked_list.h b/c-cpp/07_linkedlist/linked_list.h index 2c118aa9..2eeb91e7 100644 --- a/c-cpp/07_linkedlist/linked_list.h +++ b/c-cpp/07_linkedlist/linked_list.h @@ -1,10 +1,5 @@ /** - * 0) 遍历单链表 - * 1) 单链表反转 - * 2) 链表中环的检测 - * 3) 两个有序的链表合并 - * 4) 删除链表倒数第n个结点 - * 5) 求链表的中间结点 + * 单链表 * * Author: Liam Huang (Liam0205) */ From a0b95e879916c5844ec1cb9f9b9a76ea12efde3e Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Mon, 8 Oct 2018 15:21:39 +0800 Subject: [PATCH 08/69] [08_stack] impl stack based on linked list, in Cxx. --- c-cpp/08_stack/linked_list.h | 22 ++++++++ c-cpp/08_stack/stack_based_on_linked_list.hpp | 52 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 c-cpp/08_stack/linked_list.h create mode 100644 c-cpp/08_stack/stack_based_on_linked_list.hpp diff --git a/c-cpp/08_stack/linked_list.h b/c-cpp/08_stack/linked_list.h new file mode 100644 index 00000000..cb7ef051 --- /dev/null +++ b/c-cpp/08_stack/linked_list.h @@ -0,0 +1,22 @@ +/** + * C++ 版本单链表结点 + * + * Author: Liam Huang (Liam0205) + */ + +#ifndef STACK_LINKED_LIST_H_ +#define STACK_LINKED_LIST_H_ + +#include + +template +struct Node { + using ptr_t = std::shared_ptr>; + T data; + ptr_t next; + + Node(T data_) : data(data_), next(nullptr) {} + Node() : next(nullptr) {} +}; + +#endif diff --git a/c-cpp/08_stack/stack_based_on_linked_list.hpp b/c-cpp/08_stack/stack_based_on_linked_list.hpp new file mode 100644 index 00000000..29959c9c --- /dev/null +++ b/c-cpp/08_stack/stack_based_on_linked_list.hpp @@ -0,0 +1,52 @@ +/** + * 基于链表实现的栈。 + * + * Author: Liam Huang (Liam0205) + */ + +#ifndef STACK_STACK_BASED_ON_LINKED_LIST_HPP_ +#define STACK_STACK_BASED_ON_LINKED_LIST_HPP_ + +#include +#include "linked_list.h" + +template +class Stack { + public: + using value_type = T; + using node_type = typename Node::ptr_t; + + private: + node_type top_ = nullptr; + + public: + bool empty(void) const { + return nullptr == top_; + } + void push(const value_type& value) { + auto node = std::make_shared(value); + if (this->empty()) { + top_ = node; + } else { + node->next = top_; + top_ = node; + } + } + value_type top(void) const { + if (not this->empty()) { + return top_->data; + } else { + throw "Fetch data from empty stack!"; + } + } + void pop(void) { + if (not this->empty()) { + top_ = top_->next; + return; + } else { + throw "Pop from empty stack!"; + } + } +}; + +#endif From 7a3f952e6d20e55d531f532191bf8a6a16be8f7d Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Mon, 8 Oct 2018 15:47:41 +0800 Subject: [PATCH 09/69] [07_linkedlist] remove test files. --- c-cpp/.gitignore | 3 +++ c-cpp/07_linkedlist/main.cc | 21 --------------------- 2 files changed, 3 insertions(+), 21 deletions(-) delete mode 100644 c-cpp/07_linkedlist/main.cc diff --git a/c-cpp/.gitignore b/c-cpp/.gitignore index fe63436b..541d3986 100644 --- a/c-cpp/.gitignore +++ b/c-cpp/.gitignore @@ -1,3 +1,6 @@ +# main files +main.* + # executives a.out diff --git a/c-cpp/07_linkedlist/main.cc b/c-cpp/07_linkedlist/main.cc deleted file mode 100644 index a6f41174..00000000 --- a/c-cpp/07_linkedlist/main.cc +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include "linked_list.h" -#include "linked_list_algo.hpp" - -int main() { - typename Node::ptr_t head = nullptr; - head = std::make_shared>(1); - head->next = std::make_shared>(2); - head->next->next = std::make_shared>(3); - // head->next->next->next = head->next; // circle - - auto print_node = [&](typename Node::ptr_t node) { std::cout << node->data << ' '; }; - - traverse(head, print_node); - std::cout << std::endl; - auto mid = find_middle_node(head); - traverse(mid, print_node); - std::cout << std::endl; - - return 0; -} From cd6c548fbb883699f9cb66e3f7dfb69a9c54c60c Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Mon, 8 Oct 2018 22:07:22 +0800 Subject: [PATCH 10/69] [07_linkedlist] update comment for guards. --- c-cpp/07_linkedlist/linked_list.h | 2 +- c-cpp/07_linkedlist/linked_list_algo.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/c-cpp/07_linkedlist/linked_list.h b/c-cpp/07_linkedlist/linked_list.h index 2eeb91e7..0a599750 100644 --- a/c-cpp/07_linkedlist/linked_list.h +++ b/c-cpp/07_linkedlist/linked_list.h @@ -19,4 +19,4 @@ struct Node { Node() : next(nullptr) {} }; -#endif +#endif // LINKEDLIST_LINKED_LIST_H_ diff --git a/c-cpp/07_linkedlist/linked_list_algo.hpp b/c-cpp/07_linkedlist/linked_list_algo.hpp index 7d5666cb..edb8e6b3 100644 --- a/c-cpp/07_linkedlist/linked_list_algo.hpp +++ b/c-cpp/07_linkedlist/linked_list_algo.hpp @@ -133,4 +133,4 @@ typename Node::ptr_t find_middle_node(typename Node::ptr_t head) { return slow; } -#endif +#endif // LINKEDLIST_LINKED_LIST_ALGO_HPP_ From 90c0e319a9b326dde592cefd1f96c0223ff0bc6f Mon Sep 17 00:00:00 2001 From: Smallfly Date: Tue, 9 Oct 2018 16:03:19 +0800 Subject: [PATCH 11/69] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E6=A0=88=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E6=95=B4=E5=9E=8B=E5=9B=9B=E5=88=99=E8=BF=90=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- object-c/08_stack/stack_practice/ArrayStack.h | 21 ++++ object-c/08_stack/stack_practice/ArrayStack.m | 49 +++++++++ .../08_stack/stack_practice/FourOperation.h | 22 ++++ .../08_stack/stack_practice/FourOperation.m | 102 ++++++++++++++++++ 4 files changed, 194 insertions(+) create mode 100644 object-c/08_stack/stack_practice/ArrayStack.h create mode 100644 object-c/08_stack/stack_practice/ArrayStack.m create mode 100644 object-c/08_stack/stack_practice/FourOperation.h create mode 100644 object-c/08_stack/stack_practice/FourOperation.m diff --git a/object-c/08_stack/stack_practice/ArrayStack.h b/object-c/08_stack/stack_practice/ArrayStack.h new file mode 100644 index 00000000..59d58aed --- /dev/null +++ b/object-c/08_stack/stack_practice/ArrayStack.h @@ -0,0 +1,21 @@ + +/** + 栈实现 + + Author: Smallfly + */ + +#import + +@interface Stack : NSObject + +- (id)initWithCapacity:(NSUInteger)count; + +- (BOOL)isEmpty; +- (id)top; +- (NSUInteger)size; + +- (BOOL)push:(id)obj; +- (id)pop; + +@end diff --git a/object-c/08_stack/stack_practice/ArrayStack.m b/object-c/08_stack/stack_practice/ArrayStack.m new file mode 100644 index 00000000..300fd37d --- /dev/null +++ b/object-c/08_stack/stack_practice/ArrayStack.m @@ -0,0 +1,49 @@ +#import "ArrayStack.h" + +@implementation Stack { + NSMutableArray *_arr; + NSUInteger _capacity; + NSUInteger _count; +} + +- (id)initWithCapacity:(NSUInteger)capacity { + self = [super init]; + _capacity = capacity; + _arr = [[NSMutableArray alloc] initWithCapacity:capacity]; + return self; +} + +- (BOOL)isEmpty { + return _arr.count == 0; +} + +- (BOOL)isFull { + return _arr.count == _capacity; +} + +- (id)top { + if ([self isEmpty]) return nil; + NSUInteger index = _arr.count - 1; + return _arr[index]; +} + +- (NSUInteger)size { + return _arr.count; +} + +- (BOOL)push:(id)obj { + if (!obj) return NO; + if (_arr.count == _capacity) return NO; + [_arr addObject:obj]; + return YES; +} + +- (id)pop { + if ([self isEmpty]) return nil; + NSUInteger index = _arr.count - 1; + id obj = _arr[index]; + [_arr removeLastObject]; + return obj; +} + +@end diff --git a/object-c/08_stack/stack_practice/FourOperation.h b/object-c/08_stack/stack_practice/FourOperation.h new file mode 100644 index 00000000..5228c0fc --- /dev/null +++ b/object-c/08_stack/stack_practice/FourOperation.h @@ -0,0 +1,22 @@ + +/** + 整型四则运算 + + Author: Smallfly + */ + +#import + +@interface FourOperation : NSObject + ++ (FourOperation *)shared; + +/** + 整型四则运算 + + @param expression 运算表达式,注意操作数和运算符之间要有空格 + @return 计算结果 + */ +- (NSNumber *)caculateExpression:(NSString *)expression; + +@end diff --git a/object-c/08_stack/stack_practice/FourOperation.m b/object-c/08_stack/stack_practice/FourOperation.m new file mode 100644 index 00000000..ed91e746 --- /dev/null +++ b/object-c/08_stack/stack_practice/FourOperation.m @@ -0,0 +1,102 @@ +#import "FourOperation.h" +#import "ArrayStack.h" + +NSDictionary *OptPriority() { + return @{@"*": @1, @"/": @1, @"+": @0, @"-": @0}; +} + +@implementation FourOperation { + @private + Stack *_optStack; + Stack *_numStack; + NSNumberFormatter *_numFormatter; +} + ++ (FourOperation *)shared { + static FourOperation* single = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + single = [FourOperation new]; + }); + return single; +} + +- (instancetype)init { + self = [super init]; + _optStack = [[Stack alloc] initWithCapacity:100]; + _numStack = [[Stack alloc] initWithCapacity:100]; + _numFormatter = [NSNumberFormatter new]; + return self; +} + +- (id)caculateExpression:(NSString *)expression { + NSArray *elements = [expression componentsSeparatedByString:@" "]; + + for (NSString *obj in elements) { + NSNumber *numb = [_numFormatter numberFromString:obj]; + if (numb) { // 运算数 + [_numStack push:numb]; + } else { // 操作符 + + // 如果栈顶操作符优先级大于等于当前操作符 + while ([self _topOperationPriorityIsHigherOrEqualToOperation:obj]) { + + // 取出栈顶的操作符和两个操作数做一次运算 + NSNumber *res = [self _excuteOnceCaculate]; + + // 计算结果存入栈 + [_numStack push:res]; + } + + [_optStack push:obj]; + } + } + + // 如果操作符存在栈中,依次取出做运算 + NSNumber *res = nil; + while ([_optStack top]) { + res = [self _excuteOnceCaculate]; + [_numStack push:res]; + } + return res; +} + +- (NSInteger)_getPriority:(NSString *)opt { + return [[OptPriority() objectForKey:opt] integerValue]; +} + +- (BOOL)_topOperationPriorityIsHigherOrEqualToOperation:(NSString *)opt { + NSString *topOpt = [_optStack top]; + if (!topOpt) return NO; + NSInteger curPriority = [self _getPriority:opt]; + NSInteger topPriority = [self _getPriority:topOpt]; + return curPriority <= topPriority; +} + +- (NSNumber *)_excuteOnceCaculate { + NSNumber *numRight = [_numStack pop]; + NSNumber *numLeft = [_numStack pop]; + NSString *topOpt = [_optStack pop]; + NSInteger result = [self _caculeteWithNumberLeft:numLeft numberRight:numRight operation:topOpt]; + NSNumber *res = [NSNumber numberWithInteger:result]; + return res; +} + +- (NSInteger)_caculeteWithNumberLeft:(NSNumber *)numLeft numberRight:(NSNumber *)numRight operation:(NSString *)opt { + if (!numLeft || !numRight || !opt) return 0; + NSInteger left = [numLeft integerValue]; + NSInteger right = [numRight integerValue]; + if ([opt isEqualToString:@"+"]) { + return left + right; + } else if ([opt isEqualToString:@"-"]) { + return left - right; + } else if ([opt isEqualToString:@"*"]) { + return left * right; + } else if ([opt isEqualToString:@"/"]) { + return left / right; + } else { + return 0; + } +} + +@end From 473ef5ae94c27b96ba0a660f1d9221ca0e41bad5 Mon Sep 17 00:00:00 2001 From: Smallfly Date: Tue, 9 Oct 2018 17:13:17 +0800 Subject: [PATCH 12/69] =?UTF-8?q?=E6=A0=88=E5=AE=9E=E7=8E=B0=E6=8B=AC?= =?UTF-8?q?=E5=8F=B7=E5=8C=B9=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../stack_practice/BalancedParentheses.h | 12 ++++++ .../stack_practice/BalancedParentheses.m | 37 +++++++++++++++++++ .../08_stack/stack_practice/FourOperation.m | 4 +- object-c/08_stack/stack_practice/main.m | 20 ++++++++++ 4 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 object-c/08_stack/stack_practice/BalancedParentheses.h create mode 100644 object-c/08_stack/stack_practice/BalancedParentheses.m create mode 100644 object-c/08_stack/stack_practice/main.m diff --git a/object-c/08_stack/stack_practice/BalancedParentheses.h b/object-c/08_stack/stack_practice/BalancedParentheses.h new file mode 100644 index 00000000..2b85ad74 --- /dev/null +++ b/object-c/08_stack/stack_practice/BalancedParentheses.h @@ -0,0 +1,12 @@ +/** + 判断括号是否匹配 {} [] () + + Author: Smallfly + */ +#import + +@interface BalancedParentheses : NSObject + +- (BOOL)checkForParenthessBlanced:(NSString *)express; + +@end diff --git a/object-c/08_stack/stack_practice/BalancedParentheses.m b/object-c/08_stack/stack_practice/BalancedParentheses.m new file mode 100644 index 00000000..551a3eee --- /dev/null +++ b/object-c/08_stack/stack_practice/BalancedParentheses.m @@ -0,0 +1,37 @@ + +#import "BalancedParentheses.h" +#import "ArrayStack.h" + +const NSDictionary *parenthesesDict() { + return @{@"(": @")", @"{": @"}", @"[": @"]"}; +} + +@implementation BalancedParentheses { + Stack *_stack; +} + +- (instancetype)init { + self = [super init]; + _stack = [[Stack alloc] initWithCapacity:100]; + return self; +} + +- (BOOL)checkForParenthessBlanced:(NSString *)express { + NSInteger midIndex = express.length / 2; + for (int i = 0; i < express.length; ++i) { + NSString *ele = [express substringWithRange:NSMakeRange(i, 1)]; + if (i < midIndex) { + // 前半部分把与 ele 匹配的括号加入栈 + [_stack push:parenthesesDict()[ele]]; + } else { + // 后半部分依次于栈顶的括号匹配 + NSString *topEle = [_stack pop]; + if (![topEle isEqualToString:ele]) { + return NO; + } + } + } + return YES; +} + +@end diff --git a/object-c/08_stack/stack_practice/FourOperation.m b/object-c/08_stack/stack_practice/FourOperation.m index ed91e746..5235b89b 100644 --- a/object-c/08_stack/stack_practice/FourOperation.m +++ b/object-c/08_stack/stack_practice/FourOperation.m @@ -1,7 +1,7 @@ #import "FourOperation.h" #import "ArrayStack.h" -NSDictionary *OptPriority() { +const NSDictionary *operationPriorityDict() { return @{@"*": @1, @"/": @1, @"+": @0, @"-": @0}; } @@ -62,7 +62,7 @@ - (id)caculateExpression:(NSString *)expression { } - (NSInteger)_getPriority:(NSString *)opt { - return [[OptPriority() objectForKey:opt] integerValue]; + return [[operationPriorityDict() objectForKey:opt] integerValue]; } - (BOOL)_topOperationPriorityIsHigherOrEqualToOperation:(NSString *)opt { diff --git a/object-c/08_stack/stack_practice/main.m b/object-c/08_stack/stack_practice/main.m new file mode 100644 index 00000000..6c2644f3 --- /dev/null +++ b/object-c/08_stack/stack_practice/main.m @@ -0,0 +1,20 @@ + +#import +#import "FourOperation.h" +#import "BalancedParentheses.h" + +int main(int argc, const char * argv[]) { + @autoreleasepool { + // 测试四则运算 + NSNumber *a = [[FourOperation shared] caculateExpression:@"10 - 4 / 2 * 3 + 3 - 6 / 2"]; + NSNumber *b = [[FourOperation shared] caculateExpression:@"10 - 3"]; + NSNumber *c = [[FourOperation shared] caculateExpression:@"2 * 3"]; + NSLog(@"FourOperation: %ld\t%ld\t%ld\t", a.integerValue, b.integerValue, c.integerValue); + + // 测试括号匹配 + BalancedParentheses *balancedCheck = [BalancedParentheses new]; + BOOL result = [balancedCheck checkForParenthessBlanced:@"([{{{}}}])"]; + NSLog(@"BalancedParentheses: %d", result); + } + return 0; +} From 7044c15abf61edfcf1f09faaaf9cde122aaf5b9b Mon Sep 17 00:00:00 2001 From: Smallfly Date: Tue, 9 Oct 2018 17:21:58 +0800 Subject: [PATCH 13/69] update comment --- object-c/08_stack/stack_practice/BalancedParentheses.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/object-c/08_stack/stack_practice/BalancedParentheses.m b/object-c/08_stack/stack_practice/BalancedParentheses.m index 551a3eee..67b3291d 100644 --- a/object-c/08_stack/stack_practice/BalancedParentheses.m +++ b/object-c/08_stack/stack_practice/BalancedParentheses.m @@ -24,7 +24,7 @@ - (BOOL)checkForParenthessBlanced:(NSString *)express { // 前半部分把与 ele 匹配的括号加入栈 [_stack push:parenthesesDict()[ele]]; } else { - // 后半部分依次于栈顶的括号匹配 + // 后半部分检查栈顶的元素与当前元素是否相同 NSString *topEle = [_stack pop]; if (![topEle isEqualToString:ele]) { return NO; From b10378fb0e513ec379c1ffdb040769d893096e34 Mon Sep 17 00:00:00 2001 From: Hkesd Date: Tue, 9 Oct 2018 17:34:34 +0800 Subject: [PATCH 14/69] php 07_linkedlist --- php/06_linkedlist/SingleLinkedList.php | 92 +++++- php/06_linkedlist/SingleLinkedListNode.php | 6 +- php/07_linkedlist/main.php | 308 +++++++++++++++++++++ php/README.md | 8 +- php/buildAutoLoad.sh | 3 + php/composer.json | 3 +- 6 files changed, 411 insertions(+), 9 deletions(-) create mode 100644 php/07_linkedlist/main.php create mode 100755 php/buildAutoLoad.sh diff --git a/php/06_linkedlist/SingleLinkedList.php b/php/06_linkedlist/SingleLinkedList.php index 164c63a4..59288601 100644 --- a/php/06_linkedlist/SingleLinkedList.php +++ b/php/06_linkedlist/SingleLinkedList.php @@ -35,10 +35,17 @@ class SingleLinkedList * 初始化单链表 * * SingleLinkedList constructor. + * + * @param null $head */ - public function __construct() + public function __construct($head = null) { - $this->head = new SingleLinkedListNode(); + if (null == $head) { + $this->head = new SingleLinkedListNode(); + } else { + $this->head = $head; + } + $this->length = 0; } @@ -145,19 +152,43 @@ public function printList() return false; } + $curNode = $this->head; + // 防止链表带环,控制遍历次数 + $listLength = $this->getLength(); + while ($curNode->next != null && $listLength--) { + echo $curNode->next->data . ' -> '; + + $curNode = $curNode->next; + } + echo 'NULL' . PHP_EOL; + + return true; + } + + /** + * 输出单链表 当data的数据为可输出类型 + * + * @return bool + */ + public function printListSimple() + { + if (null == $this->head->next) { + return false; + } + $curNode = $this->head; while ($curNode->next != null) { - echo $curNode->next->data . ' '; + echo $curNode->next->data . ' -> '; $curNode = $curNode->next; } - echo PHP_EOL; + echo 'NULL' . PHP_EOL; return true; } /** - * 在某个节点后插入新的节点 + * 在某个节点后插入新的节点 (直接插入数据) * * @param SingleLinkedListNode $originNode * @param $data @@ -207,4 +238,55 @@ public function insertDataBefore(SingleLinkedListNode $originNode, $data) return $this->insertDataAfter($preNode, $data); } + + /** + * 在某个节点后插入新的节点 + * + * @param SingleLinkedListNode $originNode + * @param SingleLinkedListNode $node + * + * @return SingleLinkedListNode|bool + */ + public function insertNodeAfter(SingleLinkedListNode $originNode, SingleLinkedListNode $node) + { + // 如果originNode为空,插入失败 + if (null == $originNode) { + return false; + } + + $node->next = $originNode->next; + $originNode->next = $node; + + $this->length++; + + return $node; + } + + /** + * 构造一个有环的链表 + */ + public function buildHasCircleList() + { + $data = [1, 2, 3, 4, 5, 6, 7, 8]; + + $node0 = new SingleLinkedListNode($data[0]); + $node1 = new SingleLinkedListNode($data[1]); + $node2 = new SingleLinkedListNode($data[2]); + $node3 = new SingleLinkedListNode($data[3]); + $node4 = new SingleLinkedListNode($data[4]); + $node5 = new SingleLinkedListNode($data[5]); + $node6 = new SingleLinkedListNode($data[6]); + $node7 = new SingleLinkedListNode($data[7]); + + $this->insertNodeAfter($this->head, $node0); + $this->insertNodeAfter($node0, $node1); + $this->insertNodeAfter($node1, $node2); + $this->insertNodeAfter($node2, $node3); + $this->insertNodeAfter($node3, $node4); + $this->insertNodeAfter($node4, $node5); + $this->insertNodeAfter($node5, $node6); + $this->insertNodeAfter($node6, $node7); + + $node7->next = $node4; + } } \ No newline at end of file diff --git a/php/06_linkedlist/SingleLinkedListNode.php b/php/06_linkedlist/SingleLinkedListNode.php index c6b4f43a..0b1ee09d 100644 --- a/php/06_linkedlist/SingleLinkedListNode.php +++ b/php/06_linkedlist/SingleLinkedListNode.php @@ -33,10 +33,12 @@ class SingleLinkedListNode /** * SingleLinkedListNode constructor. + * + * @param null $data */ - public function __construct() + public function __construct($data = null) { - $this->data = null; + $this->data = $data; $this->next = null; } } \ No newline at end of file diff --git a/php/07_linkedlist/main.php b/php/07_linkedlist/main.php new file mode 100644 index 00000000..736b0486 --- /dev/null +++ b/php/07_linkedlist/main.php @@ -0,0 +1,308 @@ +list = $list; + } + + /** + * 设置单链表 + * + * @param SingleLinkedList $list + */ + public function setList(SingleLinkedList $list) + { + $this->list = $list; + } + + /** + * 单链表反转 + * + * 三个指针反转 + * preNode 指向前一个结点 + * curNode 指向当前结点 + * remainNode 指向当前结点的下一个节点(保存未逆序的链表,为了在断开curNode的next指针后能找到后续节点) + * + * @return bool + */ + public function reverse() + { + if (null == $this->list || null == $this->list->head || null == $this->list->head->next) { + return false; + } + + $preNode = null; + $curNode = $this->list->head->next; + $remainNode = null; + + // 保存头结点,稍后指向反转后的链表 + $headNode = $this->list->head; + // 断开头结点的next指针 + $this->list->head->next = null; + + while ($curNode != null) { + $remainNode = $curNode->next; + $curNode->next = $preNode; + $preNode = $curNode; + $curNode = $remainNode; + } + + // 头结点指向反转后的链表 + $headNode->next = $preNode; + + return true; + } + + /** + * 判断链表是否有环 + * + * 快慢指针判断是否有环 + * @link http://t.cn/ROxpgQ1 + * + * @return bool + */ + public function checkCircle() + { + if (null == $this->list || null == $this->list->head || null == $this->list->head->next) { + return false; + } + + $slow = $this->list->head->next; + $fast = $this->list->head->next; + + while ($fast != null && $fast->next != null) { + $fast = $fast->next->next; + $slow = $slow->next; + + // 如果慢指针跟快指针相遇了说明有环 解释在上面的链接中 + if ($slow === $fast) { + return true; + } + } + + return false; + } + + /** + * 合并两个有序链表 + * + * @param SingleLinkedList $listA + * @param SingleLinkedList $listB + * + * @return SingleLinkedList|\Algo_06\SingleLinkedListNode + */ + public function mergerSortedList(SingleLinkedList $listA, SingleLinkedList $listB) + { + if (null == $listA) { + return $listB; + } + if (null == $listB) { + return $listA; + } + + $pListA = $listA->head->next; + $pListB = $listB->head->next; + $newList = new SingleLinkedList(); + $newHead = $newList->head; + $newRootNode = $newHead; + + while ($pListA != null && $pListB != null) { + if ($pListA->data <= $pListB->data) { + $newRootNode->next = $pListA; + $pListA = $pListA->next; + } else { + $newRootNode->next = $pListB; + $pListB = $pListB->next; + } + + $newRootNode = $newRootNode->next; + } + + // 如果第一个链表未处理完,拼接到新链表后面 + if ($pListA != null) { + $newRootNode->next = $pListA; + } + // 如果第二个链表未处理完,拼接到新链表后面 + if ($pListB != null) { + $newRootNode->next = $pListB; + } + + return $newList; + } + + /** + * 删除链表倒数第n个结点 + * + * @param $index + * + * @return bool + */ + public function deleteLastKth($index) + { + if (null == $this->list || null == $this->list->head || null == $this->list->head->next) { + return false; + } + + $i = 1; + $slow = $this->list->head; + $fast = $this->list->head; + while ($fast != null && $i < $index) { + $fast = $fast->next; + ++$i; + } + + if ($fast == null) { + return true; + } + + $pre = null; + while($fast->next != null) { + $pre = $slow; + $slow = $slow->next; + $fast = $fast->next; + } + + if (null == $pre) { + $this->list->head->next = $slow->next; + } else { + $pre->next = $pre->next->next; + } + + return true; + } + + /** + * 寻找中间节点 + * + * 快慢指针遍历 + * + * @return \Algo_06\SingleLinkedListNode|bool|null + */ + public function findMiddleNode() + { + if (null == $this->list || null == $this->list->head || null == $this->list->head->next) { + return false; + } + + $slow = $this->list->head->next; + $fast = $this->list->head->next; + + while ($fast != null && $fast->next != null) { + $fast = $fast->next->next; + $slow = $slow->next; + } + + return $slow; + } +} + +echo '---------------------- 单链表反转 ----------------------' . PHP_EOL . PHP_EOL; +$list = new SingleLinkedList(); +$list->insert(1); +$list->insert(2); +$list->insert(3); +$list->insert(4); +$list->insert(5); +$list->insert(6); +$list->insert(7); + +// 单链表反转 +$listAlgo = new SingleLinkedListAlgo($list); +$listAlgo->list->printList(); +$listAlgo->reverse(); +$listAlgo->list->printList(); +echo '--------------------------------------------------------' . PHP_EOL . PHP_EOL; + +echo '---------------------- 链表中环的检测 ----------------------'. PHP_EOL . PHP_EOL; +// 链表中环的检测 +$listCircle = new SingleLinkedList(); +$listCircle->buildHasCircleList(); +$listAlgo->setList($listCircle); +var_dump($listAlgo->checkCircle()); +echo '------------------------------------------------------------' . PHP_EOL . PHP_EOL; + +echo '---------------------- 两个有序的链表合并 ----------------------' . PHP_EOL . PHP_EOL; +// 两个有序的链表合并 +$listA = new SingleLinkedList(); +$listA->insert(9); +$listA->insert(7); +$listA->insert(5); +$listA->insert(3); +$listA->insert(1); +$listA->printList(); + +$listB = new SingleLinkedList(); +$listB->insert(10); +$listB->insert(8); +$listB->insert(6); +$listB->insert(4); +$listB->insert(2); +$listB->printList(); + +$listAlgoMerge = new SingleLinkedListAlgo(); +$newList = $listAlgoMerge->mergerSortedList($listA, $listB); +$newList->printListSimple(); +echo '----------------------------------------------------------------'. PHP_EOL . PHP_EOL; + +echo '---------------------- 删除链表倒数第n个结点 ----------------------' . PHP_EOL . PHP_EOL; +// 删除链表倒数第n个结点 +$listDelete = new SingleLinkedList(); +$listDelete->insert(1); +$listDelete->insert(2); +$listDelete->insert(3); +$listDelete->insert(4); +$listDelete->insert(5); +$listDelete->insert(6); +$listDelete->insert(7); +$listDelete->printList(); +$listAlgo->setList($listDelete); +$listAlgo->deleteLastKth(3); +var_dump($listAlgo->list->printListSimple()); +echo '------------------------------------------------------------------'. PHP_EOL . PHP_EOL; + +echo '---------------------- 求链表的中间结点 ----------------------' . PHP_EOL . PHP_EOL; +// 求链表的中间结点 +$listAlgo->setList($list); +$middleNode = $listAlgo->findMiddleNode(); +var_dump($middleNode->data); +echo '-------------------------------------------------------------'. PHP_EOL . PHP_EOL; \ No newline at end of file diff --git a/php/README.md b/php/README.md index e8da44a8..3aa96741 100644 --- a/php/README.md +++ b/php/README.md @@ -7,4 +7,10 @@ ### 项目实现 #### 06 * 单链表php实现 -* 回文判断 \ No newline at end of file +* 回文判断 +#### 07 +* reverse 单链表反转 +* checkCircle 链表中环的检测 +* mergerSortedList 两个有序的链表合并 +* deleteLastKth 删除链表倒数第n个结点 +* findMiddleNode 求链表的中间结点 \ No newline at end of file diff --git a/php/buildAutoLoad.sh b/php/buildAutoLoad.sh new file mode 100755 index 00000000..67680bc9 --- /dev/null +++ b/php/buildAutoLoad.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +composer dump-autoload \ No newline at end of file diff --git a/php/composer.json b/php/composer.json index 73d39e84..ea60240e 100644 --- a/php/composer.json +++ b/php/composer.json @@ -5,7 +5,8 @@ "require": {}, "autoload": { "psr-4": { - "Algo_06\\": "06_linkedlist/" + "Algo_06\\": "06_linkedlist/", + "Algo_07\\": "07_linkedlist/" } } } From ebeeb7e8a39d7ea722362fa33a28d487bd283cba Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 9 Oct 2018 22:35:37 +0800 Subject: [PATCH 15/69] fix issue#26 --- go/05_array/array.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/go/05_array/array.go b/go/05_array/array.go index 345cf3c7..ce2e05a4 100644 --- a/go/05_array/array.go +++ b/go/05_array/array.go @@ -32,8 +32,9 @@ func (this *Array) Len() uint { return this.length } +//判断索引是否越界 func (this *Array) isIndexOutOfRange(index uint) bool { - if this.length != 0 && index > this.length { + if index >= this.length { return true } return false @@ -52,7 +53,7 @@ func (this *Array) Insert(index uint, v int) error { if this.Len() == uint(cap(this.data)) { return errors.New("full array") } - if this.isIndexOutOfRange(index) { + if index != this.length && this.isIndexOutOfRange(index) { return errors.New("out of index range") } From e2b841f9847004f3aa3e9c3048664f36b38cead0 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 9 Oct 2018 23:54:01 +0800 Subject: [PATCH 16/69] 08_stack --- go/08_stack/SimpleBrowser.go | 56 ++++++++++++++++++ go/08_stack/SimpleBrowser_test.go | 29 ++++++++++ go/08_stack/StackBasedOnArray.go | 67 ++++++++++++++++++++++ go/08_stack/StackBasedOnArray_test.go | 41 +++++++++++++ go/08_stack/StackBasedOnLinkedList.go | 63 ++++++++++++++++++++ go/08_stack/StackBasedOnLinkedList_test.go | 41 +++++++++++++ go/08_stack/StatckInterface.go | 9 +++ 7 files changed, 306 insertions(+) create mode 100644 go/08_stack/SimpleBrowser.go create mode 100644 go/08_stack/SimpleBrowser_test.go create mode 100644 go/08_stack/StackBasedOnArray.go create mode 100644 go/08_stack/StackBasedOnArray_test.go create mode 100644 go/08_stack/StackBasedOnLinkedList.go create mode 100644 go/08_stack/StackBasedOnLinkedList_test.go create mode 100644 go/08_stack/StatckInterface.go diff --git a/go/08_stack/SimpleBrowser.go b/go/08_stack/SimpleBrowser.go new file mode 100644 index 00000000..b949fee7 --- /dev/null +++ b/go/08_stack/SimpleBrowser.go @@ -0,0 +1,56 @@ +package _8_stack + +import "fmt" + +type Browser struct { + forwardStack Stack + backStack Stack +} + +func NewBrowser() *Browser { + return &Browser{ + forwardStack: NewArrayStack(), + backStack: NewLinkedListStack(), + } +} + +func (this *Browser) CanForward() bool { + if this.forwardStack.IsEmpty() { + return false + } + return true +} + +func (this *Browser) CanBack() bool { + if this.backStack.IsEmpty() { + return false + } + return true +} + +func (this *Browser) Open(addr string) { + fmt.Printf("Open new addr %+v\n", addr) + this.forwardStack.Flush() +} + +func (this *Browser) PushBack(addr string) { + this.backStack.Push(addr) +} + +func (this *Browser) Forward() { + if this.forwardStack.IsEmpty() { + return + } + top := this.forwardStack.Pop() + this.backStack.Push(top) + fmt.Printf("forward to %+v\n", top) +} + +func (this *Browser) Back() { + if this.backStack.IsEmpty() { + return + } + top := this.backStack.Pop() + this.forwardStack.Push(top) + fmt.Printf("back to %+v\n", top) +} diff --git a/go/08_stack/SimpleBrowser_test.go b/go/08_stack/SimpleBrowser_test.go new file mode 100644 index 00000000..589a405c --- /dev/null +++ b/go/08_stack/SimpleBrowser_test.go @@ -0,0 +1,29 @@ +package _8_stack + +import "testing" + +func TestBrowser(t *testing.T) { + b := NewBrowser() + b.PushBack("www.qq.com") + b.PushBack("www.baidu.com") + b.PushBack("www.sina.com") + if b.CanBack() { + b.Back() + } + if b.CanForward() { + b.Forward() + } + if b.CanBack() { + b.Back() + } + if b.CanBack() { + b.Back() + } + if b.CanBack() { + b.Back() + } + b.Open("www.taobao.com") + if b.CanForward() { + b.Forward() + } +} diff --git a/go/08_stack/StackBasedOnArray.go b/go/08_stack/StackBasedOnArray.go new file mode 100644 index 00000000..cdecbf8b --- /dev/null +++ b/go/08_stack/StackBasedOnArray.go @@ -0,0 +1,67 @@ +package _8_stack + +import "fmt" + +/* +基于数组实现的栈 +*/ + +type ArrayStack struct { + //数据 + data []interface{} + //栈顶指针 + top int +} + +func NewArrayStack() *ArrayStack { + return &ArrayStack{ + data: make([]interface{}, 0, 32), + top: -1, + } +} + +func (this *ArrayStack) IsEmpty() bool { + if this.top < 0 { + return true + } + return false +} + +func (this *ArrayStack) Push(v interface{}) { + this.data = append(this.data, v) + if this.top < 0 { + this.top = 0 + } else { + this.top += 1 + } +} + +func (this *ArrayStack) Pop() interface{} { + if this.IsEmpty() { + return nil + } + v := this.data[this.top] + this.top -= 1 + return v +} + +func (this *ArrayStack) Top() interface{} { + if this.IsEmpty() { + return nil + } + return this.data[this.top] +} + +func (this *ArrayStack) Flush() { + this.top = -1 +} + +func (this *ArrayStack) Print() { + if this.IsEmpty() { + fmt.Println("empty statck") + } else { + for i := this.top; i >= 0; i-- { + fmt.Println(this.data[i]) + } + } +} diff --git a/go/08_stack/StackBasedOnArray_test.go b/go/08_stack/StackBasedOnArray_test.go new file mode 100644 index 00000000..0a6ea7dd --- /dev/null +++ b/go/08_stack/StackBasedOnArray_test.go @@ -0,0 +1,41 @@ +package _8_stack + +import "testing" + +func TestArrayStack_Push(t *testing.T) { + s := NewArrayStack() + s.Push(1) + s.Push(2) + s.Push(3) + s.Print() +} + +func TestArrayStack_Pop(t *testing.T) { + s := NewArrayStack() + s.Push(1) + s.Push(2) + s.Push(3) + s.Print() + + t.Log(s.Pop()) + t.Log(s.Pop()) + t.Log(s.Pop()) + t.Log(s.Pop()) + s.Print() +} + +func TestArrayStack_Top(t *testing.T) { + s := NewArrayStack() + s.Push(1) + s.Push(2) + s.Push(3) + + t.Log(s.Top()) + s.Pop() + t.Log(s.Top()) + s.Pop() + t.Log(s.Top()) + s.Pop() + t.Log(s.Top()) + s.Pop() +} diff --git a/go/08_stack/StackBasedOnLinkedList.go b/go/08_stack/StackBasedOnLinkedList.go new file mode 100644 index 00000000..ef4fef40 --- /dev/null +++ b/go/08_stack/StackBasedOnLinkedList.go @@ -0,0 +1,63 @@ +package _8_stack + +import "fmt" + +/* +基于链表实现的栈 +*/ +type node struct { + next *node + val interface{} +} + +type LinkedListStack struct { + //栈顶节点 + topNode *node +} + +func NewLinkedListStack() *LinkedListStack { + return &LinkedListStack{nil} +} + +func (this *LinkedListStack) IsEmpty() bool { + if this.topNode == nil { + return true + } + return false +} + +func (this *LinkedListStack) Push(v interface{}) { + this.topNode = &node{next: this.topNode, val: v} +} + +func (this *LinkedListStack) Pop() interface{} { + if this.IsEmpty() { + return nil + } + v := this.topNode.val + this.topNode = this.topNode.next + return v +} + +func (this *LinkedListStack) Top() interface{} { + if this.IsEmpty() { + return nil + } + return this.topNode.val +} + +func (this *LinkedListStack) Flush() { + this.topNode = nil +} + +func (this *LinkedListStack) Print() { + if this.IsEmpty() { + fmt.Println("empty stack") + } else { + cur := this.topNode + for nil != cur { + fmt.Println(cur.val) + cur = cur.next + } + } +} diff --git a/go/08_stack/StackBasedOnLinkedList_test.go b/go/08_stack/StackBasedOnLinkedList_test.go new file mode 100644 index 00000000..e047cc9d --- /dev/null +++ b/go/08_stack/StackBasedOnLinkedList_test.go @@ -0,0 +1,41 @@ +package _8_stack + +import "testing" + +func TestLinkedListStack_Push(t *testing.T) { + s := NewLinkedListStack() + s.Push(1) + s.Push(2) + s.Push(3) + s.Print() +} + +func TestLinkedListStack_Pop(t *testing.T) { + s := NewLinkedListStack() + s.Push(1) + s.Push(2) + s.Push(3) + s.Print() + + t.Log(s.Pop()) + t.Log(s.Pop()) + t.Log(s.Pop()) + t.Log(s.Pop()) + s.Print() +} + +func TestLinkedListStack_Top(t *testing.T) { + s := NewLinkedListStack() + s.Push(1) + s.Push(2) + s.Push(3) + + t.Log(s.Top()) + s.Pop() + t.Log(s.Top()) + s.Pop() + t.Log(s.Top()) + s.Pop() + t.Log(s.Top()) + s.Pop() +} diff --git a/go/08_stack/StatckInterface.go b/go/08_stack/StatckInterface.go new file mode 100644 index 00000000..b2bead18 --- /dev/null +++ b/go/08_stack/StatckInterface.go @@ -0,0 +1,9 @@ +package _8_stack + +type Stack interface { + Push(v interface{}) + Pop() interface{} + IsEmpty() bool + Top() interface{} + Flush() +} From 13d6ce3d960bef1f4d952092826d8fe40e38bd2b Mon Sep 17 00:00:00 2001 From: Wenru Dong Date: Tue, 9 Oct 2018 22:31:47 +0100 Subject: [PATCH 17/69] implementation of ArrayQueue and CircularQueue in Python --- python/09_queue/array_queue.py | 33 ++++++++++++++++++++++++ python/09_queue/circular_queue.py | 43 +++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 python/09_queue/array_queue.py create mode 100644 python/09_queue/circular_queue.py diff --git a/python/09_queue/array_queue.py b/python/09_queue/array_queue.py new file mode 100644 index 00000000..40f34c28 --- /dev/null +++ b/python/09_queue/array_queue.py @@ -0,0 +1,33 @@ +""" + Queue based upon array + 用数组实现的队列 + + Author: Wenru +""" + +from typing import Optional + +class ArrayQueue: + + def __init__(self, capacity: int): + self._items = [] + self._capacity = capacity + self._head = 0 + self._tail = 0 + + def enqueue(self, item: str) -> bool: + if self._tail == self._capacity: return False + + self._items.append(item) + self._tail += 1 + return True + + def dequeue(self) -> Optional[str]: + if self._head != self._tail: + item = self._items[self._head] + self._head += 1 + return item + + def __repr__(self) -> str: + return " ".join(item for item in self._items[self._head : self._tail]) + diff --git a/python/09_queue/circular_queue.py b/python/09_queue/circular_queue.py new file mode 100644 index 00000000..90ec01e0 --- /dev/null +++ b/python/09_queue/circular_queue.py @@ -0,0 +1,43 @@ +""" + Author: Wenru +""" + +from typing import Optional +from itertools import chain + +class CircularQueue: + + def __init__(self, capacity): + self._items = [] + self._capacity = capacity + 1 + self._head = 0 + self._tail = 0 + + def enqueue(self, item: str) -> bool: + if (self._tail + 1) % self._capacity == self._head: + return False + + self._items.append(item) + self._tail = (self._tail + 1) % self._capacity + return True + + def dequeue(self) -> Optional[str]: + if self._head != self._tail: + item = self._items[self._head] + self._head = (self._head + 1) % self._capacity + return item + + def __repr__(self) -> str: + if self._tail >= self._head: + return " ".join(item for item in self._items[self._head : self._tail]) + else: + return " ".join(item for item in chain(self._items[self._head:], self._items[:self._tail])) + +if __name__ == "__main__": + q = CircularQueue(5) + for i in range(5): + q.enqueue(str(i)) + q.dequeue() + q.dequeue() + q.enqueue(str(5)) + print(q) From 387f9278b102a5b5714a9e23a31a2af49fae51fe Mon Sep 17 00:00:00 2001 From: TripleZ Date: Wed, 10 Oct 2018 13:32:57 +0800 Subject: [PATCH 18/69] palindromeList: another implementation O(n) time complexity & O(1) space complexity --- .../palindromeList/LinkedList.hpp | 118 ++++++++++++++++++ .../06_linkedlist/palindromeList/ListNode.hpp | 16 +++ .../palindromeList/palindromeList.cpp | 92 ++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 c-cpp/06_linkedlist/palindromeList/LinkedList.hpp create mode 100644 c-cpp/06_linkedlist/palindromeList/ListNode.hpp create mode 100644 c-cpp/06_linkedlist/palindromeList/palindromeList.cpp diff --git a/c-cpp/06_linkedlist/palindromeList/LinkedList.hpp b/c-cpp/06_linkedlist/palindromeList/LinkedList.hpp new file mode 100644 index 00000000..737e41e8 --- /dev/null +++ b/c-cpp/06_linkedlist/palindromeList/LinkedList.hpp @@ -0,0 +1,118 @@ +/** + * Author: TripleZ + * Date: 2018-10-10 + * Brief: Linked list class. + */ + +#ifndef _LINKEDLIST_HPP_ +#define _LINKEDLIST_HPP_ + +#include +#include "ListNode.hpp" + +class LinkedList { +public: + int size; + int length; + ListNode *head; + LinkedList(); + LinkedList(int size); + ~LinkedList(); + ListNode* FindElem(int elemVal); + bool DeleteElem(ListNode *elem); + bool DeleteLastElem(); + bool InsertElemAtFront(int elemVal); + bool InsertElemAtBack(int elemVal); + void PrintList(); +}; + +LinkedList::LinkedList() { + this -> head = new ListNode(); + this -> head->next = nullptr; + this -> head->val = -1; + this -> size = 10; // default + this -> length = 0; +} + +LinkedList::LinkedList(int size) { + this -> head = new ListNode(); + this -> head->next = nullptr; + this -> head->val = -1; + + this -> size = size; + this -> length = 0; +} + +LinkedList::~LinkedList() { + ListNode *p, *q; + p = this -> head; + while(p -> next != nullptr) { + q = p -> next; + p -> next = p -> next -> next; + delete q; + } + delete head; + this -> head = nullptr; + this -> length = 0; +} + +ListNode* LinkedList::FindElem(int elemVal) { + ListNode *p; + for (p = this -> head; p != nullptr; p = p -> next) { + if (p -> val == elemVal) { + return p; + } + } + return nullptr; +} + +bool LinkedList::DeleteElem(ListNode *elem) { + ListNode *prev, *next; + for (prev = this -> head; prev -> next != elem; prev = prev -> next); + next = elem -> next; + prev -> next = next; + delete elem; + this -> length --; + return true; +} + +bool LinkedList::DeleteLastElem() { + ListNode *prev, *elem; + for (prev = this -> head; prev -> next -> next != nullptr; prev = prev -> next) ; + elem = prev -> next; + prev -> next = nullptr; + delete elem; + this -> length --; + return true; +} + +bool LinkedList::InsertElemAtFront(int elemVal) { + ListNode *newNode = new ListNode(); + newNode -> val = elemVal; + newNode -> next = this -> head -> next; + this -> head -> next = newNode; + this -> length ++; + return true; +} + +bool LinkedList::InsertElemAtBack(int elemVal) { + ListNode *newNode = new ListNode(); + newNode -> val = elemVal; + ListNode *end; + for (end = this -> head; end -> next != nullptr; end = end -> next); + end -> next = newNode; + newNode -> next = nullptr; + this -> length ++; + return true; +} + +void LinkedList::PrintList() { + ListNode *elem; + printf("List: "); + for (elem = this -> head -> next; elem -> next != nullptr; elem = elem -> next) { + printf("%d - ", elem -> val); + } + printf("%d\n", elem -> val); +} + +#endif diff --git a/c-cpp/06_linkedlist/palindromeList/ListNode.hpp b/c-cpp/06_linkedlist/palindromeList/ListNode.hpp new file mode 100644 index 00000000..5b6189b0 --- /dev/null +++ b/c-cpp/06_linkedlist/palindromeList/ListNode.hpp @@ -0,0 +1,16 @@ +/** + * Author: TripleZ + * Date: 2018-10-10 + * Brief: ListNode class. + */ + +#ifndef _LISTNODE_HPP_ +#define _LISTNODE_HPP_ + +class ListNode { +public: + int val; + ListNode *next; +}; + +#endif diff --git a/c-cpp/06_linkedlist/palindromeList/palindromeList.cpp b/c-cpp/06_linkedlist/palindromeList/palindromeList.cpp new file mode 100644 index 00000000..5c3915b8 --- /dev/null +++ b/c-cpp/06_linkedlist/palindromeList/palindromeList.cpp @@ -0,0 +1,92 @@ +/** + * Author: TripleZ + * Date: 2018-10-10 + * Brief: Check a list whether is palindrome. + */ + +#include +#include "LinkedList.hpp" + +bool CheckPalindromeList(LinkedList *list) { + // 使用快慢指针找链表中点 + ListNode *slow, *fast, *mid2; + slow = list -> head; + fast = list -> head; + while (fast -> next != nullptr) { + slow = slow -> next; + fast = fast -> next; + if (fast -> next != nullptr) { + fast = fast -> next; + mid2 = slow -> next; + } else { + mid2 = nullptr; + } + } + + // 从中点向后逆转链表(区分奇偶情况) + ListNode *mid = slow; + ListNode *elem, *prev, *save; + if (mid2 == nullptr) { // odd + elem = mid; + prev = mid -> next; + } else { // even + elem = mid2; + prev = mid2 -> next; + mid2 -> next = nullptr; + } + save = prev -> next; + mid -> next = nullptr; + while (save != nullptr) { + prev -> next = elem; + elem = prev; + prev = save; + save = save -> next; + } + prev -> next = elem; + + ListNode *end = prev; + ListNode *front = list -> head -> next; + + // 从头尾同时遍历比较,检测链表是否为回文 + bool palindrome = true; + while (front != end) { + // printf("%d, %d\n", front -> val, end -> val); + if (front -> val != end -> val) { + palindrome = false; + break; + } + front = front -> next; + end = end -> next; + } + + palindrome ? printf("The list is palindrome~\n") : printf("The list is not palindrome!\n"); + + return palindrome; +} + +int main(int argc, char const *argv[]) { + + int init[] = {1, 2, 3, 2, 1}; + LinkedList *list = new LinkedList(5); + for (int i = 0; i < 5; i++) { + list -> InsertElemAtBack(init[i]); + } + list -> PrintList(); + + CheckPalindromeList(list); // true + + list -> InsertElemAtFront(5); + CheckPalindromeList(list); // false + + + int init2[] = {1, 2, 3, 3, 2, 1}; + LinkedList *list2 = new LinkedList(10); + for (int i = 0; i < 6; i++) list2 -> InsertElemAtBack(init2[i]); + list2 -> PrintList(); + CheckPalindromeList(list2); + + list2 -> InsertElemAtBack(4); + CheckPalindromeList(list2); + + return 0; +} From 6dcb6d6c6d10c565baf61e6d2ef1588d29aa263f Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Wed, 10 Oct 2018 15:47:24 +0800 Subject: [PATCH 19/69] implement ring queue in c --- c-cpp/09_queue/ring_queue.c | 130 ++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 c-cpp/09_queue/ring_queue.c diff --git a/c-cpp/09_queue/ring_queue.c b/c-cpp/09_queue/ring_queue.c new file mode 100644 index 00000000..1ae29f00 --- /dev/null +++ b/c-cpp/09_queue/ring_queue.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include + +struct ring_queue { + int cap; + int head, tail; + int *_q; +}; + +int alloc_queue(struct ring_queue* queue, int cap) +{ + if (!queue || cap < 0) + return -1; + if (queue->_q) + return -1; + + queue->_q = (int *)malloc(cap * sizeof(int)); + if (!queue->_q) + return -1; + + queue->head = queue->tail = 0; + queue->cap = cap; + return 0; +} + +void free_queue(struct ring_queue *queue) +{ + queue->cap = 0; + queue->head = queue->tail = 0; + free(queue->_q); +} + +int _valid_index(int curr, int step, int cap) +{ + return (curr + step) % cap; +} + +int _next(int curr, int cap) +{ + return _valid_index(curr, 1, cap); +} + +bool is_empty(struct ring_queue *queue) +{ + return (queue->head == queue->tail); +} + +bool is_full(struct ring_queue *queue) +{ + int next_tail = _next(queue->tail, queue->cap); + return (next_tail == queue->head); +} + +int enqueue(struct ring_queue* queue, int elem) +{ + if (is_full(queue)) + return -1; + + queue->_q[queue->tail] = elem; + queue->tail = _next(queue->tail, queue->cap); + return 0; +} + +int dequeue(struct ring_queue* queue, int *elem) +{ + if (is_empty(queue)) + return -1; + + if (elem) + *elem = queue->_q[queue->head]; + queue->head = _next(queue->head, queue->cap); + return 0; +} + +int size(struct ring_queue* queue) +{ + int size = queue->tail - queue->head; + + if (size < 0) + size += queue->cap; + return size; +} + +void dump(struct ring_queue* queue) +{ + int i, idx; + + printf("Queue has %d elements with %d capacity\n", + size(queue), queue->cap); + for (i = 0; i < size(queue); i++) { + idx = _valid_index(queue->head, i, queue->cap); + printf("[%02d]: %08d\n", idx, queue->_q[idx]); + } +} + +int main() +{ + struct ring_queue queue = {0, 0, 0, NULL}; + int i; + + if (alloc_queue(&queue, 8)) { + printf("Failed to allocate a queue\n"); + return -1; + } + + printf("A new queue is %s\n", is_empty(&queue)?"empty":"not empty"); + + enqueue(&queue, 1); + printf("After enqueue 1 element, queue is %s\n", is_empty(&queue)?"empty":"not empty"); + dequeue(&queue, NULL); + printf("After dequeue 1 element, queue is %s\n", is_empty(&queue)?"empty":"not empty"); + + for (i = 0; i < 7; i++) + enqueue(&queue, i); + printf("After enqueue 7 element, queue is %s\n", is_full(&queue)?"full":"not full"); + + for (i = 0; i < 4; i++) { + dequeue(&queue, NULL); + enqueue(&queue, i); + } + printf("After enqueue/dequeue 4 element, queue is %s\n", + is_full(&queue)?"full":"not full"); + printf("Head is %d, Tail is %d\n", queue.head, queue.tail); + + dump(&queue); + free_queue(&queue); + return 0; +} From 03f846c07ce4f1aca5c865f139f4ea45b6aa127f Mon Sep 17 00:00:00 2001 From: xiaojunhehe <43926569+xiaojunhehe@users.noreply.github.com> Date: Wed, 10 Oct 2018 19:46:02 +0800 Subject: [PATCH 20/69] =?UTF-8?q?=E9=92=88=E5=AF=B9=E4=B8=8A=E6=AC=A1?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=9A=84=E4=B8=80=E4=BA=9B=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E4=BF=AE=E6=AD=A3=E5=B9=B6=E4=B8=94=E5=9B=9E?= =?UTF-8?q?=E7=AD=94count=E7=9A=84=E4=BD=9C=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/05_array/Array.java | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/java/05_array/Array.java b/java/05_array/Array.java index 6b7ad055..8ec2fe1d 100644 --- a/java/05_array/Array.java +++ b/java/05_array/Array.java @@ -11,14 +11,14 @@ public class Array { public int data[]; //定义数组长度 private int n; - //定义中保存的数据个数 + //定义中实际个数 private int count; //构造方法,定义数组大小 public Array(int capacity){ - this.data = new int[]{0,1,2,3,4}; + this.data = new int[capacity]; this.n = capacity; - this.count=capacity; + this.count=0;//一开始一个数都没有存所以为0 } //根据索引,找到数据中的元素并返回 @@ -49,13 +49,14 @@ public boolean delete(int index){ //向数组中插入一个元素 public boolean insert(int index, int value){ if (index<0 || index>=count) return false; -// if (count == n) return false;不是太懂 - //数组长度增加1 - int[] arr = new int[count+1]; + //当实际存储的个数等于数组的最大长度就不让新增 + if (count == n) return false; + //数组长度增加1。不需要初始化 + /*int[] arr = new int[count+1]; for (int i = 0; i < data.length; i++) { arr[i] = data[i]; } - data=arr; + data=arr;*/ for (int i = count-1; i>=index; --i){ data[i+1] = data[i]; @@ -66,13 +67,15 @@ public boolean insert(int index, int value){ } public boolean insertToTail(int value) { -// if (count == n) return false;不是太懂 + + //当实际存储的个数等于数组的最大长度就不让新增 + if (count == n) return false; //数组长度增加1 - int[] arr = new int[count+1]; + /*int[] arr = new int[count+1]; for (int i = 0; i < data.length; i++) { arr[i] = data[i]; } - data=arr; + data=arr;*/ data[count++] = value; return true; } From 8b15f0b80ca06e78c9b6c367fef58743a9d9fecc Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Wed, 10 Oct 2018 20:27:11 +0800 Subject: [PATCH 21/69] [09_queue] .gitkeep. --- c-cpp/09_queue/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 c-cpp/09_queue/.gitkeep diff --git a/c-cpp/09_queue/.gitkeep b/c-cpp/09_queue/.gitkeep new file mode 100644 index 00000000..e69de29b From aed2b6d85fa552d96d0bd9b9f87e952457d01627 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Wed, 10 Oct 2018 20:45:18 +0800 Subject: [PATCH 22/69] [09_queue] consturctors [default, normal, copy], destructor. --- c-cpp/09_queue/array_queue.hpp | 43 ++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 c-cpp/09_queue/array_queue.hpp diff --git a/c-cpp/09_queue/array_queue.hpp b/c-cpp/09_queue/array_queue.hpp new file mode 100644 index 00000000..1be4392d --- /dev/null +++ b/c-cpp/09_queue/array_queue.hpp @@ -0,0 +1,43 @@ +/** + * Created by Liam Huang (Liam0205) on 2018/10/10. + */ + +#ifndef QUEUE_ARRAY_QUEUE_HPP_ +#define QUEUE_ARRAY_QUEUE_HPP_ + +template +class ArrayQueue { + private: + T* items_ = nullptr; + size_t capacity_ = 0; + size_t head_ = 0; + size_t tail_ = 0; + + public: + ArrayQueue() = default; + ArrayQueue(size_t capacity) : capacity_(capacity) { + items_ = new T[capacity]; + } + ~ArrayQueue() { + if (nullptr != items_) { + delete[] items_; + items_ = nullptr; + } + } + ArrayQueue(const ArrayQueue& other) : capacity_(other.capacity_) { + items_ = new T[capacity_]; + for (size_t i = other.head_; i != other.tail_; ++i) { + enqueue(other.items_[i]); + } + } + // TODO + ArrayQueue& operator=(const ArrayQueue& rhs) { + capacity_ = rhs.capacity_; + items_ = new T[capacity_]; + for (size_t i = other.head_; i != other.tail_; ++i) { + enqueue(other.items_[i]); + } + } +}; + +#endif // QUEUE_ARRAY_QUEUE_HPP_ From 84f5a63a08eb93d0661a026c13a5d7adf1390233 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Wed, 10 Oct 2018 21:36:52 +0800 Subject: [PATCH 23/69] [09_queue] consturctors [move], [copy, move] assignment. --- c-cpp/09_queue/array_queue.hpp | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/c-cpp/09_queue/array_queue.hpp b/c-cpp/09_queue/array_queue.hpp index 1be4392d..ff465b92 100644 --- a/c-cpp/09_queue/array_queue.hpp +++ b/c-cpp/09_queue/array_queue.hpp @@ -30,13 +30,37 @@ class ArrayQueue { enqueue(other.items_[i]); } } - // TODO ArrayQueue& operator=(const ArrayQueue& rhs) { + delete[] items_; + head_ = 0; + tail_ = 0; capacity_ = rhs.capacity_; - items_ = new T[capacity_]; + items_ = new T[capacity_]; for (size_t i = other.head_; i != other.tail_; ++i) { enqueue(other.items_[i]); } + return *this; + } + ArrayQueue(ArrayQueue&& other) : items_(other.items_), + capacity_(other.capacity_), + head_(other.head_), + tail_(other.tail_) { + other.items_ = nullptr; + other.capacity_ = 0; + other.head_ = 0; + other.tail_ = 0; + } + ArrayQueue& operator=(ArrayQueue&& rhs) { + delete[] items_; + items_ = rhs.items_; + capacity_ = rhs.capacity_; + head_ = rhs.head_; + tail_ = rhs.tail_; + rhs.items_ = nullptr; + rhs.capacity_ = 0; + rhs.head_ = 0; + rhs.tail_ = 0; + return *this; } }; From 8e7d064f8f2e62964421b7e0c950f17618cf615e Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Wed, 10 Oct 2018 21:44:51 +0800 Subject: [PATCH 24/69] [09_queue] enqueue and dequeue. --- c-cpp/09_queue/array_queue.hpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/c-cpp/09_queue/array_queue.hpp b/c-cpp/09_queue/array_queue.hpp index ff465b92..cb375b7f 100644 --- a/c-cpp/09_queue/array_queue.hpp +++ b/c-cpp/09_queue/array_queue.hpp @@ -62,6 +62,28 @@ class ArrayQueue { rhs.tail_ = 0; return *this; } + + public: + bool enqueue(T item) { + if (capacity_ == tail_) { return false; } + items_[tail_++] = item; + return true; + } + T head() const { + if (head_ != tail_) { + return items_[head_]; + } else { + throw "Fetch data from an empty queue!"; + } + } + bool dequeue() { + if (head_ != tail_) { + ++head_; + return true; + } else { + return false; + } + } }; #endif // QUEUE_ARRAY_QUEUE_HPP_ From 29c9ffc9c5c02e16d3708e566be93992f5461ae0 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Wed, 10 Oct 2018 21:45:23 +0800 Subject: [PATCH 25/69] [09_queue] default constructor should be deleted. --- c-cpp/09_queue/array_queue.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c-cpp/09_queue/array_queue.hpp b/c-cpp/09_queue/array_queue.hpp index cb375b7f..894c00d0 100644 --- a/c-cpp/09_queue/array_queue.hpp +++ b/c-cpp/09_queue/array_queue.hpp @@ -14,7 +14,7 @@ class ArrayQueue { size_t tail_ = 0; public: - ArrayQueue() = default; + ArrayQueue() = delete; ArrayQueue(size_t capacity) : capacity_(capacity) { items_ = new T[capacity]; } From af91fa84a8c29467bd7bf2646ab0833df29c9e16 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Wed, 10 Oct 2018 21:50:06 +0800 Subject: [PATCH 26/69] [09_queue] void return. --- c-cpp/09_queue/array_queue.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/c-cpp/09_queue/array_queue.hpp b/c-cpp/09_queue/array_queue.hpp index 894c00d0..f6c602d8 100644 --- a/c-cpp/09_queue/array_queue.hpp +++ b/c-cpp/09_queue/array_queue.hpp @@ -64,10 +64,11 @@ class ArrayQueue { } public: - bool enqueue(T item) { - if (capacity_ == tail_) { return false; } + void enqueue(T item) { + if (capacity_ == tail_) { + throw "Push data into a full queue!"; + } items_[tail_++] = item; - return true; } T head() const { if (head_ != tail_) { @@ -76,12 +77,11 @@ class ArrayQueue { throw "Fetch data from an empty queue!"; } } - bool dequeue() { + void dequeue() { if (head_ != tail_) { ++head_; - return true; } else { - return false; + throw "Pop data from an empty queue!"; } } }; From b2cb8db35a0959a803f979fe7c460c7a93a91eb0 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Wed, 10 Oct 2018 21:53:38 +0800 Subject: [PATCH 27/69] [09_queue] add traverse function. --- c-cpp/09_queue/array_queue.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/c-cpp/09_queue/array_queue.hpp b/c-cpp/09_queue/array_queue.hpp index f6c602d8..9789718a 100644 --- a/c-cpp/09_queue/array_queue.hpp +++ b/c-cpp/09_queue/array_queue.hpp @@ -84,6 +84,14 @@ class ArrayQueue { throw "Pop data from an empty queue!"; } } + + public: + template + void traverse(UnaryFunc do_traverse) { + for (size_t i = head_; i != tail_; ++i) { + do_traverse(items_[i]); + } + } }; #endif // QUEUE_ARRAY_QUEUE_HPP_ From 286f9250a666360811c67280247feafbecfb0b4b Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Wed, 10 Oct 2018 21:54:02 +0800 Subject: [PATCH 28/69] [09_queue] fix typo [other -> rhs]. --- c-cpp/09_queue/array_queue.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/c-cpp/09_queue/array_queue.hpp b/c-cpp/09_queue/array_queue.hpp index 9789718a..5704da5b 100644 --- a/c-cpp/09_queue/array_queue.hpp +++ b/c-cpp/09_queue/array_queue.hpp @@ -36,8 +36,8 @@ class ArrayQueue { tail_ = 0; capacity_ = rhs.capacity_; items_ = new T[capacity_]; - for (size_t i = other.head_; i != other.tail_; ++i) { - enqueue(other.items_[i]); + for (size_t i = rhs.head_; i != rhs.tail_; ++i) { + enqueue(rhs.items_[i]); } return *this; } From 0983790871544945b03d6ff34dfe0f6cfeb4d802 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Wed, 10 Oct 2018 22:05:11 +0800 Subject: [PATCH 29/69] [09_queue] array_queue_test, passed. --- c-cpp/09_queue/array_queue_test.cc | 56 ++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 c-cpp/09_queue/array_queue_test.cc diff --git a/c-cpp/09_queue/array_queue_test.cc b/c-cpp/09_queue/array_queue_test.cc new file mode 100644 index 00000000..c2c3b3b2 --- /dev/null +++ b/c-cpp/09_queue/array_queue_test.cc @@ -0,0 +1,56 @@ +#include +#include "array_queue.hpp" + +int main() { + auto do_traverse = [&](auto item){ std::cout << item << ' '; }; + + ArrayQueue array_queue_1(3); + array_queue_1.enqueue(1); + array_queue_1.enqueue(2); + array_queue_1.enqueue(3); + // array_queue_1.enqueue(4); // throw + array_queue_1.traverse(do_traverse); + std::cout << std::endl; + + ArrayQueue array_queue_2(array_queue_1); // copy constructor + array_queue_2.traverse(do_traverse); + std::cout << std::endl; + + ArrayQueue array_queue_3(std::move(array_queue_2)); // move constructor + array_queue_3.traverse(do_traverse); + std::cout << std::endl; + array_queue_2.traverse(do_traverse); + std::cout << std::endl; + + std::cout << array_queue_3.head() << std::endl; + array_queue_3.dequeue(); + std::cout << array_queue_3.head() << std::endl; + array_queue_3.dequeue(); + std::cout << array_queue_3.head() << std::endl; + array_queue_3.dequeue(); + // std::cout << array_queue_3.head() << std::endl; // throw + // array_queue_3.dequeue(); // throw + + ArrayQueue array_queue_4(1); + array_queue_4 = array_queue_1; // copy assignment + array_queue_4.traverse(do_traverse); + std::cout << std::endl; + + ArrayQueue array_queue_5(100); + array_queue_5 = std::move(array_queue_4); // move assignment + array_queue_5.traverse(do_traverse); + std::cout << std::endl; + array_queue_4.traverse(do_traverse); + std::cout << std::endl; + + std::cout << array_queue_5.head() << std::endl; + array_queue_5.dequeue(); + std::cout << array_queue_5.head() << std::endl; + array_queue_5.dequeue(); + std::cout << array_queue_5.head() << std::endl; + array_queue_5.dequeue(); + // std::cout << array_queue_5.head() << std::endl; // throw + // array_queue_5.dequeue(); // throw + + return 0; +} From 1ab1e93edc2537072bf2c82e2fee35362442196a Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Wed, 10 Oct 2018 22:16:57 +0800 Subject: [PATCH 30/69] [09_queue] const in constructor's parameter. --- c-cpp/09_queue/array_queue.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/c-cpp/09_queue/array_queue.hpp b/c-cpp/09_queue/array_queue.hpp index 5704da5b..6bf0892e 100644 --- a/c-cpp/09_queue/array_queue.hpp +++ b/c-cpp/09_queue/array_queue.hpp @@ -15,8 +15,8 @@ class ArrayQueue { public: ArrayQueue() = delete; - ArrayQueue(size_t capacity) : capacity_(capacity) { - items_ = new T[capacity]; + ArrayQueue(const size_t capacity) : capacity_(capacity) { + items_ = new T[capacity_]; } ~ArrayQueue() { if (nullptr != items_) { From 2b79c34c7265ed1908fbd3220dea3c0983c0cf19 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Wed, 10 Oct 2018 22:49:23 +0800 Subject: [PATCH 31/69] [09_queue] circular_queue, done. --- c-cpp/09_queue/circular_queue.hpp | 98 +++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 c-cpp/09_queue/circular_queue.hpp diff --git a/c-cpp/09_queue/circular_queue.hpp b/c-cpp/09_queue/circular_queue.hpp new file mode 100644 index 00000000..c73624f9 --- /dev/null +++ b/c-cpp/09_queue/circular_queue.hpp @@ -0,0 +1,98 @@ +/** + * Created by Liam Huang (Liam0205) on 2018/10/10. + */ + +#ifndef QUEUE_CIRCULAR_QUEUE_HPP_ +#define QUEUE_CIRCULAR_QUEUE_HPP_ + +template +class CircularQueue { + private: + T* items_ = nullptr; + size_t capacity_ = 0; + size_t head_ = 0; + size_t tail_ = 0; + + public: + CircularQueue() = delete; + CircularQueue(const size_t capacity) : capacity_(capacity) { + items_ = new T[capacity_]; + } + ~CircularQueue() { + if (nullptr != items_) { + delete[] items_; + items_ = nullptr; + } + } + CircularQueue(const CircularQueue& other) : capacity_(other.capacity_) { + items_ = new T[capacity_]; + for (size_t i = other.head_; i != other.tail_; ++i) { + enqueue(other.items_[i]); + } + } + CircularQueue& operator=(const CircularQueue& rhs) { + delete[] items_; + head_ = 0; + tail_ = 0; + capacity_ = rhs.capacity_; + items_ = new T[capacity_]; + for (size_t i = rhs.head_; i != rhs.tail_; ++i) { + enqueue(rhs.items_[i]); + } + return *this; + } + CircularQueue(CircularQueue&& other) : items_(other.items_), + capacity_(other.capacity_), + head_(other.head_), + tail_(other.tail_) { + other.items_ = nullptr; + other.capacity_ = 0; + other.head_ = 0; + other.tail_ = 0; + } + CircularQueue& operator=(CircularQueue&& rhs) { + delete[] items_; + items_ = rhs.items_; + capacity_ = rhs.capacity_; + head_ = rhs.head_; + tail_ = rhs.tail_; + rhs.items_ = nullptr; + rhs.capacity_ = 0; + rhs.head_ = 0; + rhs.tail_ = 0; + return *this; + } + + public: + void enqueue(T item) { + if ((tail_ + 1) % capacity_ == head_) { + throw "Push data into a full queue!"; + } + items_[tail_] = item; + tail_ = (tail_ + 1) % capacity_; + } + T head() const { + if (head_ != tail_) { + return items_[head_]; + } else { + throw "Fetch data from an empty queue!"; + } + } + void dequeue() { + if (head_ != tail_) { + head_ = (head_ + 1) % capacity_; + } else { + throw "Pop data from an empty queue!"; + } + } + + public: + template + void traverse(UnaryFunc do_traverse) { + for (size_t i = head_; i % capacity_ != tail_; ++i) { + do_traverse(items_[i % capacity_]); + } + } +}; + +#endif // QUEUE_CIRCULAR_QUEUE_HPP_ From 8367555e027a7fcb380e3dcf488084aa76723858 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Wed, 10 Oct 2018 22:53:27 +0800 Subject: [PATCH 32/69] [09_queue] circular_queue, fix bug [ x / 0.0 ] --- c-cpp/09_queue/circular_queue.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/c-cpp/09_queue/circular_queue.hpp b/c-cpp/09_queue/circular_queue.hpp index c73624f9..df4664cc 100644 --- a/c-cpp/09_queue/circular_queue.hpp +++ b/c-cpp/09_queue/circular_queue.hpp @@ -89,6 +89,7 @@ class CircularQueue { public: template void traverse(UnaryFunc do_traverse) { + if (0 == capacity_) return; for (size_t i = head_; i % capacity_ != tail_; ++i) { do_traverse(items_[i % capacity_]); } From a2714da4819d1c467fc263f0b14e2224cac1823d Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Wed, 10 Oct 2018 22:58:01 +0800 Subject: [PATCH 33/69] [09_queue] circular_queue_test, passed. --- c-cpp/09_queue/circular_queue_test.cc | 62 +++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 c-cpp/09_queue/circular_queue_test.cc diff --git a/c-cpp/09_queue/circular_queue_test.cc b/c-cpp/09_queue/circular_queue_test.cc new file mode 100644 index 00000000..46e025ae --- /dev/null +++ b/c-cpp/09_queue/circular_queue_test.cc @@ -0,0 +1,62 @@ +#include +#include "circular_queue.hpp" + +int main() { + auto do_traverse = [&](auto item){ std::cout << item << ' '; }; + + CircularQueue circular_queue_1(4); + circular_queue_1.enqueue(1); + circular_queue_1.enqueue(2); + circular_queue_1.enqueue(3); + // circular_queue_1.enqueue(4); // throw + circular_queue_1.traverse(do_traverse); + std::cout << std::endl; + + CircularQueue circular_queue_2(circular_queue_1); // copy constructor + circular_queue_2.traverse(do_traverse); + std::cout << std::endl; + + CircularQueue circular_queue_3(std::move(circular_queue_2)); // move constructor + circular_queue_3.traverse(do_traverse); + std::cout << std::endl; + circular_queue_2.traverse(do_traverse); + std::cout << std::endl; + + std::cout << circular_queue_3.head() << std::endl; + circular_queue_3.dequeue(); + std::cout << circular_queue_3.head() << std::endl; + circular_queue_3.dequeue(); + std::cout << circular_queue_3.head() << std::endl; + circular_queue_3.dequeue(); + // std::cout << circular_queue_3.head() << std::endl; // throw + // circular_queue_3.dequeue(); // throw + + CircularQueue circular_queue_4(1); + circular_queue_4 = circular_queue_1; // copy assignment + circular_queue_4.traverse(do_traverse); + std::cout << std::endl; + + CircularQueue circular_queue_5(100); + circular_queue_5 = std::move(circular_queue_4); // move assignment + circular_queue_5.traverse(do_traverse); + std::cout << std::endl; + circular_queue_4.traverse(do_traverse); + std::cout << std::endl; + + std::cout << circular_queue_5.head() << std::endl; + circular_queue_5.dequeue(); + std::cout << circular_queue_5.head() << std::endl; + circular_queue_5.dequeue(); + std::cout << circular_queue_5.head() << std::endl; + circular_queue_5.dequeue(); + // std::cout << circular_queue_5.head() << std::endl; // throw + // circular_queue_5.dequeue(); // throw + + for (size_t i = 0; i != 4; ++i) { + circular_queue_1.dequeue(); + circular_queue_1.enqueue(i + 4); + circular_queue_1.traverse(do_traverse); + std::cout << std::endl; + } + return 0; +} From f520b13b09f93b6182217ffffb2cc9344c33b57e Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Wed, 10 Oct 2018 23:00:17 +0800 Subject: [PATCH 34/69] [09_queue] bugfix for printAll in CircularQueue. --- java/09_queue/CircularQueue.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/09_queue/CircularQueue.java b/java/09_queue/CircularQueue.java index c3c54cc7..71a988c4 100644 --- a/java/09_queue/CircularQueue.java +++ b/java/09_queue/CircularQueue.java @@ -36,7 +36,8 @@ public String dequeue() { } public void printAll() { - for (int i = head; i < tail; ++i) { + if (0 == n) return; + for (int i = head; i % n != tail; ++i) { System.out.print(items[i] + " "); } System.out.println(); From a9dff3d6dc115ea9191bf46462b7e2ab5a5069c9 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 10 Oct 2018 23:01:59 +0800 Subject: [PATCH 35/69] fix bugs of array stack --- go/08_stack/StackBasedOnArray.go | 7 ++++++- go/08_stack/StackBasedOnArray_test.go | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/go/08_stack/StackBasedOnArray.go b/go/08_stack/StackBasedOnArray.go index cdecbf8b..27e3bec8 100644 --- a/go/08_stack/StackBasedOnArray.go +++ b/go/08_stack/StackBasedOnArray.go @@ -28,12 +28,17 @@ func (this *ArrayStack) IsEmpty() bool { } func (this *ArrayStack) Push(v interface{}) { - this.data = append(this.data, v) if this.top < 0 { this.top = 0 } else { this.top += 1 } + + if this.top > len(this.data)-1 { + this.data = append(this.data, v) + } else { + this.data[this.top] = v + } } func (this *ArrayStack) Pop() interface{} { diff --git a/go/08_stack/StackBasedOnArray_test.go b/go/08_stack/StackBasedOnArray_test.go index 0a6ea7dd..55dc8003 100644 --- a/go/08_stack/StackBasedOnArray_test.go +++ b/go/08_stack/StackBasedOnArray_test.go @@ -6,7 +6,12 @@ func TestArrayStack_Push(t *testing.T) { s := NewArrayStack() s.Push(1) s.Push(2) + t.Log(s.Pop()) s.Push(3) + t.Log(s.Pop()) + t.Log(s.Pop()) + s.Push(4) + t.Log(s.Pop()) s.Print() } From 4be60c4628307d9c4ebe7b66c08804519cf06e74 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Wed, 10 Oct 2018 23:06:56 +0800 Subject: [PATCH 36/69] [09_queue] typo fix. --- .../{DynimacArrayQueue.java => DynamicArrayQueue.java} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename java/09_queue/{DynimacArrayQueue.java => DynamicArrayQueue.java} (94%) diff --git a/java/09_queue/DynimacArrayQueue.java b/java/09_queue/DynamicArrayQueue.java similarity index 94% rename from java/09_queue/DynimacArrayQueue.java rename to java/09_queue/DynamicArrayQueue.java index 3a19fa3d..9faad0fd 100644 --- a/java/09_queue/DynimacArrayQueue.java +++ b/java/09_queue/DynamicArrayQueue.java @@ -3,7 +3,7 @@ /** * Created by wangzheng on 2018/10/9. */ -public class DynimacArrayQueue { +public class DynamicArrayQueue { // 数组:items,数组大小:n private String[] items; private int n = 0; @@ -12,7 +12,7 @@ public class DynimacArrayQueue { private int tail = 0; // 申请一个大小为capacity的数组 - public DynimacArrayQueue(int capacity) { + public DynamicArrayQueue(int capacity) { items = new String[capacity]; n = capacity; } From f2cc3231465fb6aee10ba2c7ecbf15c52094d5db Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Wed, 10 Oct 2018 23:14:56 +0800 Subject: [PATCH 37/69] [09_queue] dynamic_array_queue, done. --- c-cpp/09_queue/dynamic_array_queue.hpp | 106 +++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 c-cpp/09_queue/dynamic_array_queue.hpp diff --git a/c-cpp/09_queue/dynamic_array_queue.hpp b/c-cpp/09_queue/dynamic_array_queue.hpp new file mode 100644 index 00000000..a8ecca5b --- /dev/null +++ b/c-cpp/09_queue/dynamic_array_queue.hpp @@ -0,0 +1,106 @@ +/** + * Created by Liam Huang (Liam0205) on 2018/10/10. + */ + +#ifndef QUEUE_DYNAMIC_ARRAY_QUEUE_HPP_ +#define QUEUE_DYNAMIC_ARRAY_QUEUE_HPP_ + +template +class DynamicArrayQueue { + private: + T* items_ = nullptr; + size_t capacity_ = 0; + size_t head_ = 0; + size_t tail_ = 0; + + public: + DynamicArrayQueue() = delete; + DynamicArrayQueue(const size_t capacity) : capacity_(capacity) { + items_ = new T[capacity_]; + } + ~DynamicArrayQueue() { + if (nullptr != items_) { + delete[] items_; + items_ = nullptr; + } + } + DynamicArrayQueue(const DynamicArrayQueue& other) : capacity_(other.capacity_) { + items_ = new T[capacity_]; + for (size_t i = other.head_; i != other.tail_; ++i) { + enqueue(other.items_[i]); + } + } + DynamicArrayQueue& operator=(const DynamicArrayQueue& rhs) { + delete[] items_; + head_ = 0; + tail_ = 0; + capacity_ = rhs.capacity_; + items_ = new T[capacity_]; + for (size_t i = rhs.head_; i != rhs.tail_; ++i) { + enqueue(rhs.items_[i]); + } + return *this; + } + DynamicArrayQueue(DynamicArrayQueue&& other) : items_(other.items_), + capacity_(other.capacity_), + head_(other.head_), + tail_(other.tail_) { + other.items_ = nullptr; + other.capacity_ = 0; + other.head_ = 0; + other.tail_ = 0; + } + DynamicArrayQueue& operator=(DynamicArrayQueue&& rhs) { + delete[] items_; + items_ = rhs.items_; + capacity_ = rhs.capacity_; + head_ = rhs.head_; + tail_ = rhs.tail_; + rhs.items_ = nullptr; + rhs.capacity_ = 0; + rhs.head_ = 0; + rhs.tail_ = 0; + return *this; + } + + public: + void enqueue(T item) { + if (capacity_ == tail_ - head_) { + throw "Push data into a full queue!"; + } + if (capacity_ != tail_) { + items_[tail_++] = item; + } else { + // item transport + for (size_t i = head_; i != tail_; ++i) { + items_[i - head_] = items_[i]; + } + tail_ = tail_ - head_; + head_ = 0; + } + } + T head() const { + if (head_ != tail_) { + return items_[head_]; + } else { + throw "Fetch data from an empty queue!"; + } + } + void dequeue() { + if (head_ != tail_) { + ++head_; + } else { + throw "Pop data from an empty queue!"; + } + } + + public: + template + void traverse(UnaryFunc do_traverse) { + for (size_t i = head_; i != tail_; ++i) { + do_traverse(items_[i]); + } + } +}; + +#endif // QUEUE_DYNAMIC_ARRAY_QUEUE_HPP_ From f6295f811969a5d47510146dd19acb462b015f7c Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Wed, 10 Oct 2018 23:20:38 +0800 Subject: [PATCH 38/69] [09_queue] dynamic_array_queue, bug fix (enqueue). --- c-cpp/09_queue/dynamic_array_queue.hpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/c-cpp/09_queue/dynamic_array_queue.hpp b/c-cpp/09_queue/dynamic_array_queue.hpp index a8ecca5b..73939e40 100644 --- a/c-cpp/09_queue/dynamic_array_queue.hpp +++ b/c-cpp/09_queue/dynamic_array_queue.hpp @@ -68,9 +68,7 @@ class DynamicArrayQueue { if (capacity_ == tail_ - head_) { throw "Push data into a full queue!"; } - if (capacity_ != tail_) { - items_[tail_++] = item; - } else { + if (capacity_ == tail_) { // item transport for (size_t i = head_; i != tail_; ++i) { items_[i - head_] = items_[i]; @@ -78,6 +76,7 @@ class DynamicArrayQueue { tail_ = tail_ - head_; head_ = 0; } + items_[tail_++] = item; } T head() const { if (head_ != tail_) { From 4c66d18b7523d11088b647f9bfe3e571e11ea43c Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Wed, 10 Oct 2018 23:20:51 +0800 Subject: [PATCH 39/69] [09_queue] dynamic_array_queue_test, passed. --- c-cpp/09_queue/dynamic_array_queue_test.cc | 62 ++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 c-cpp/09_queue/dynamic_array_queue_test.cc diff --git a/c-cpp/09_queue/dynamic_array_queue_test.cc b/c-cpp/09_queue/dynamic_array_queue_test.cc new file mode 100644 index 00000000..65804338 --- /dev/null +++ b/c-cpp/09_queue/dynamic_array_queue_test.cc @@ -0,0 +1,62 @@ +#include +#include "dynamic_array_queue.hpp" + +int main() { + auto do_traverse = [&](auto item){ std::cout << item << ' '; }; + + DynamicArrayQueue dynamic_array_queue_1(3); + dynamic_array_queue_1.enqueue(1); + dynamic_array_queue_1.enqueue(2); + dynamic_array_queue_1.enqueue(3); + // dynamic_array_queue_1.enqueue(4); // throw + dynamic_array_queue_1.traverse(do_traverse); + std::cout << std::endl; + + DynamicArrayQueue dynamic_array_queue_2(dynamic_array_queue_1); // copy constructor + dynamic_array_queue_2.traverse(do_traverse); + std::cout << std::endl; + + DynamicArrayQueue dynamic_array_queue_3(std::move(dynamic_array_queue_2)); // move constructor + dynamic_array_queue_3.traverse(do_traverse); + std::cout << std::endl; + dynamic_array_queue_2.traverse(do_traverse); + std::cout << std::endl; + + std::cout << dynamic_array_queue_3.head() << std::endl; + dynamic_array_queue_3.dequeue(); + std::cout << dynamic_array_queue_3.head() << std::endl; + dynamic_array_queue_3.dequeue(); + std::cout << dynamic_array_queue_3.head() << std::endl; + dynamic_array_queue_3.dequeue(); + // std::cout << dynamic_array_queue_3.head() << std::endl; // throw + // dynamic_array_queue_3.dequeue(); // throw + + DynamicArrayQueue dynamic_array_queue_4(1); + dynamic_array_queue_4 = dynamic_array_queue_1; // copy assignment + dynamic_array_queue_4.traverse(do_traverse); + std::cout << std::endl; + + DynamicArrayQueue dynamic_array_queue_5(100); + dynamic_array_queue_5 = std::move(dynamic_array_queue_4); // move assignment + dynamic_array_queue_5.traverse(do_traverse); + std::cout << std::endl; + dynamic_array_queue_4.traverse(do_traverse); + std::cout << std::endl; + + std::cout << dynamic_array_queue_5.head() << std::endl; + dynamic_array_queue_5.dequeue(); + std::cout << dynamic_array_queue_5.head() << std::endl; + dynamic_array_queue_5.dequeue(); + std::cout << dynamic_array_queue_5.head() << std::endl; + dynamic_array_queue_5.dequeue(); + // std::cout << dynamic_array_queue_5.head() << std::endl; // throw + // dynamic_array_queue_5.dequeue(); // throw + + for (size_t i = 0; i != 3; ++i) { + dynamic_array_queue_1.dequeue(); + dynamic_array_queue_1.enqueue(i + 4); + dynamic_array_queue_1.traverse(do_traverse); + std::cout << std::endl; + } + return 0; +} From 81a23a1f9307ce42bfa215c9d60356d7d25df76d Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Wed, 10 Oct 2018 23:46:15 +0800 Subject: [PATCH 40/69] [09_queue] linked_queue, done. --- c-cpp/09_queue/linked_queue.hpp | 75 +++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 c-cpp/09_queue/linked_queue.hpp diff --git a/c-cpp/09_queue/linked_queue.hpp b/c-cpp/09_queue/linked_queue.hpp new file mode 100644 index 00000000..13727753 --- /dev/null +++ b/c-cpp/09_queue/linked_queue.hpp @@ -0,0 +1,75 @@ +/** + * Created by Liam Huang (Liam0205) on 2018/10/10. + */ + +#ifndef QUEUE_LINKED_QUEUE_HPP_ +#define QUEUE_LINKED_QUEUE_HPP_ + +#include + +template +struct Node { + using ptr_t = std::shared_ptr>; + T data; + ptr_t next; + + Node(T data_) : data(data_), next(nullptr) {} + Node() : next(nullptr) {} +}; + +template +class LinkedQueue { + public: + using node_type = Node; + using node_ptr_t = typename node_type::ptr_t; + + private: + node_ptr_t head_ = nullptr; + node_ptr_t before_tail_ = nullptr; + + public: + LinkedQueue() = default; + ~LinkedQueue() = default; + LinkedQueue(const LinkedQueue& other) = default; + LinkedQueue& operator=(const LinkedQueue& rhs) = default; + LinkedQueue(LinkedQueue&& other) = default; + LinkedQueue& operator=(LinkedQueue&& rhs) = default; + + public: + void enqueue(T item) { + if (nullptr == head_) { + head_ = std::make_shared(item); + before_tail_ = head_; + } else { + before_tail_->next = std::make_shared(item); + before_tail_ = before_tail_->next; + } + } + T head() const { + if (nullptr != head_) { + return head_->data; + } else { + throw "Fetch data from an empty queue!"; + } + } + void dequeue() { + if (nullptr != head_) { + head_ = head_->next; + if (nullptr == head_) { + before_tail_ = nullptr; + } + } else { + throw "Pop data from an empty queue!"; + } + } + + public: + template + void traverse(UnaryFunc do_traverse) { + for (node_ptr_t work = head_; nullptr != work; work = work->next) { + do_traverse(work->data); + } + } +}; + +#endif // QUEUE_LINKED_QUEUE_HPP_ From a9fee74a396fc6f550eb1c233dc55450e93ab10f Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Wed, 10 Oct 2018 23:46:37 +0800 Subject: [PATCH 41/69] [09_queue] linked_queue_test, passed. --- c-cpp/09_queue/linked_queue_test.cc | 55 +++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 c-cpp/09_queue/linked_queue_test.cc diff --git a/c-cpp/09_queue/linked_queue_test.cc b/c-cpp/09_queue/linked_queue_test.cc new file mode 100644 index 00000000..04a90195 --- /dev/null +++ b/c-cpp/09_queue/linked_queue_test.cc @@ -0,0 +1,55 @@ +#include +#include "linked_queue.hpp" + +int main() { + auto do_traverse = [&](auto item){ std::cout << item << ' '; }; + + LinkedQueue linked_queue_1; + linked_queue_1.enqueue(1); + linked_queue_1.enqueue(2); + linked_queue_1.enqueue(3); + linked_queue_1.traverse(do_traverse); + std::cout << std::endl; + + LinkedQueue linked_queue_2(linked_queue_1); // copy constructor + linked_queue_2.traverse(do_traverse); + std::cout << std::endl; + + LinkedQueue linked_queue_3(std::move(linked_queue_2)); // move constructor + linked_queue_3.traverse(do_traverse); + std::cout << std::endl; + linked_queue_2.traverse(do_traverse); + std::cout << std::endl; + + std::cout << linked_queue_3.head() << std::endl; + linked_queue_3.dequeue(); + std::cout << linked_queue_3.head() << std::endl; + linked_queue_3.dequeue(); + std::cout << linked_queue_3.head() << std::endl; + linked_queue_3.dequeue(); + // std::cout << linked_queue_3.head() << std::endl; // throw + // linked_queue_3.dequeue(); // throw + + LinkedQueue linked_queue_4; + linked_queue_4 = linked_queue_1; // copy assignment + linked_queue_4.traverse(do_traverse); + std::cout << std::endl; + + LinkedQueue linked_queue_5; + linked_queue_5 = std::move(linked_queue_4); // move assignment + linked_queue_5.traverse(do_traverse); + std::cout << std::endl; + linked_queue_4.traverse(do_traverse); + std::cout << std::endl; + + std::cout << linked_queue_5.head() << std::endl; + linked_queue_5.dequeue(); + std::cout << linked_queue_5.head() << std::endl; + linked_queue_5.dequeue(); + std::cout << linked_queue_5.head() << std::endl; + linked_queue_5.dequeue(); + // std::cout << linked_queue_5.head() << std::endl; // throw + // linked_queue_5.dequeue(); // throw + + return 0; +} From 51944bdd26217178c6b161a413a85f08a56172bb Mon Sep 17 00:00:00 2001 From: nameczz Date: Thu, 11 Oct 2018 09:24:27 +0800 Subject: [PATCH 42/69] add 08_stack for js version --- javascript/08_stack/SampleBrowser.js | 56 +++++++++++++++++ javascript/08_stack/StackBasedOnLinkedList.js | 62 +++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 javascript/08_stack/SampleBrowser.js create mode 100644 javascript/08_stack/StackBasedOnLinkedList.js diff --git a/javascript/08_stack/SampleBrowser.js b/javascript/08_stack/SampleBrowser.js new file mode 100644 index 00000000..c084dd78 --- /dev/null +++ b/javascript/08_stack/SampleBrowser.js @@ -0,0 +1,56 @@ +/** + * 使用前后栈实现浏览器的前进后退。 + * + * Author nameczz + */ +const stack = require('./StackBasedOnLinkedList') + +class SampleBrowser { + constructor() { + this.normalStack = new stack.CreatedStack() + this.backStack = new stack.CreatedStack() + } + // 正常浏览页面 + pushNormal(name) { + this.normalStack.push(name) + this.backStack.clear() + this.displayAllStack() + } + // 后退 + back() { + const value = this.normalStack.pop() + if (value !== -1) { + this.backStack.push(value) + this.displayAllStack() + } else { + console.log('无法后退') + } + } + // 前进 + front() { + const value = this.backStack.pop() + if (value !== -1) { + this.normalStack.push(value) + this.displayAllStack() + } else { + console.log('无法前进') + } + } + // 打印栈内数据 + displayAllStack() { + console.log('---后退页面---') + this.backStack.display() + console.log('---浏览页面---') + this.normalStack.display() + } +} +// Test +const browser = new SampleBrowser() +browser.pushNormal('www.google.com') +browser.pushNormal('www.baidu.com') +browser.pushNormal('www.github.com') +// 后退 +browser.back() +browser.back() +browser.front() +browser.pushNormal('www.new.com') \ No newline at end of file diff --git a/javascript/08_stack/StackBasedOnLinkedList.js b/javascript/08_stack/StackBasedOnLinkedList.js new file mode 100644 index 00000000..07acc0e6 --- /dev/null +++ b/javascript/08_stack/StackBasedOnLinkedList.js @@ -0,0 +1,62 @@ +/** + * 基于链表实现的栈。 + * + * Author: nameczz + */ + +class Node { + constructor(element) { + this.element = element + this.next = null + } +} + +class StackBasedLinkedList { + constructor() { + this.top = null + } + push(value) { + const node = new Node(value) + if (this.top === null) { + this.top = node + } else { + node.next = this.top + this.top = node + } + } + pop() { + if (this.top === null) { + return -1 + } + const value = this.top.element + this.top = this.top.next + return value + } + // 为了实现浏览器前进后退 + clear() { + this.top = null + } + display() { + if (this.top !== null) { + let temp = this.top + while (temp !== null) { + console.log(temp.element) + temp = temp.next + } + } + } +} +// Test +const newStack = new StackBasedLinkedList() +newStack.push(1) +newStack.push(2) +newStack.push(3) +// 获取元素 +let res = 0 +console.log('-------获取pop元素------') +while (res !== -1) { + res = newStack.pop() + console.log(res) +} + +exports.CreatedStack = StackBasedLinkedList \ No newline at end of file From 1289a1cacf451b8fd8c9ef06bc3d4586fb4ae138 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Thu, 11 Oct 2018 12:09:03 +0800 Subject: [PATCH 43/69] [09_queue] concurrency, block_queue, wait, done. --- c-cpp/09_queue/block_queue.hpp | 59 ++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 c-cpp/09_queue/block_queue.hpp diff --git a/c-cpp/09_queue/block_queue.hpp b/c-cpp/09_queue/block_queue.hpp new file mode 100644 index 00000000..6fbb61ed --- /dev/null +++ b/c-cpp/09_queue/block_queue.hpp @@ -0,0 +1,59 @@ +/** + * Created by Liam Huang (Liam0205) on 2018/10/11. + */ + +#ifndef QUEUE_BLOCK_QUEUE_HPP_ +#define QUEUE_BLOCK_QUEUE_HPP_ + +#include +#include +#include + +template +class BlockQueue { + public: + using value_type = T; + using container_type = std::queue; + using size_type = typename container_type::size_type; + + private: + size_type capacity_ = 0; + container_type container_; + mutable std::mutex mutex_; + mutable std::condition_variable not_empty_; + mutable std::condition_variable not_full_; + + public: + BlockQueue() = delete; + BlockQueue(const size_type capacity) : capacity_(capacity) {} + BlockQueue(const BlockQueue&) = default; + BlockQueue(BlockQueue&&) = default; + BlockQueue& operator=(const BlockQueue&) = default; + BlockQueue& operator=(BlockQueue&&) = default; + + private: + bool empty() const { return container_.empty(); } + bool full() const { return not(container_.size() < capacity_); } + + public: + void put(const value_type& item) { + std::unqiue_lock lock(mutex_); + while (full()) { + not_full_.wait(lock); + } + container_.push(item); + not_empty_.notify_one(); + } + void take(value_type& out) { + std::unique_lock lock(mutex_); + while (empty()) { + not_empty_.wait(lock); + } + out = container_.front(); + container_.pop(); + not_full_.notify_one(); + } +}; + +#endif // QUEUE_BLOCK_QUEUE_HPP_ + From 82b0b47cbd85a11b124e224056f7253fdfee75b3 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Thu, 11 Oct 2018 12:15:35 +0800 Subject: [PATCH 44/69] [09_queue] concurrency, block_queue, wait_for, done. --- c-cpp/09_queue/block_queue.hpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/c-cpp/09_queue/block_queue.hpp b/c-cpp/09_queue/block_queue.hpp index 6fbb61ed..d8de1689 100644 --- a/c-cpp/09_queue/block_queue.hpp +++ b/c-cpp/09_queue/block_queue.hpp @@ -53,6 +53,29 @@ class BlockQueue { container_.pop(); not_full_.notify_one(); } + template + bool put_for(const value_type& item, const Duration& d) { + std::unqiue_lock lock(mutex_); + if (not_full_.wait_for(lock, d, [&](){ return not full(); })) { + container_.push(item); + not_empty_.notify_one(); + return true; + } else { + return false; + } + } + template + bool take_for(const Duration& d, value_type& out) { + std::unique_lock lock(mutex_); + if (not_empty_.wait_for(lock, d, [&](){ return not empty(); })) { + out = container_.front(); + container_.pop(); + not_full_.notify_one(); + return true; + } else { + return false; + } + } }; #endif // QUEUE_BLOCK_QUEUE_HPP_ From 2e8bbeeaf063c164c6982abb5984ed20dff66e4e Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Thu, 11 Oct 2018 12:18:51 +0800 Subject: [PATCH 45/69] [git] update root .gitignore for ignoring Vim temp files. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 31f5f1e9..c456446b 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ hs_err_pid* # editor files .vscode +.*.swp From 2aa9de5ebf15419dcee0ab9d95567942a59f5258 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Thu, 11 Oct 2018 12:27:38 +0800 Subject: [PATCH 46/69] [09_queue] concurrency, concurrency_queue, init. --- c-cpp/09_queue/concurrency_queue.hpp | 34 ++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 c-cpp/09_queue/concurrency_queue.hpp diff --git a/c-cpp/09_queue/concurrency_queue.hpp b/c-cpp/09_queue/concurrency_queue.hpp new file mode 100644 index 00000000..cee58804 --- /dev/null +++ b/c-cpp/09_queue/concurrency_queue.hpp @@ -0,0 +1,34 @@ +/** + * Created by Liam Huang (Liam0205) on 2018/10/11. + */ + +#ifndef QUEUE_CONCURRENCY_QUEUE_HPP_ +#define QUEUE_CONCURRENCY_QUEUE_HPP_ + +#include +#include + +template +class ConcurrencyQueue { + public: + using value_type = T; + using container_type = std::queue; + using size_type = typename container_type::size_type; + + private: + container_type container_; + mutable std::mutex mutex_; + + public: + ConcurrencyQueue() = default; + ConcurrencyQueue(const ConcurrencyQueue&) = default; + ConcurrencyQueue(ConcurrencyQueue&&) = default; + ConcurrencyQueue& operator=(const ConcurrencyQueue&) = default; + ConcurrencyQueue& operator=(ConcurrencyQueue&&) = default; + + private: + bool empty() const { return container_.empty(); } +}; + +#endif // QUEUE_CONCURRENCY_QUEUE_HPP_ + From 9db53b54c0b0de305e84e3e4fe17e2d2cf9e1ce5 Mon Sep 17 00:00:00 2001 From: AttackXiaoJinJin Date: Thu, 11 Oct 2018 13:43:09 +0800 Subject: [PATCH 47/69] =?UTF-8?q?=E5=AE=8C=E5=96=84javascript=E7=9A=8407?= =?UTF-8?q?=E9=93=BE=E8=A1=A8=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- javascript/07_linkedlist/LinkedListAlgo.js | 31 +++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/javascript/07_linkedlist/LinkedListAlgo.js b/javascript/07_linkedlist/LinkedListAlgo.js index 39cf6e49..77695c99 100644 --- a/javascript/07_linkedlist/LinkedListAlgo.js +++ b/javascript/07_linkedlist/LinkedListAlgo.js @@ -33,7 +33,7 @@ class LinkedList { currentNode = currentNode.next pos++ } - return currentNode === null ? -1 : pos + return currentNode === null ? -1 : currentNode } // 指定元素向后插入 insert(newElement, element) { @@ -69,6 +69,9 @@ class LinkedList { } // 遍历显示所有节点 display() { + //先检查是否为环 + if(this.checkCircle()) return false + let currentNode = this.head while (currentNode !== null) { console.log(currentNode.element) @@ -89,6 +92,30 @@ class LinkedList { this.head = root } + //增强尾插法可读性,便于初学者理解 + reverseList1(){ + //head节点即哨兵,作用就是使所有链表, + // 包括空链表的头节点不为null,并使对单链表的插入、删除操作不需要区分是否为空表或是否在第一个位置进行, + // 从而与其他位置的插入、删除操作一致 + //所以反转链表的时候不需要带上head节点 + let currentNode=this.head.next + //第一个节点头结点让其指向null + let previousNode=null + while(currentNode!==null){ + //务必先保留下一节点的指针地址 + let nextNode=currentNode.next + //第一次是null + currentNode.next=previousNode + //此时将previousNode赋值为当前节点, + // 那么下次循环的时候,方便下次的currentNode指向previousNode + previousNode=currentNode + //抬走,下一个! + currentNode=nextNode + } + //最后将反转好的链表加上头节点 + this.head.next=previousNode + } + // 自己一开始瞎想的。差距啊 reverseList2() { let currentNode = this.head.next @@ -122,6 +149,8 @@ class LinkedList { } // 删除倒数第k个节点 removeByIndexFromEnd(index) { + //务必先判断是否是 环链表 + if(this.checkCircle()) return false let pos = 1 this.reverseList() let currentNode = this.head.next From 0d077d1f6983cb97620bb0c211b73c52cfcaa3c0 Mon Sep 17 00:00:00 2001 From: Fangyu Gai Date: Wed, 10 Oct 2018 22:57:44 -0700 Subject: [PATCH 48/69] Add data migration --- python/09_queue/array_queue.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/python/09_queue/array_queue.py b/python/09_queue/array_queue.py index 40f34c28..1b1252e7 100644 --- a/python/09_queue/array_queue.py +++ b/python/09_queue/array_queue.py @@ -16,9 +16,16 @@ def __init__(self, capacity: int): self._tail = 0 def enqueue(self, item: str) -> bool: - if self._tail == self._capacity: return False + if self._tail == self._capacity: + if self._head == 0: + return False + else: + for i in range(0, self._tail - self._head): + self._data[i] = self._items[i + self._head] + self._tail = self._tail - self._head + self._head = 0 - self._items.append(item) + self._items.insert(self._tail, item) self._tail += 1 return True From 751da8998fea1f21b63705a33f07301fd1ff7cb0 Mon Sep 17 00:00:00 2001 From: carlos Date: Thu, 11 Oct 2018 14:25:42 +0800 Subject: [PATCH 49/69] =?UTF-8?q?=E6=95=B0=E7=BB=84=E9=80=9A=E7=94=A8?= =?UTF-8?q?=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 数组通用,支持自定义数据类型和基础数据类型 --- c-cpp/05_array/Array_gp.c | 278 ++++++++++++++++++++++++++++++++++++++ c-cpp/05_array/Array_gp.h | 48 +++++++ 2 files changed, 326 insertions(+) create mode 100644 c-cpp/05_array/Array_gp.c create mode 100644 c-cpp/05_array/Array_gp.h diff --git a/c-cpp/05_array/Array_gp.c b/c-cpp/05_array/Array_gp.c new file mode 100644 index 00000000..0147a121 --- /dev/null +++ b/c-cpp/05_array/Array_gp.c @@ -0,0 +1,278 @@ +#include "Array.h" + +#include +#include + +Array* arrayCreate() +{ + struct Array *array = NULL; + array = malloc(sizeof(*array)); + if (NULL == array) + { + return NULL; + } + + array->p = NULL; + + array->size = 0; + array->typeSize = 0; + array->len = 0; + + array->dup = NULL; + array->free = NULL; + array->match = NULL; + + return array; +} + +void arrayInit(Array *array, int size, int typeSize) +{ + if (NULL == array + || typeSize <= 0 + || size < 0) + { + return; + } + + void *p = calloc(1, size* typeSize); + if (NULL == p) + { + return; + } + + array->p = p; + array->len = 0; + array->size = size; + array->typeSize = typeSize; +} + +int arrayInsert(Array *array, size_t pos, void *const value) +{ + if (NULL == array) + { + return -1; + } + + if (array->len >= array->size) + { + return -2; + } + + if (pos > array->size || pos <= 0) + { + return -3; + } + + char *pBegin = array->p; + for (size_t i = array->len; i > pos - 1; --i) + { + void *pNew = pBegin + i * array->typeSize; + void *pOld = pBegin + (i - 1) *array->typeSize; + if (NULL != array->dup) + { + array->dup(pNew, pOld); + } + else + { + memcpy(pNew, pOld, array->typeSize); + } + } + + void *pCopy = (void*)(pBegin + ((pos - 1) * array->typeSize)); + if (NULL != array->dup) + { + array->dup(pCopy, value); + } + else + { + memcpy(pCopy, value, array->typeSize); + } + ++array->len; + return 0; +} + +size_t arraySearchValue(Array *array, void* const value) +{ + if (NULL == array) + { + return -1; + } + + char *pBegin = array->p; + size_t i = 0; + for (; i < array->len; ++i) + { + int nCmp = 0; + if (NULL != array->match) + { + nCmp = array->match(pBegin + i * array->typeSize, value); + } + else + { + nCmp = memcmp(pBegin + i * array->typeSize, value, array->typeSize); + } + + if (nCmp == 0) + { + break; + } + } + + return i; +} + +void* arrayIndex(Array *array, size_t index) +{ + if (NULL == array) + { + return NULL; + } + + if (index > array->len + || index <= 0) + { + return NULL; + } + + char *pBegin = array->p; + return pBegin + array->typeSize * (index - 1); +} + +int arrayModify(Array *array, size_t pos, void *const value) +{ + if (NULL == array) + { + return -1; + } + if (pos > array->len + || pos <= 0) + { + return -2; + } + + char *pBegin = array->p; + void *pOld = pBegin + (pos - 1) * array->typeSize; + if (NULL != array->dup) + { + array->dup(pOld, value); + } + else + { + memcpy(pOld, value, array->typeSize); + } + + return 0; +} + +size_t arrayLen(Array *array) +{ + if (NULL == array) + { + return 0; + } + + return array->len; +} + +size_t arraySize(Array *array) +{ + if (NULL == array) + { + return 0; + } + + return array->size; +} + +void arrayEmpty(Array *array) +{ + if (NULL == array) + { + return; + } + + free(array->p); + array->p = NULL; + free(array); + array = NULL; +} + +void arrayDelValue(Array *array, void *value) +{ + if (NULL == array) + { + return; + } + + char* pBegin = array->p; + bool bCopy = false; + for (size_t i = 0; i < array->len; ++i) + { + if (!bCopy) + { + int nCmp = 0; + if (NULL != array->match) + { + nCmp = array->match(pBegin + i * array->typeSize, value); + } + else + { + nCmp = memcmp(pBegin + i * array->typeSize, value, array->typeSize); + } + + if (0 == nCmp) + { + bCopy = true; + continue; + } + } + else + { + void *pOld = pBegin + (i + 1) * array->typeSize; + void *pNew = pBegin + i * array->typeSize; + if (NULL != array->dup) + { + array->dup(pNew, pOld); + } + else + { + memcpy(pNew, pOld, array->typeSize); + } + } + } + + if (bCopy) + { + --array->len; + } +} + +void arrayDelIndex(Array *array, size_t pos) +{ + if (NULL == array) + { + return; + } + + if (pos > array->len || pos <= 0) + { + return; + } + + char* pBegin = array->p; + for (size_t i = pos - 1; i < array->len - 1; ++i) + { + void *pOld = pBegin + (i + 1) * array->typeSize; + void *pNew = pBegin + i * array->typeSize; + if (NULL != array->dup) + { + array->dup(pNew, pOld); + } + else + { + memcpy(pNew, pOld, array->typeSize); + } + } + + --array->len; +} \ No newline at end of file diff --git a/c-cpp/05_array/Array_gp.h b/c-cpp/05_array/Array_gp.h new file mode 100644 index 00000000..662ef8a5 --- /dev/null +++ b/c-cpp/05_array/Array_gp.h @@ -0,0 +1,48 @@ +#ifndef __ARRAY_H__ +#define __ARRAY_H__ + +#include +#include + +typedef struct Array +{ + // pָĿռС + size_t size; + // pָѾʹõĿռС + size_t len; + // ͵ĴС + size_t typeSize; + // ֵƺ + void(*dup)(void *ptr, void *key); + // ֵͷź + void(*free)(void *ptr); + // ֵȽϺ + int(*match)(void *ptr, void *key); + // ݵָ + void *p; +}Array; + +#define arraySetDupMethod(a, m) ((a)->dup = (m)) +#define arraySetFreeMethod(a, m) ((a)->free = (m)) +#define arraySetMatchMethod(a, m) ((a)->match = (m)) + +#define arrayGetDupMethod(a) ((a)->dup) +#define arrayGetFree(a) ((a)->free) +#define arrayGetMatchMethod(a) ((a)->match) + +Array* arrayCreate(); +void arrayInit(Array *array, int size, int typeSize); + +int arrayInsert(Array *array, size_t pos, void *const value); +size_t arraySearchValue(Array *array, void* const value); +void* arrayIndex(Array *array, size_t index); +int arrayModify(Array *array, size_t pos, void *const value); + +size_t arrayLen(Array *array); +size_t arraySize(Array *array); + +void arrayEmpty(Array *array); +void arrayDelValue(Array *array, void *value); +void arrayDelIndex(Array *array, size_t pos); + +#endif // !__ARRAY_H__ \ No newline at end of file From e3cfa2cad931aac7f912c787e8af61cd1e167fb7 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Thu, 11 Oct 2018 17:23:51 +0800 Subject: [PATCH 50/69] [09_queue] concurrency, concurrency_queue, done. --- c-cpp/09_queue/concurrency_queue.hpp | 53 +++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/c-cpp/09_queue/concurrency_queue.hpp b/c-cpp/09_queue/concurrency_queue.hpp index cee58804..8e9bb787 100644 --- a/c-cpp/09_queue/concurrency_queue.hpp +++ b/c-cpp/09_queue/concurrency_queue.hpp @@ -7,6 +7,8 @@ #include #include +#include +#include template class ConcurrencyQueue { @@ -18,6 +20,7 @@ class ConcurrencyQueue { private: container_type container_; mutable std::mutex mutex_; + std::condition_variable container_cond_; public: ConcurrencyQueue() = default; @@ -27,7 +30,55 @@ class ConcurrencyQueue { ConcurrencyQueue& operator=(ConcurrencyQueue&&) = default; private: - bool empty() const { return container_.empty(); } + bool empty_() const { return container_.empty(); } + + public: + bool empty() const { + std::lock_guard lg(mutex_); + return container_.empty(); + } + void push(value_type item) { + std::lock_guard lg(mutex_); + container_.push(std::move(item)); + container_cond_.notify_one(); + } + void wait_and_pop(value_type& out) { + std::unique_lock lk(mutex_); + while (empty_()) { + container_cond_.wait(lk) + } + out = std::move(container_.front()); + container_.pop(); + } + std::shared_ptr wait_and_pop() { + std::unique_lock lk(mutex_); + while (empty_()) { + container_cond_.wait(lk) + } + auto res = std::make_shared(std::move(container_.front())); + container_.pop(); + return res; + } + bool try_pop(value_type& out) { + std::lock_guard lg(mutex_); + if (empty_()) { + return false; + } else { + out = std::move(container_.front()); + container_.pop(); + return true; + } + } + std::shared_ptr try_pop() { + std::lock_guard lg(mutex_); + if (empty_()) { + return nullptr; + } else { + auto res = std::make_shared(std::move(container_.front())); + container_.pop(); + return res; + } + } }; #endif // QUEUE_CONCURRENCY_QUEUE_HPP_ From c2f1a0f4a2961c48064b6f06384cae5891757c77 Mon Sep 17 00:00:00 2001 From: nameczz Date: Thu, 11 Oct 2018 17:36:27 +0800 Subject: [PATCH 51/69] [javascript] add 09_queue CircularQueueBasedOnLinkedList and QueueBasedOnLinkedList --- .../CircularQueueBasedOnLinkedList.js | 71 +++++++++++++++++++ javascript/09_queue/QueueBasedOnLinkedList.js | 52 ++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 javascript/09_queue/CircularQueueBasedOnLinkedList.js create mode 100644 javascript/09_queue/QueueBasedOnLinkedList.js diff --git a/javascript/09_queue/CircularQueueBasedOnLinkedList.js b/javascript/09_queue/CircularQueueBasedOnLinkedList.js new file mode 100644 index 00000000..a94f46dc --- /dev/null +++ b/javascript/09_queue/CircularQueueBasedOnLinkedList.js @@ -0,0 +1,71 @@ +/** + * 基于链表实现的循环队列。 + * + * Author: nameczz + */ + +class Node { + constructor(element) { + this.element = element + this.next = null + } +} + +class CircularQueue { + constructor() { + this.head = null + this.tail = null + } + + enqueue(value) { + if (this.head === null) { + this.head = new Node(value) + this.head.next = this.head + this.tail = this.head + } else { + const flag = this.head === this.tail + this.tail.next = new Node(value) + this.tail.next.next = this.head + this.tail = this.tail.next + if (flag) { + this.head.next = this.tail + } + } + } + + dequeue() { + if (this.head === this.tail) { + const value = this.head.element + this.head = null + return value + } else if (this.head !== null) { + const value = this.head.element + this.head = this.head.next + this.tail.next = this.head + return value + } else { + return -1 + } + } + + display() { + let res = 0 + console.log('-------获取dequeue元素------') + while (res !== -1) { + res = this.dequeue() + console.log(res) + } + } +} +// Test +const newCircularQueue = new CircularQueue() +// 插入元素 +newCircularQueue.enqueue(1) +newCircularQueue.enqueue(2) +newCircularQueue.enqueue(3) +// 获取元素 +newCircularQueue.display() +newCircularQueue.enqueue(1) +newCircularQueue.display() + +// exports.CreatedStack = StackBasedLinkedList \ No newline at end of file diff --git a/javascript/09_queue/QueueBasedOnLinkedList.js b/javascript/09_queue/QueueBasedOnLinkedList.js new file mode 100644 index 00000000..75918585 --- /dev/null +++ b/javascript/09_queue/QueueBasedOnLinkedList.js @@ -0,0 +1,52 @@ +/** + * 基于链表实现的队列。 + * + * Author: nameczz + */ + +class Node { + constructor(element) { + this.element = element + this.next = null + } +} + +class QueueBasedOnLinkedList { + constructor() { + this.head = null + this.tail = null + } + + enqueue(value) { + if (this.head === null) { + this.head = new Node(value) + this.tail = this.head + } else { + this.tail.next = new Node(value) + this.tail = this.tail.next + } + } + + dequeue() { + if (this.head !== null) { + const value = this.head.element + this.head = this.head.next + return value + } else { + return -1 + } + } +} +// Test +const newQueue = new QueueBasedOnLinkedList() +// 插入元素 +newQueue.enqueue(1) +newQueue.enqueue(2) +newQueue.enqueue(3) +// 获取元素 +let res = 0 +console.log('-------获取dequeue元素------') +while (res !== -1) { + res = newQueue.dequeue() + console.log(res) +} From ee3253afddf3792ff2b6a092d3664925bbe3718c Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Thu, 11 Oct 2018 18:01:33 +0800 Subject: [PATCH 52/69] [09_queue] concurrency, lock_free_queue, done. --- c-cpp/09_queue/lock_free_queue.hpp | 74 ++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 c-cpp/09_queue/lock_free_queue.hpp diff --git a/c-cpp/09_queue/lock_free_queue.hpp b/c-cpp/09_queue/lock_free_queue.hpp new file mode 100644 index 00000000..23cf2613 --- /dev/null +++ b/c-cpp/09_queue/lock_free_queue.hpp @@ -0,0 +1,74 @@ +/** + * Created by Liam Huang (Liam0205) on 2018/10/11. + */ + +#ifndef QUEUE_LOCK_FREE_QUEUE_HPP_ +#define QUEUE_LOCK_FREE_QUEUE_HPP_ + +#include +#include + +template +class LockFreeQueue { + public: + using value_type = T; + + private: + struct node { + std::shared data = nullptr; + node* next = nullptr; + }; + std::atomic head = nullptr; + std::atomic tail = nullptr; + + public: + LockFreeQueue() head(new node), tail(head.load()) {} + LockFreeQueue(const LockFreeQueue&) = delete; + LockFreeQueue& operator=(const LockFreeQueue&) = delete; + // TODO(Liam Huang): move constructor and move assignment should be well implemented later, + // and hance marked "delete". + LockFreeQueue(LockFreeQueue&&) = delete; + LockFreeQueue& operator=(LockFreeQueue&&) = delete; + ~LockFreeQueue() { + while (node* const old_head = head.load()) { + head.store(old_head->next); + delete old_head; + } + } + + private: + node* pop_head() { + node* const res = head.load(); + if (res == tail.load()) { + return nullptr; + } + head.store(res->next); + return res; + } + + public: + bool empty() const { + return head.load() == tail.load(); + } + std::shared_ptr pop() { + node* old_head = pop_head(); + if (nullptr == old_head) { + return nullptr; + } else { + auto res = old_head->data; + delete old_head; + return res; + } + } + void push(value_type new_value) { + auto new_data = std::make_shared(new_value); + node* p = new node; + node* old_tail = tail.load(); + old_tail->data.swap(new_data); + old_tail->next = p; + tail_.store(p); + } +}; + +#endif // QUEUE_LOCK_FREE_QUEUE_HPP_ + From 038359ef2620b1b78e4d79757d882d888501096d Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Thu, 11 Oct 2018 18:06:05 +0800 Subject: [PATCH 53/69] [09_queue] concurrency, lock_free_queue, updated. --- c-cpp/09_queue/lock_free_queue.hpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/c-cpp/09_queue/lock_free_queue.hpp b/c-cpp/09_queue/lock_free_queue.hpp index 23cf2613..3f02d8ae 100644 --- a/c-cpp/09_queue/lock_free_queue.hpp +++ b/c-cpp/09_queue/lock_free_queue.hpp @@ -24,11 +24,21 @@ class LockFreeQueue { public: LockFreeQueue() head(new node), tail(head.load()) {} LockFreeQueue(const LockFreeQueue&) = delete; + LockFreeQueue(LockFreeQueue&& other) : head(other.head.load()), tail(other.tail.load()) { + other.head.store(nullptr); + other.tail.store(nullptr); + } LockFreeQueue& operator=(const LockFreeQueue&) = delete; - // TODO(Liam Huang): move constructor and move assignment should be well implemented later, - // and hance marked "delete". - LockFreeQueue(LockFreeQueue&&) = delete; - LockFreeQueue& operator=(LockFreeQueue&&) = delete; + LockFreeQueue& operator=(LockFreeQueue&& rhs) { + while (node* const old_head = head.load()) { + head.store(old_head->next); + delete old_head; + } + head.store(rhs.head.load()); + tail.store(rhs.tail.load()); + rhs.head.store(nullptr); + rhs.tail.store(nullptr); + } ~LockFreeQueue() { while (node* const old_head = head.load()) { head.store(old_head->next); From d1f416973e6350f41317c694fdcebbb24e653eac Mon Sep 17 00:00:00 2001 From: Jiandan Date: Thu, 11 Oct 2018 19:09:50 +0800 Subject: [PATCH 54/69] [swift] [05_array] [add] --- swift/05_array/MyArray.swift | 77 ++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 swift/05_array/MyArray.swift diff --git a/swift/05_array/MyArray.swift b/swift/05_array/MyArray.swift new file mode 100644 index 00000000..42a135b6 --- /dev/null +++ b/swift/05_array/MyArray.swift @@ -0,0 +1,77 @@ +// +// Created by Jiandan on 2018/10/10. +// Copyright (c) 2018 Jiandan. All rights reserved. +// + +import Foundation + +// Swift 泛型,此数组支持不同数据类型 +public struct MyArray { + private var data: [Element] + private var capacity = 0 // 数组长度 + private var count = 0 // 已保存的数据个数 + + /// 构造方法 + /// - parameter defaultElement: 默认元素,用来占位 + /// - parameter capacity: 数组长度 + init(defaultElement: Element, capacity: Int) { + data = [Element](repeating: defaultElement, count: capacity) + self.capacity = capacity + } + + // 根据 index,查找元素 + func find(at index: Int) -> Element? { + // index 必须在 [0, count) + guard index >= 0, index < count else { + return nil + } + + return data[index] + } + + // 根据 index,删除元素 + mutating func delete(at index: Int) -> Bool { + // index 必须在 [0, count) + guard index >= 0, index < count else { + return false + } + + // [index, count - 1) 从 index 开始,元素分别向前移动一位 + for i in index ..< count - 1 { + data[i] = data[i+1] + } + count -= 1 + return true + } + + // 根据 index 插入元素 + mutating func insert(value: Element, at index: Int) -> Bool { + // index 必须在 [0, count) + guard index >= 0, index < count, count < capacity else { + return false + } + + // count - 1 ~ index + for i in (index ... count - 1).reversed() { + data[i + 1] = data[i] + } + + data[index] = value + count += 1 + return true + } + + // 添加元素 + mutating func add(value: Element) -> Bool { + guard count < capacity else { + return false + } + data[count] = value + count += 1 + return true + } + + func printAll() { + print("\(data)") + } +} From 7540c6c23f749269241a7269292501d4f1a48cb6 Mon Sep 17 00:00:00 2001 From: Hkesd Date: Thu, 11 Oct 2018 20:11:09 +0800 Subject: [PATCH 55/69] php 08_stack --- php/06_linkedlist/SingleLinkedList.php | 2 +- php/08_stack/.gitkeep | 0 php/08_stack/StackOnLinkedList.php | 159 +++++++++++++++++++++++++ php/08_stack/main.php | 32 +++++ php/README.md | 12 +- php/composer.json | 3 +- 6 files changed, 202 insertions(+), 6 deletions(-) create mode 100644 php/08_stack/.gitkeep create mode 100644 php/08_stack/StackOnLinkedList.php create mode 100644 php/08_stack/main.php diff --git a/php/06_linkedlist/SingleLinkedList.php b/php/06_linkedlist/SingleLinkedList.php index 59288601..222f638a 100644 --- a/php/06_linkedlist/SingleLinkedList.php +++ b/php/06_linkedlist/SingleLinkedList.php @@ -133,7 +133,7 @@ public function getPreNode(SingleLinkedListNode $node) $preNode = $this->head; // 遍历找到前置节点 要用全等判断是否是同一个对象 // http://php.net/manual/zh/language.oop5.object-comparison.php - while ($curNode !== $node) { + while ($curNode !== $node && $curNode != null) { $preNode = $curNode; $curNode = $curNode->next; } diff --git a/php/08_stack/.gitkeep b/php/08_stack/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/php/08_stack/StackOnLinkedList.php b/php/08_stack/StackOnLinkedList.php new file mode 100644 index 00000000..bfac655d --- /dev/null +++ b/php/08_stack/StackOnLinkedList.php @@ -0,0 +1,159 @@ +head = new SingleLinkedListNode(); + $this->length = 0; + } + + /** + * 出栈 + * + * @return bool + */ + public function pop() + { + if (0 == $this->length) { + return false; + } + + $this->head->next = $this->head->next->next; + $this->length--; + + return true; + } + + /** + * 入栈 + * + * @param $data + * + * @return SingleLinkedListNode|bool + */ + public function push($data) + { + return $this->pushData($data); + } + + /** + * 入栈 node + * + * @param SingleLinkedListNode $node + * + * @return bool + */ + public function pushNode(SingleLinkedListNode $node) + { + if (null == $node) { + return false; + } + + $node->next = $this->head->next; + $this->head->next = $node; + + $this->length++; + return true; + } + + /** + * 入栈 data + * + * @param $data + * + * @return SingleLinkedListNode|bool + */ + public function pushData($data) + { + $node = new SingleLinkedListNode($data); + + if (!$this->pushNode($node)) { + return false; + } + + return $node; + } + + /** + * 获取栈顶元素 + * + * @return SingleLinkedListNode|bool|null + */ + public function top() + { + if (0 == $this->length) { + return false; + } + + return $this->head->next; + } + + /** + * 打印栈 + */ + public function printSelf() + { + if (0 == $this->length) { + echo 'empty stack' . PHP_EOL; + return; + } + + echo 'head.next -> '; + $curNode = $this->head; + while ($curNode->next) { + echo $curNode->next->data . ' -> '; + + $curNode = $curNode->next; + } + echo 'NULL' . PHP_EOL; + } + + /** + * 获取栈长度 + * + * @return int + */ + public function getLength() + { + return $this->length; + } + + /** + * 判断栈是否为空 + * + * @return bool + */ + public function isEmpty() + { + return $this->length > 0 ? false : true; + } +} \ No newline at end of file diff --git a/php/08_stack/main.php b/php/08_stack/main.php new file mode 100644 index 00000000..63478217 --- /dev/null +++ b/php/08_stack/main.php @@ -0,0 +1,32 @@ +pushData(1); +$stack->pushData(2); +$stack->pushData(3); +$stack->pushData(4); +var_dump($stack->getLength()); +$stack->printSelf(); + +$topNode = $stack->top(); +var_dump($topNode->data); + +$stack->pop(); +$stack->printSelf(); +$stack->pop(); +$stack->printSelf(); + +var_dump($stack->getLength()); + +$stack->pop(); +$stack->pop(); +$stack->printSelf(); \ No newline at end of file diff --git a/php/README.md b/php/README.md index 3aa96741..6a6fa5d1 100644 --- a/php/README.md +++ b/php/README.md @@ -1,16 +1,20 @@ ## 数据结构与算法之美PHP实现 ### 项目运行 -* 依赖composer自动加载,php目录下执行`composer dump-autoload` +* 依赖composer自动加载,php目录下执行`composer dump-autoload` || `sh buildAutoLoad.sh` * 项目代码均在mac&php7环境下跑通 ### 项目实现 -#### 06 +#### 06_linkedlist * 单链表php实现 * 回文判断 -#### 07 + +#### 07_linkedlist * reverse 单链表反转 * checkCircle 链表中环的检测 * mergerSortedList 两个有序的链表合并 * deleteLastKth 删除链表倒数第n个结点 -* findMiddleNode 求链表的中间结点 \ No newline at end of file +* findMiddleNode 求链表的中间结点 + +#### 08_stack +* 链栈实现 \ No newline at end of file diff --git a/php/composer.json b/php/composer.json index ea60240e..01f6f022 100644 --- a/php/composer.json +++ b/php/composer.json @@ -6,7 +6,8 @@ "autoload": { "psr-4": { "Algo_06\\": "06_linkedlist/", - "Algo_07\\": "07_linkedlist/" + "Algo_07\\": "07_linkedlist/", + "Algo_08\\": "08_stack/" } } } From 6eca2be3498f2cbd2d05b9c287303c608e8c9883 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Thu, 11 Oct 2018 22:21:51 +0800 Subject: [PATCH 56/69] [notes] notes, start. --- notes/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 notes/.gitkeep diff --git a/notes/.gitkeep b/notes/.gitkeep new file mode 100644 index 00000000..e69de29b From 2029a4de8d29d9dae76a063bf6a514f5c3b66063 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 11 Oct 2018 22:33:32 +0800 Subject: [PATCH 57/69] 09_queue --- go/09_queue/CircularQueue.go | 72 ++++++++++++++++++++++ go/09_queue/CircularQueue_test.go | 37 +++++++++++ go/09_queue/QueueBasedOnArray.go | 44 +++++++++++++ go/09_queue/QueueBasedOnArray_test.go | 35 +++++++++++ go/09_queue/QueueBasedOnLinkedList.go | 52 ++++++++++++++++ go/09_queue/QueueBasedOnLinkedList_test.go | 35 +++++++++++ 6 files changed, 275 insertions(+) create mode 100644 go/09_queue/CircularQueue.go create mode 100644 go/09_queue/CircularQueue_test.go create mode 100644 go/09_queue/QueueBasedOnArray.go create mode 100644 go/09_queue/QueueBasedOnArray_test.go create mode 100644 go/09_queue/QueueBasedOnLinkedList.go create mode 100644 go/09_queue/QueueBasedOnLinkedList_test.go diff --git a/go/09_queue/CircularQueue.go b/go/09_queue/CircularQueue.go new file mode 100644 index 00000000..c2284909 --- /dev/null +++ b/go/09_queue/CircularQueue.go @@ -0,0 +1,72 @@ +package _9_queue + +import "fmt" + +type CircularQueue struct { + q []interface{} + capacity int + head int + tail int +} + +func NewCircularQueue(n int) *CircularQueue { + if n == 0 { + return nil + } + return &CircularQueue{make([]interface{}, n), n, 0, 0} +} + +/* +栈空条件:head==tail为true +*/ +func (this *CircularQueue) IsEmpty() bool { + if this.head == this.tail { + return true + } + return false +} + +/* +栈满条件:(tail+1)%capacity==head为true +*/ +func (this *CircularQueue) IsFull() bool { + if this.head == (this.tail+1)%this.capacity { + return true + } + return false +} + +func (this *CircularQueue) EnQueue(v interface{}) bool { + if this.IsFull() { + return false + } + this.q[this.tail] = v + this.tail = (this.tail + 1) % this.capacity + return true +} + +func (this *CircularQueue) DeQueue() interface{} { + if this.IsEmpty() { + return nil + } + v := this.q[this.head] + this.head = (this.head + 1) % this.capacity + return v +} + +func (this *CircularQueue) String() string { + if this.IsEmpty() { + return "empty queue" + } + result := "head" + var i = this.head + for true { + result += fmt.Sprintf("<-%+v", this.q[i]) + i = (i + 1) % this.capacity + if i == this.tail { + break + } + } + result += "<-tail" + return result +} diff --git a/go/09_queue/CircularQueue_test.go b/go/09_queue/CircularQueue_test.go new file mode 100644 index 00000000..59c64417 --- /dev/null +++ b/go/09_queue/CircularQueue_test.go @@ -0,0 +1,37 @@ +package _9_queue + +import "testing" + +func TestCircularQueue_EnQueue(t *testing.T) { + q := NewCircularQueue(5) + q.EnQueue(1) + q.EnQueue(2) + q.EnQueue(3) + q.EnQueue(4) + q.EnQueue(5) + q.EnQueue(6) + t.Log(q) +} + +func TestCircularQueue_DeQueue(t *testing.T) { + q := NewCircularQueue(5) + q.EnQueue(1) + q.EnQueue(2) + q.EnQueue(3) + q.EnQueue(4) + q.EnQueue(5) + q.EnQueue(6) + t.Log(q) + t.Log(q.DeQueue()) + t.Log(q) + q.EnQueue(5) + t.Log(q) + q.DeQueue() + t.Log(q) + q.DeQueue() + t.Log(q) + q.DeQueue() + t.Log(q) + q.DeQueue() + t.Log(q) +} diff --git a/go/09_queue/QueueBasedOnArray.go b/go/09_queue/QueueBasedOnArray.go new file mode 100644 index 00000000..d70335f5 --- /dev/null +++ b/go/09_queue/QueueBasedOnArray.go @@ -0,0 +1,44 @@ +package _9_queue + +import "fmt" + +type ArrayQueue struct { + q []interface{} + capacity int + head int + tail int +} + +func NewArrayQueue(n int) *ArrayQueue { + return &ArrayQueue{make([]interface{}, n), n, 0, 0} +} + +func (this *ArrayQueue) EnQueue(v interface{}) bool { + if this.tail == this.capacity { + return false + } + this.q[this.tail] = v + this.tail++ + return true +} + +func (this *ArrayQueue) DeQueue() interface{} { + if this.head == this.tail { + return nil + } + v := this.q[this.head] + this.head++ + return v +} + +func (this *ArrayQueue) String() string { + if this.head == this.tail { + return "empty queue" + } + result := "head" + for i := this.head; i <= this.tail-1; i++ { + result += fmt.Sprintf("<-%+v", this.q[i]) + } + result += "<-tail" + return result +} diff --git a/go/09_queue/QueueBasedOnArray_test.go b/go/09_queue/QueueBasedOnArray_test.go new file mode 100644 index 00000000..50335f7f --- /dev/null +++ b/go/09_queue/QueueBasedOnArray_test.go @@ -0,0 +1,35 @@ +package _9_queue + +import "testing" + +func TestArrayQueue_EnQueue(t *testing.T) { + q := NewArrayQueue(5) + q.EnQueue(1) + q.EnQueue(2) + q.EnQueue(3) + q.EnQueue(4) + q.EnQueue(5) + q.EnQueue(6) + t.Log(q) +} + +func TestArrayQueue_DeQueue(t *testing.T) { + q := NewArrayQueue(5) + q.EnQueue(1) + q.EnQueue(2) + q.EnQueue(3) + q.EnQueue(4) + q.EnQueue(5) + q.EnQueue(6) + t.Log(q) + q.DeQueue() + t.Log(q) + q.DeQueue() + t.Log(q) + q.DeQueue() + t.Log(q) + q.DeQueue() + t.Log(q) + q.DeQueue() + t.Log(q) +} diff --git a/go/09_queue/QueueBasedOnLinkedList.go b/go/09_queue/QueueBasedOnLinkedList.go new file mode 100644 index 00000000..65d898da --- /dev/null +++ b/go/09_queue/QueueBasedOnLinkedList.go @@ -0,0 +1,52 @@ +package _9_queue + +import "fmt" + +type ListNode struct { + val interface{} + next *ListNode +} + +type LinkedListQueue struct { + head *ListNode + tail *ListNode + length int +} + +func NewLinkedListQueue() *LinkedListQueue { + return &LinkedListQueue{nil, nil, 0} +} + +func (this *LinkedListQueue) EnQueue(v interface{}) { + node := &ListNode{v, nil} + if nil == this.tail { + this.tail = node + this.head = node + } else { + this.tail.next = node + this.tail = node + } + this.length++ +} + +func (this *LinkedListQueue) DeQueue() interface{} { + if this.head == nil { + return nil + } + v := this.head.val + this.head = this.head.next + this.length-- + return v +} + +func (this *LinkedListQueue) String() string { + if this.head == nil { + return "empty queue" + } + result := "head<-" + for cur := this.head; cur != nil; cur = cur.next { + result += fmt.Sprintf("<-%+v", cur.val) + } + result += "<-tail" + return result +} diff --git a/go/09_queue/QueueBasedOnLinkedList_test.go b/go/09_queue/QueueBasedOnLinkedList_test.go new file mode 100644 index 00000000..425c6e8a --- /dev/null +++ b/go/09_queue/QueueBasedOnLinkedList_test.go @@ -0,0 +1,35 @@ +package _9_queue + +import "testing" + +func TestListQueue_EnQueue(t *testing.T) { + q := NewLinkedListQueue() + q.EnQueue(1) + q.EnQueue(2) + q.EnQueue(3) + q.EnQueue(4) + q.EnQueue(5) + q.EnQueue(6) + t.Log(q) +} + +func TestListQueue_DeQueue(t *testing.T) { + q := NewLinkedListQueue() + q.EnQueue(1) + q.EnQueue(2) + q.EnQueue(3) + q.EnQueue(4) + q.EnQueue(5) + q.EnQueue(6) + t.Log(q) + q.DeQueue() + t.Log(q) + q.DeQueue() + t.Log(q) + q.DeQueue() + t.Log(q) + q.DeQueue() + t.Log(q) + q.DeQueue() + t.Log(q) +} From fc167fd11f284e64b800b583e5bec6382e762548 Mon Sep 17 00:00:00 2001 From: Jiandan Date: Thu, 11 Oct 2018 22:56:35 +0800 Subject: [PATCH 58/69] [swift] [09_queue] [add] --- swift/09_queue/ArrayQueue.swift | 112 ++++++++++++++++++++ swift/09_queue/CircularQueue.swift | 63 +++++++++++ swift/09_queue/Queue.swift | 21 ++++ swift/09_queue/QueueBasedOnLinkedList.swift | 61 +++++++++++ 4 files changed, 257 insertions(+) create mode 100644 swift/09_queue/ArrayQueue.swift create mode 100644 swift/09_queue/CircularQueue.swift create mode 100644 swift/09_queue/Queue.swift create mode 100644 swift/09_queue/QueueBasedOnLinkedList.swift diff --git a/swift/09_queue/ArrayQueue.swift b/swift/09_queue/ArrayQueue.swift new file mode 100644 index 00000000..1dea014b --- /dev/null +++ b/swift/09_queue/ArrayQueue.swift @@ -0,0 +1,112 @@ +// +// Created by Jiandan on 2018/10/11. +// Copyright (c) 2018 Jiandan. All rights reserved. +// + +import Foundation + +/// 用数组实现的队列 +struct ArrayQueue: Queue { + typealias Element = T + + /// 数组 + private var items: [Element] + /// 数组最大长度 + private var capacity = 0 + /// 队头下标 + private var head = 0 + /// 队尾下标 + private var tail = 0 + + /// 构造方法 + /// - parameter defaultElement: 默认元素 + /// - parameter capacity: 数组长度 + init(defaultElement: Element, capacity: Int) { + self.capacity = capacity + items = [Element](repeating: defaultElement, count: capacity) + } + + // MARK: Protocol: Queue + + var isEmpty: Bool { return head == tail } + + var size: Int { return tail - head } + + var peek: Element? { return isEmpty ? nil : items[head] } + + // 没有数据搬移的实现,即实现了一个有界序列 +// mutating func enqueue(newElement: Element) -> Bool { +// // 整个队列都占满了 +// if tail == capacity { +// return false +// } +// +// items[tail] = newElement +// tail += 1 +// return true +// } + // 有数据搬移的实现,即实现了一个无界序列 + mutating func enqueue(newElement: Element) -> Bool { + // 如果 tail == capacity 表示队列末尾没有空间了 + if tail == capacity { + // 整个队列都占满了 + if head == 0 { return false } + // 数据搬移 + for i in head ..< tail { + items[i - head] = items[i] + } + // 搬移完之后重新更新 head 和 tail + tail -= head + head = 0 + } + + items[tail] = newElement + tail += 1 + return true + } + + mutating func dequeue() -> Element? { + if isEmpty { + return nil + } + + let item = items[head] + head += 1 + return item + } +} + +/// 使用2个数组实现无界队列,用到 Swift 中 Array 较多的方法 +/// 来源:《iOS 面试之道》(故胤道长,唐巧) +struct ArrayQueue2: Queue { + typealias Element = T + + /// 输入数组,主要负责入队 + var inArray = [Element]() + /// 输出数组,主要负责出队 + var outArray = [Element]() + + var isEmpty: Bool { return inArray.isEmpty && outArray.isEmpty } + + var size: Int { return inArray.count + outArray.count } + + // 当 outArray 为空时,返回 inArray 首个元素,否则返回 outArray 末尾元素 + var peek: Element? { return outArray.isEmpty ? inArray.first : outArray.last } + + mutating func enqueue(newElement: Element) -> Bool { + // inArray 添加元素 + inArray.append(newElement) + return true + } + + mutating func dequeue() -> Element? { + if outArray.isEmpty { + // 将 inArray 倒序存入 outArray 中 + outArray = inArray.reversed() + // 清空 inArray + inArray.removeAll() + } + // 弹出 outArray 最后一个元素 + return outArray.popLast() + } +} diff --git a/swift/09_queue/CircularQueue.swift b/swift/09_queue/CircularQueue.swift new file mode 100644 index 00000000..6a58f982 --- /dev/null +++ b/swift/09_queue/CircularQueue.swift @@ -0,0 +1,63 @@ +// +// Created by Jiandan on 2018/10/11. +// Copyright (c) 2018 Jiandan. All rights reserved. +// + +import Foundation + +/// 循环队列 +struct CircularQueue: Queue { + typealias Element = T + + /// 数组 + private var items: [Element] + /// 数组最大长度 + private var capacity = 0 + /// 队头下标 + private var head = 0 + /// 队尾下标 + private var tail = 0 + + /// 构造方法 + /// - parameter defaultElement: 默认元素 + /// - parameter capacity: 数组长度 + init(defaultElement: Element, capacity: Int) { + self.capacity = capacity + items = [Element](repeating: defaultElement, count: capacity) + } + + // MARK: Protocol: Queue + + var isEmpty: Bool { return head == tail } + + var size: Int { + if tail >= head { + return tail - head + } else { + return (tail + 1) + (capacity - head) + } + } + + var peek: Element? { return isEmpty ? nil : items[head] } + + mutating func enqueue(newElement: Element) -> Bool { + // 整个队列都占满了 + if (tail + 1) % capacity == head { + return false + } + + items[tail] = newElement + tail = (tail + 1) % capacity + return true + } + + mutating func dequeue() -> Element? { + if isEmpty { + return nil + } + + let item = items[head] + head = (head + 1) % capacity + return item + } +} diff --git a/swift/09_queue/Queue.swift b/swift/09_queue/Queue.swift new file mode 100644 index 00000000..ab0bdd94 --- /dev/null +++ b/swift/09_queue/Queue.swift @@ -0,0 +1,21 @@ +// +// Created by Jiandan on 2018/10/11. +// Copyright (c) 2018 Jiandan. All rights reserved. +// + +import Foundation + +protocol Queue { + /// 持有的数据类型 + associatedtype Element + /// 是否为空 + var isEmpty: Bool { get } + /// 队列大小 + var size: Int { get } + /// 返回队列头部元素 + var peek: Element? { get } + /// 入队 + mutating func enqueue(newElement: Element) -> Bool + /// 出队 + mutating func dequeue() -> Element? +} diff --git a/swift/09_queue/QueueBasedOnLinkedList.swift b/swift/09_queue/QueueBasedOnLinkedList.swift new file mode 100644 index 00000000..be737950 --- /dev/null +++ b/swift/09_queue/QueueBasedOnLinkedList.swift @@ -0,0 +1,61 @@ +// +// Created by Jiandan on 2018/10/11. +// Copyright (c) 2018 Jiandan. All rights reserved. +// + +import Foundation + +class Node { + var value: T? + var next: Node? + + init(value: T) { + self.value = value + } +} + +struct QueueBasedOnLinkedList: Queue { + typealias Element = T + + /// 队首 + var head: Node? + /// 队尾 + var tail: Node? + + // MARK: Protocol: Queue + + var isEmpty: Bool { return head == nil } + + var size: Int { + var count = 0 + while head?.next != nil { + count += 1 + } + return count + } + + var peek: Element? { return head?.value } + + mutating func enqueue(newElement: Element) -> Bool { + if isEmpty { + // 空队列 + let node = Node(value: newElement) + head = node + tail = node + } else { + tail!.next = Node(value: newElement) + tail = tail!.next + } + return true + } + + mutating func dequeue() -> Element? { + if isEmpty { + return nil + } + + let node = head + head = head!.next + return node?.value + } +} From be1244ea463dfb3d1d8e10007a3e285b877f0e66 Mon Sep 17 00:00:00 2001 From: Wenru Dong Date: Thu, 11 Oct 2018 17:28:20 +0100 Subject: [PATCH 59/69] [Issue 34]fixed bug in merge_sorted_list --- python/07_linkedlist/linked_list_algo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/07_linkedlist/linked_list_algo.py b/python/07_linkedlist/linked_list_algo.py index 94271265..4d69ae83 100644 --- a/python/07_linkedlist/linked_list_algo.py +++ b/python/07_linkedlist/linked_list_algo.py @@ -55,7 +55,7 @@ def merge_sorted_list(l1: Node, l2: Node) -> Optional[Node]: current = current._next current._next = p1 if p1 else p2 return fake_head._next - return p1 or p2 + return l1 or l2 # Remove nth node from the end # 删除倒数第n个节点。假设n大于0 From 01ae89d478c51703914e1a9b161c1b8c4471c476 Mon Sep 17 00:00:00 2001 From: Wenru Dong Date: Thu, 11 Oct 2018 17:46:43 +0100 Subject: [PATCH 60/69] [Issue 49]fix bug of deleting and then insert to tail --- python/05_array/myarray.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/python/05_array/myarray.py b/python/05_array/myarray.py index af554804..e4df25bb 100644 --- a/python/05_array/myarray.py +++ b/python/05_array/myarray.py @@ -39,7 +39,10 @@ def insert(self, index: int, value: int) -> bool: def insert_to_tail(self, value: int) -> bool: if self._count == self._capacity: return False - self._data.append(value) + if self._count == len(self._data): + self._data.append(value) + else: + self._data[self._count] = value self._count += 1 return True @@ -57,4 +60,6 @@ def print_all(self): a.insert_to_tail(i) a.delete(2) + print(a) + a.insert_to_tail(7) print(a) \ No newline at end of file From 1c6b5e932ff487f7cd26a1c1bdd7185d44b5f403 Mon Sep 17 00:00:00 2001 From: Wenru Dong Date: Thu, 11 Oct 2018 20:03:29 +0100 Subject: [PATCH 61/69] implementation of DynamicArray and queue based upon linked list in python --- python/09_queue/dynamic_array_queue.py | 51 ++++++++++++++++++++++ python/09_queue/linked_queue.py | 58 ++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 python/09_queue/dynamic_array_queue.py create mode 100644 python/09_queue/linked_queue.py diff --git a/python/09_queue/dynamic_array_queue.py b/python/09_queue/dynamic_array_queue.py new file mode 100644 index 00000000..b4228403 --- /dev/null +++ b/python/09_queue/dynamic_array_queue.py @@ -0,0 +1,51 @@ +""" + Author: Wenru +""" + +from typing import Optional + +class DynamicArrayQueue: + + def __init__(self, capacity: int): + self._items = [] + self._capacity = capacity + self._head = 0 + self._tail = 0 + + def enqueue(self, item: str) -> bool: + if self._tail == self._capacity: + if self._head == 0: return False + + self._items[0 : self._tail - self._head] = self._items[self._head : self._tail] + self._tail -= self._head + self._head = 0 + + if self._tail == len(self._items): + self._items.append(item) + else: + self._items[self._tail] = item + self._tail += 1 + return True + + def dequeue(self) -> Optional[str]: + if self._head != self._tail: + item = self._items[self._head] + self._head += 1 + return item + + def __repr__(self) -> str: + return " ".join(item for item in self._items[self._head:self._tail]) + +if __name__ == "__main__": + q = DynamicArrayQueue(10) + for i in range(10): + q.enqueue(str(i)) + print(q) + + for _ in range(3): + q.dequeue() + print(q) + + q.enqueue("7") + q.enqueue("8") + print(q) \ No newline at end of file diff --git a/python/09_queue/linked_queue.py b/python/09_queue/linked_queue.py new file mode 100644 index 00000000..4ee4ecf0 --- /dev/null +++ b/python/09_queue/linked_queue.py @@ -0,0 +1,58 @@ +""" + Queue based upon linked list + + Author: Wenru +""" + +from typing import Optional + +class Node: + + def __init__(self, data: str, next=None): + self.data = data + self._next = next + +class LinkedQueue: + + def __init__(self): + self._head: Optional[Node] = None + self._tail: Optional[Node] = None + + def enqueue(self, value: str): + new_node = Node(value) + if self._tail: + self._tail._next = new_node + else: + self._head = new_node + self._tail = new_node + + def dequeue(self) -> Optional[str]: + if self._head: + value = self._head.data + self._head = self._head._next + if not self._head: + self._tail = None + return value + + def __repr__(self) -> str: + values = [] + current = self._head + while current: + values.append(current.data) + current = current._next + return "->".join(value for value in values) + + +if __name__ == "__main__": + q = LinkedQueue() + for i in range(10): + q.enqueue(str(i)) + print(q) + + for _ in range(3): + q.dequeue() + print(q) + + q.enqueue("7") + q.enqueue("8") + print(q) From 2c1c926ed829c29e746a11b98db01fb559bdc5ea Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Fri, 12 Oct 2018 08:24:48 +0800 Subject: [PATCH 62/69] [notes][10_recursion] init. --- notes/10_recursion/readme.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 notes/10_recursion/readme.md diff --git a/notes/10_recursion/readme.md b/notes/10_recursion/readme.md new file mode 100644 index 00000000..100b9b86 --- /dev/null +++ b/notes/10_recursion/readme.md @@ -0,0 +1,7 @@ +# 递归 + +## 三个条件 + +* 可分解为子问题 +* 子问题与原问题解法一致,只有规模上的不同 +* 有终止条件 From b5d134703cd9dcfea95a50b9a6867a4ffc636f33 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Fri, 12 Oct 2018 08:31:43 +0800 Subject: [PATCH 63/69] [notes][10_recursion] done. --- notes/10_recursion/readme.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/notes/10_recursion/readme.md b/notes/10_recursion/readme.md index 100b9b86..29478b1c 100644 --- a/notes/10_recursion/readme.md +++ b/notes/10_recursion/readme.md @@ -5,3 +5,24 @@ * 可分解为子问题 * 子问题与原问题解法一致,只有规模上的不同 * 有终止条件 + +## 写递归代码 + +* 整理出递推公式 +* 确定好终止条件 +* 「翻译」成代码 + +关键: + +> 只要遇到递归,我们就把它抽象成一个递推公式,不用想一层层的调用关系,不要试图用人脑去分解每一个步骤。 + +## 警惕 + +* 堆栈溢出 <- 递归深度过大 +* 重复计算 <- 递归过程中的不同分支,重复计算相同子问题 + * 保存子问题结果(map/dict) +* 空间复杂度高 <- 递归函数调用带来的消耗 + +## 递归改写非递归 + +本质:人肉模拟函数调用堆栈。 From d45831418492267f750c25be334d2c263763d977 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Fri, 12 Oct 2018 08:56:57 +0800 Subject: [PATCH 64/69] [10_recursive] one_two_step, done. --- c-cpp/10_recursive/.gitkeep | 0 c-cpp/10_recursive/one_two_step.cc | 26 ++++++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 c-cpp/10_recursive/.gitkeep create mode 100644 c-cpp/10_recursive/one_two_step.cc diff --git a/c-cpp/10_recursive/.gitkeep b/c-cpp/10_recursive/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/c-cpp/10_recursive/one_two_step.cc b/c-cpp/10_recursive/one_two_step.cc new file mode 100644 index 00000000..561c32b0 --- /dev/null +++ b/c-cpp/10_recursive/one_two_step.cc @@ -0,0 +1,26 @@ +#include +#include + +class SolutionOFOneTwoStep { + private: + static std::unordered_map result_; + + public: + size_t operator()(size_t steps) { + if (result_.end() != result_.find(steps)) { + return result_[steps]; + } else { + size_t res = operator()(steps - 1) + operator()(steps - 2); + result_.insert({steps, res}); + return res; + } + } +}; + +std::unordered_map + SolutionOFOneTwoStep::result_ = {{1, 1}, {2, 2}}; + +int main() { + std::cout << SolutionOFOneTwoStep()(10) << std::endl; + return 0; +} From 07297f8fb4f47b9fd8eab1a9a7e6b899e765f57f Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Fri, 12 Oct 2018 09:00:30 +0800 Subject: [PATCH 65/69] [10_recursive] one_two_step, applying iterator. --- c-cpp/10_recursive/one_two_step.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/c-cpp/10_recursive/one_two_step.cc b/c-cpp/10_recursive/one_two_step.cc index 561c32b0..7ae239f2 100644 --- a/c-cpp/10_recursive/one_two_step.cc +++ b/c-cpp/10_recursive/one_two_step.cc @@ -7,8 +7,9 @@ class SolutionOFOneTwoStep { public: size_t operator()(size_t steps) { - if (result_.end() != result_.find(steps)) { - return result_[steps]; + auto iter = result_.find(steps); + if (result_.end() != iter) { // found. + return iter->second; } else { size_t res = operator()(steps - 1) + operator()(steps - 2); result_.insert({steps, res}); From 7d7933f198157659b0d333f015fdd42a8ce15784 Mon Sep 17 00:00:00 2001 From: huruidong <1390095912@qq.com> Date: Fri, 12 Oct 2018 15:04:32 +0800 Subject: [PATCH 66/69] =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E7=9A=84=E5=9B=9B?= =?UTF-8?q?=E5=88=99=E8=BF=90=E7=AE=97=20+-*/()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/Stack/Compute.php | 78 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 php/Stack/Compute.php diff --git a/php/Stack/Compute.php b/php/Stack/Compute.php new file mode 100644 index 00000000..3e5624bd --- /dev/null +++ b/php/Stack/Compute.php @@ -0,0 +1,78 @@ += 48 && ord($arr[$i] <= 57)){ + array_push($numStack, $arr[$i]); + continue; + } + switch ($arr[$i]){ + case '+': + case '-': + $arrLen = count($operStack); + while ($operStack[$arrLen-1] === '*' || $operStack[$arrLen-1] === '/' || $operStack[$arrLen-1] === '-'){ + compute($numStack, $operStack); + $arrLen--; + } + array_push($operStack, $arr[$i]); + break; + case '*': + case '/': + case '(': + array_push($operStack, $arr[$i]); + break; + case ')': + $arrLen = count($operStack); + while ($operStack[$arrLen-1] !== '('){ + compute($numStack, $operStack); + $arrLen--; + } + array_pop($operStack); + break; + default: + throw new \Exception("不支持的运算符", 1); + break; + } + } + + $arrLen = count($operStack); + while ($operStack[$arrLen-1] !== NULL){ + compute($numStack, $operStack); + $arrLen--; + } + echo array_pop($numStack); +} + +//数字栈长度减一,运算符栈长度减一 +function compute(&$numStack, &$operStack){ + $num = array_pop($numStack); + switch (array_pop($operStack)) { + case '*': + array_push($numStack, array_pop($numStack) * $num); + break; + case '/': + array_push($numStack, array_pop($numStack) / $num); + break; + case '+': + array_push($numStack, array_pop($numStack) + $num); + break; + case '-': + array_push($numStack, array_pop($numStack) - $num); + break; + + } +} +expression('-1+2-(1+2*3)'); +echo PHP_EOL; +eval('echo -1+2-(1+2*3);'); \ No newline at end of file From 5a374e03f5be2f4b0d27613705b6e4046b615363 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Fri, 12 Oct 2018 17:46:51 +0800 Subject: [PATCH 67/69] [10_recursive] one_two_step, nonrecursive version, done. --- c-cpp/10_recursive/one_two_step.cc | 52 +++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/c-cpp/10_recursive/one_two_step.cc b/c-cpp/10_recursive/one_two_step.cc index 7ae239f2..11159c7f 100644 --- a/c-cpp/10_recursive/one_two_step.cc +++ b/c-cpp/10_recursive/one_two_step.cc @@ -6,7 +6,13 @@ class SolutionOFOneTwoStep { static std::unordered_map result_; public: - size_t operator()(size_t steps) { + enum class POLICY { + RECURSIVE, + NONRECURSIVE + }; + + private: + size_t recursive(size_t steps) { auto iter = result_.find(steps); if (result_.end() != iter) { // found. return iter->second; @@ -16,12 +22,50 @@ class SolutionOFOneTwoStep { return res; } } + size_t nonrecursive(size_t steps) { + auto iter = result_.find(steps); + if (result_.end() != iter) { // found. + return iter->second; + } else { + size_t start; + for (start = steps; start != 2 and result_.end() == result_.find(start); --start) {} + for (size_t i = start; i != steps; ++i) { + result_.insert({i + 1, result_[i - 1] + result_[i]}); + } + return result_[steps]; + } + } + + public: + size_t operator()(size_t steps, const POLICY policy = POLICY::RECURSIVE) { + if (policy == POLICY::RECURSIVE) { + return recursive(steps); + } else if (policy == POLICY::NONRECURSIVE) { + return nonrecursive(steps); + } + } + static void debug() { + for (auto kv : result_) { + std::cout << kv.first << ' ' << kv.second << std::endl; + } + std::cout << std::endl; + } }; -std::unordered_map - SolutionOFOneTwoStep::result_ = {{1, 1}, {2, 2}}; +std::unordered_map SolutionOFOneTwoStep::result_ = {{1, 1}, {2, 2}}; int main() { - std::cout << SolutionOFOneTwoStep()(10) << std::endl; + SolutionOFOneTwoStep::debug(); + + std::cout << SolutionOFOneTwoStep()(5, SolutionOFOneTwoStep::POLICY::RECURSIVE) << std::endl; + SolutionOFOneTwoStep::debug(); + + std::cout << SolutionOFOneTwoStep()(10, SolutionOFOneTwoStep::POLICY::NONRECURSIVE) << std::endl; + SolutionOFOneTwoStep::debug(); + + std::cout << SolutionOFOneTwoStep()(20, SolutionOFOneTwoStep::POLICY::RECURSIVE) << std::endl; + SolutionOFOneTwoStep::debug(); + return 0; } + From dccc9749a31d6846b670365bb85164959f2be4be Mon Sep 17 00:00:00 2001 From: wangzheng0822 Date: Fri, 12 Oct 2018 17:59:27 +0800 Subject: [PATCH 68/69] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index a915e840..d4f39b23 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,5 @@ # 数据结构和算法之美 # 请点击查看:[https://time.geekbang.org/column/intro/126](https://time.geekbang.org/column/intro/126) + +# Java rate limiting library/framework +# https://github.com/wangzheng0822/ratelimiter4j From 91d126d960d741388cc507cb2dca633f4138588b Mon Sep 17 00:00:00 2001 From: wangzheng0822 Date: Fri, 12 Oct 2018 18:00:12 +0800 Subject: [PATCH 69/69] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d4f39b23..01789399 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # 数据结构和算法之美 -# 请点击查看:[https://time.geekbang.org/column/intro/126](https://time.geekbang.org/column/intro/126) +# [https://time.geekbang.org/column/intro/126](https://time.geekbang.org/column/intro/126) # Java rate limiting library/framework # https://github.com/wangzheng0822/ratelimiter4j