From dfc81c7e1369e530775b742ea379614088edc587 Mon Sep 17 00:00:00 2001 From: Didnelpsun <2675350965@qq.com> Date: Sat, 18 Sep 2021 23:58:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=98=9F=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 7 +- Code/CPP-Code/head/link_queue.h | 162 ++++++++++++++++++++++++++++ Code/CPP-Code/head/link_stack.h | 16 +-- Code/CPP-Code/head/sequence_stack.h | 4 +- Code/Code/head/link_list.h | 28 ++--- Code/Code/head/link_queue.h | 55 +++++++++- Code/Code/head/sequence_list.h | 13 +-- Code/Code/head/sequence_queue.h | 4 +- Code/Code/head/share_stack.h | 8 +- Code/Code/source/test.cpp | 11 +- Data-Structrue/2-stack.md | 12 +-- Data-Structrue/3-queue-ex.md | 23 ++++ Data-Structrue/3-queue.md | 7 +- 13 files changed, 299 insertions(+), 51 deletions(-) create mode 100644 Data-Structrue/3-queue-ex.md diff --git a/.gitignore b/.gitignore index 9963ab2..06c413c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,8 @@ *Debug/ *x64/ *out/ -*cmake-build-debug/ -*cmake-build-debug-mingw/ \ No newline at end of file +*cmake-build-debug +*cmake-build-debug-mingw +*cmake-build-debug-default +*cmake-build-debug-wsl +*/CMakeFiles \ No newline at end of file diff --git a/Code/CPP-Code/head/link_queue.h b/Code/CPP-Code/head/link_queue.h index 44ba00d..1d9948a 100644 --- a/Code/CPP-Code/head/link_queue.h +++ b/Code/CPP-Code/head/link_queue.h @@ -1,4 +1,166 @@ #include #include "head.h" +// 链队结点 +class LinkQueueNode { +private: + // 数据 + element_type _data; + // 指针 + LinkQueueNode *_next; +public: + // 设置数据 + bool SetData(element_type elem); + + // 获取数据 + element_type GetData() const; + + // 设置指针 + bool SetNext(LinkQueueNode *next); + + // 获取指针 + LinkQueueNode *GetNext(); + + // 构造函数 + LinkQueueNode() { + this->SetData(DEFAULTELEM); + this->SetNext(nullptr); + } + + LinkQueueNode(element_type elem) { + this->SetData(elem); + this->SetNext(nullptr); + } + + LinkQueueNode(element_type elem, LinkQueueNode *next) { + this->SetData(elem); + this->SetNext(next); + } +}; + +bool LinkQueueNode::SetData(element_type elem) { + this->_data = elem; + return true; +} + +element_type LinkQueueNode::GetData() const { + return this->_data; +} + +bool LinkQueueNode::SetNext(LinkQueueNode *next) { + this->_next = next; + return true; +} + +LinkQueueNode *LinkQueueNode::GetNext() { + return this->_next; +} + // 链队 +class LinkQueue { +private: + // 队头指针和队尾指针 + LinkQueueNode *_front{}, *_rear{}; + // 长度 + int _length{}; +public: + // 设置队首指针 + bool SetFront(LinkQueueNode *front); + + // 获取对首指针 + LinkQueueNode *GetFront(); + + // 设置队尾指针 + bool SetRear(LinkQueueNode *rear); + + // 获取队尾指针 + LinkQueueNode *GetRear(); + + // 队长自加 + bool SetLength(); + + // 设置队长 + bool SetLength(int length); + + // 获取队长 + int GetLength() const; + + // 构造函数 + LinkQueue(); + + // 判空 + bool Empty() const; + + // 入队 + bool Enter(element_type elem); + + // 出队 + element_type Depart(); +}; + +bool LinkQueue::SetFront(LinkQueueNode *front) { + this->_front = front; + return true; +} + +LinkQueueNode *LinkQueue::GetFront() { + return this->_front; +} + +bool LinkQueue::SetRear(LinkQueueNode *rear) { + this->_rear = rear; + return true; +} + +LinkQueueNode *LinkQueue::GetRear() { + return this->_rear; +} + +bool LinkQueue::SetLength() { + this->_length++; + return true; +} + +bool LinkQueue::SetLength(int length) { + this->_length = length; + return true; +} + +int LinkQueue::GetLength() const { + return this->_length; +} + +LinkQueue::LinkQueue() { + auto *node = new LinkQueueNode(); + this->SetFront(node); + this->SetRear(node); + this->SetLength(0); +} + +bool LinkQueue::Empty() const { + return this->GetLength() == 0; +} + +bool LinkQueue::Enter(element_type elem) { + // 创建新结点 + auto *node = new LinkQueueNode(elem); + // 把最后一个元素的next连接到node + this->GetRear()->SetNext(node); + // 移动尾指针 + this->SetRear(node); + return true; +} + +element_type LinkQueue::Depart() { + if(this->Empty()){ + cout << "Depart:The queue is empty!" << endl; + return DEFAULTELEM; + } + // 获取对首元素下一个元素的数据 + element_type elem = this->GetFront()->GetNext()->GetData(); + // 后移移位 + this->GetFront()->SetNext(this->GetFront()->GetNext()->GetNext()); + return true; +} + + diff --git a/Code/CPP-Code/head/link_stack.h b/Code/CPP-Code/head/link_stack.h index aee4b72..a2b2fe0 100644 --- a/Code/CPP-Code/head/link_stack.h +++ b/Code/CPP-Code/head/link_stack.h @@ -3,13 +3,13 @@ using namespace std; // 链栈 -class LinkStackNode{ +class LinkStackNode { private: // 数据 element_type _data{}; // 指针 - LinkStackNode* _next{}; -public: + LinkStackNode *_next{}; + // 设置数据 bool SetData(element_type data); @@ -17,17 +17,19 @@ public: element_type GetData() const; // 设置指针 - bool SetNext(LinkStackNode* next); + bool SetNext(LinkStackNode *next); // 获取指针 - LinkStackNode* GetNext(); + LinkStackNode *GetNext(); + +public: // 构造函数 LinkStackNode(); explicit LinkStackNode(element_type data); - LinkStackNode(element_type data, LinkStackNode* next); + LinkStackNode(element_type data, LinkStackNode *next); // 销毁 bool Destroy(); @@ -68,7 +70,7 @@ LinkStackNode::LinkStackNode(element_type data, LinkStackNode *next) { bool LinkStackNode::Destroy() { this->SetData(DEFAULTELEM); - delete(this->GetNext()); + delete (this->GetNext()); this->SetNext(nullptr); return true; } diff --git a/Code/CPP-Code/head/sequence_stack.h b/Code/CPP-Code/head/sequence_stack.h index e98af08..56b9feb 100644 --- a/Code/CPP-Code/head/sequence_stack.h +++ b/Code/CPP-Code/head/sequence_stack.h @@ -11,7 +11,7 @@ private: int _top{}; // 最大容量 int _max_size{}; -public: + // 设置数据 bool SetData(element_type *data); @@ -27,6 +27,8 @@ public: // 设置最大容量 bool SetMaxSize(int max_size); +public: + // 获取最大容量 int GetMaxSize() const; diff --git a/Code/Code/head/link_list.h b/Code/Code/head/link_list.h index b0b746c..0f05d34 100644 --- a/Code/Code/head/link_list.h +++ b/Code/Code/head/link_list.h @@ -183,10 +183,10 @@ bool PriorInsertLinkList(LinkList &list, element_type *elem, int start, int leng // ɾ element_type *DeleteLinkListWithHead(LinkList &list, int index, int length) { - auto *data = (element_type *) malloc(length * sizeof(element_type)); + auto *elem = (element_type *) malloc(length * sizeof(element_type)); if (index < 1) { printf("DeleteLinkListWithHead:ɾֵ%dС\n", index); - return data; + return elem; } if (length < 1) { printf("DeleteLinkListWithHead:ɾ%dС\n", length); @@ -202,7 +202,7 @@ element_type *DeleteLinkListWithHead(LinkList &list, int index, int length) { // ûκ if (start == nullptr) { printf("DeleteLinkListWithHead:Ϊգ\n"); - return data; + return elem; } // ѭָŵĵĽ // ǵǰһΪŵĽһǿս @@ -213,16 +213,16 @@ element_type *DeleteLinkListWithHead(LinkList &list, int index, int length) { // ʱiСindex-1ʾ껹ûеӦ if (i < index - 1) { printf("DeleteLinkListWithHead:ɾֵ%d\n", index); - return data; + return elem; } // ʱi==index-1startend end = start; for (int i = 0; i < length; i++) { - data[i] = end->data; + elem[i] = end->data; end = end->next; if (end == nullptr) { printf("DeleteLinkListWithHead:ɾֵ%d%d\n", index + length - 1, length - 1); - return data; + return elem; } } if (index == 1) { @@ -230,14 +230,14 @@ element_type *DeleteLinkListWithHead(LinkList &list, int index, int length) { } else { start->next = end->next; } - return data; + return elem; } element_type *DeleteLinkListWithoutHead(LinkList &list, int index, int length) { - auto *data = (element_type *) malloc(length * sizeof(element_type)); + auto *elem = (element_type *) malloc(length * sizeof(element_type)); if (index < 0) { printf("DeleteLinkListWithoutHead:ɾֵС\n"); - return data; + return elem; } if (length < 1) { printf("DeleteLinkListWithoutHead:ɾ%dС\n", length); @@ -253,7 +253,7 @@ element_type *DeleteLinkListWithoutHead(LinkList &list, int index, int length) { // ûκ if (EmptyLinkList(list)) { printf("DeleteLinkListWithoutHead:Ϊգ\n"); - return data; + return elem; } // ѭָŵĵĽ // ǵǰһΪŵĽһǿս @@ -264,16 +264,16 @@ element_type *DeleteLinkListWithoutHead(LinkList &list, int index, int length) { // ʱiСindex-1ʾ껹ûеӦ if (i < index - 1) { printf("DeleteLinkListWithoutHead:ɾֵ%d\n", index); - return data; + return elem; } // λ end = start; for (int i = 0; i < length; i++) { end = end->next; - data[i] = end->data; + elem[i] = end->data; if (end->next == nullptr) { printf("DeleteLinkListWithoutHead:ɾֵ%d%d\n", index + length - 1, length - 1); - return data; + return elem; } } // ɾһ0Ž @@ -282,7 +282,7 @@ element_type *DeleteLinkListWithoutHead(LinkList &list, int index, int length) { start->next = end->next->next; } start->next = end->next; - return data; + return elem; } // diff --git a/Code/Code/head/link_queue.h b/Code/Code/head/link_queue.h index c03aea7..7529eb5 100644 --- a/Code/Code/head/link_queue.h +++ b/Code/Code/head/link_queue.h @@ -3,7 +3,7 @@ // 链队结点 typedef struct LinkQueueNode { // 数据 - element_type* data; + element_type data; // 指针 struct LinkQueueNode *next; } LinkQueueNode; @@ -12,4 +12,55 @@ typedef struct LinkQueueNode { typedef struct { // 队头指针和队尾指针 LinkQueueNode *front, *rear; -} LinkQueue; \ No newline at end of file +} LinkQueue; + +// 初始化 +bool InitLinkQueue(LinkQueue &queue){ + // 建立头节点 + queue.front = queue.rear = (LinkQueueNode*) malloc(sizeof(LinkQueueNode)); + // 初始为空 + queue.front->next = nullptr; + queue.front->data = DEFAULTELEM; + return true; +} + +LinkQueue InitLinkQueue(){ + auto* queue = (LinkQueue*) malloc(sizeof(LinkQueue)); + queue->front = queue->rear = (LinkQueueNode*) malloc(sizeof(LinkQueueNode)); + // 初始为空 + queue->front->next = nullptr; + queue->front->data = DEFAULTELEM; + return (LinkQueue &) queue; +} + +// 判空 +bool EmptyLinkQueue(LinkQueue queue){ + return queue.front==queue.rear; +} + +// 入队 +bool EnterLinkQueue(LinkQueue &queue, element_type elem){ + // 创建新结点 + auto *node = (LinkQueueNode *) malloc(sizeof(LinkQueueNode)); + node->data = elem; + node->next = nullptr; + // 把最后一个元素的next连接到node + queue.rear->next = node; + // 移动尾指针 + queue.rear = node; + return true; +} + +// 出队 +element_type DepartLinkQueue(LinkQueue &queue){ + if(EmptyLinkQueue(queue)){ + printf("DepartLinkQueue:The queue is empty!"); + return false; + } + // 获取对首元素下一个元素的数据 + element_type elem = queue.front->next->data; + // 后移移位 + queue.front->next=queue.front->next->next; + // 若队列空 + return true; +} \ No newline at end of file diff --git a/Code/Code/head/sequence_list.h b/Code/Code/head/sequence_list.h index 2e2a8c6..f85def7 100644 --- a/Code/Code/head/sequence_list.h +++ b/Code/Code/head/sequence_list.h @@ -158,26 +158,27 @@ bool LoopInsertSequenceList(List &list, element_type *elem, int start, int end) // ɾ template -bool DeleteSequenceList(List &list, int index, element_type &elem) { +element_type DeleteSequenceList(List &list, int index) { if (index >= list.length || index < 0) { printf("DeleteStaticSequenceList:ɾΧ\n"); return false; } - elem = list.data[index]; + element_type elem = list.data[index]; for (int i = index; i < list.length; i++) { list.data[i] = list.data[i + 1]; } list.length--; - return true; + return elem; } // ɾԪ template -int MultiDeleteSequenceList(List &list, int index, int length, element_type *elem) { +element_type* MultiDeleteSequenceList(List &list, int index, int length) { if (index + length >= list.length || index < 0) { printf("MultiDeleteSequenceList:ɾΧ\n"); - return 1; + return nullptr; } + auto elem = new element_type[length]; for (int i = index; i < list.length - length; i++) { if (i < index + length) { elem[i - index] = list.data[i]; @@ -185,7 +186,7 @@ int MultiDeleteSequenceList(List &list, int index, int length, element_type *ele list.data[i] = list.data[i + length]; } list.length -= length; - return 0; + return elem; } // λ˳Ԫ diff --git a/Code/Code/head/sequence_queue.h b/Code/Code/head/sequence_queue.h index 0efaa6b..83edab9 100644 --- a/Code/Code/head/sequence_queue.h +++ b/Code/Code/head/sequence_queue.h @@ -100,9 +100,9 @@ element_type DepartCircularDepartSequence(SequenceQueue &queue) { printf("DepartCircularDepartSequence:队空无法出队!\n"); return DEFAULTELEM; } - element_type temp = queue.data[queue.front]; + element_type elem = queue.data[queue.front]; queue.front = (queue.front + 1) % queue.max_size; - return temp; + return elem; } // 获取队长 diff --git a/Code/Code/head/share_stack.h b/Code/Code/head/share_stack.h index 6759b5c..ac46ae5 100644 --- a/Code/Code/head/share_stack.h +++ b/Code/Code/head/share_stack.h @@ -95,9 +95,9 @@ element_type PopLeftShareStack(ShareStack &stack){ printf("PopLeftShareStack:栈空无法出栈!\n"); return DEFAULTELEM; } - element_type temp = stack.data[stack.top_left]; + element_type elem = stack.data[stack.top_left]; stack.top_left--; - return temp; + return elem; } // 右出栈 @@ -106,9 +106,9 @@ element_type PopRightShareStack(ShareStack &stack){ printf("PopRightShareStack:栈空无法出栈!\n"); return DEFAULTELEM; } - element_type temp = stack.data[stack.top_right]; + element_type elem = stack.data[stack.top_right]; stack.top_left++; - return temp; + return elem; } // 读取左首部 diff --git a/Code/Code/source/test.cpp b/Code/Code/source/test.cpp index dcbbffb..b59c913 100644 --- a/Code/Code/source/test.cpp +++ b/Code/Code/source/test.cpp @@ -1,4 +1,4 @@ -// ļ +// ??????? #include #include "../head/sequence_list.h" #include "../head/link_list.h" @@ -21,8 +21,7 @@ bool SequenceListTest() { PrintSequenceList(list); printf("\n"); int len = 2; - element_type elem[2]; - MultiDeleteSequenceList(list, 0, len, elem); + element_type* elem = MultiDeleteSequenceList(list, 0, len); PrintSequenceList(list); for (int i = 0; i < len; i++) { printf("%c\n", elem[i]); @@ -45,9 +44,9 @@ bool LinkListTest() { element_type* data = DeleteLinkListWithoutHead(list, 2, length); PrintLinkList(list); for (int i = 0; i < length; i++) { - printf("%dΪ%c\n", i, data[i]); + printf("??%d?%c\n", i, data[i]); } - printf("Ϊ%d", GetLengthLinkList(list)); - printf("%cַ%d", '3', LocateLinkList(list, '3')); + printf("?????%d", GetLengthLinkList(list)); + printf("%c???%d", '3', LocateLinkList(list, '3')); return true; } \ No newline at end of file diff --git a/Data-Structrue/2-stack.md b/Data-Structrue/2-stack.md index 0f768c5..28c4fdd 100644 --- a/Data-Structrue/2-stack.md +++ b/Data-Structrue/2-stack.md @@ -46,13 +46,13 @@ 即需要括号成双相对,且大小一样。 -括号匹配时会发现最后出现的左括号最先被匹配LIFO。所以就可以通过栈来模拟这个匹配过程。 +括号匹配时会发现最后出现的左括号最先被匹配$LIFO$。所以就可以通过栈来模拟这个匹配过程。 自左至右扫描表达式,若遇左括号,则将左括号入栈,若遇右括号,则将其与栈顶的左括号进行匹配,若配对,则栈顶的左括号出栈,否则出现括号不匹配错误,如果需要匹配但是栈空说明有单独的左或右括号,也匹配失败。 ### 表达式求值 -一般使用的都是中缀表达式,例如:4+2×3-10÷5,按照运算法则,我们应当先算2×3然后算10÷5 ,再算加法,最后算减法。 +一般使用的都是中缀表达式,例如:$4+2\times3-10\div5$,按照运算法则,我们应当先算$2\times3$然后算$10\div5$ ,再算加法,最后算减法。 表达式分为三个部分:操作数、运算符、界限符。 @@ -68,7 +68,7 @@ 2. 选择下一个运算符,按照**左操作数 右操作数 运算符**的方式组合一个个新的操作数。 3. 如果还有运算符没有处理就重复步骤二。 -如A+B*(C-D)-E/F就是ABCD-*+EF/-和ABCD-\*EF/-+。中缀转后缀的结果可以有不同的结果。 +如$A+B*(C-D)-E/F$就是$ABCD-*+EF/-$和$ABCD-*EF/-+$。中缀转后缀的结果可以有不同的结果。 即使有不同的转换结果,但是如果我们要通过计算机实现这种转换算法,就必须保证算法的唯一性,所以规定后缀表达式中运算符的顺序就是中缀表达式中运算符生效的顺序,即结果是第一个而不是第二个。 @@ -86,7 +86,7 @@ 后缀表达式计算的程序实现: 1. 从左往右扫描下一个元素,直到处理所有元素。 -2. 若扫描到操作数则压入栈,并回到1,若扫描到运算符则执行3. +2. 若扫描到操作数则压入栈,并回到$1$,若扫描到运算符则执行$3$。 3. 扫描到运算符则弹出两个栈顶元素,执行相应操作,运算结果压入栈,回到步骤一。 4. 先出栈的是右操作数,后出栈的是左操作数。 @@ -117,9 +117,9 @@ ### 递归 -函数调用的特点:最后被调用的函数最先执行结束LIFO。 +函数调用的特点:最后被调用的函数最先执行结束$LIFO$。 -函数调用时需要一个栈存储:调用返回地址、实参、局部变量。 +函数调用时需要一个栈存储:调用返回地址、实参、局部变量。用栈来让递归算法转换为非递归算法。 递归可以将原始问题拆分为属性相同、规模较小的问题。但是如果太多层会造成栈溢出。 diff --git a/Data-Structrue/3-queue-ex.md b/Data-Structrue/3-queue-ex.md new file mode 100644 index 0000000..93736af --- /dev/null +++ b/Data-Structrue/3-queue-ex.md @@ -0,0 +1,23 @@ +# 队列习题 + +## 顺序队列 + +**例题** 火车车轨入口到出口之间有$n$条轨道,列车的行进方向均为从左至右,列车可驶入任意一条轨道且每条道路可以容纳任意多数量的列车。现有编号为$1\sim9$的$9$列列车,驶入的次序依次是$8,4,2,5,3,9,1,6,7$。若期望驶出的次序依次为$1\sim9$,则$n$至少是()。 + +解:这个题目是一个多队列问题。根据题意:入队顺序为$8,4,2,5,3,9,1,6,7$,出队顺序为$1\sim9$。入口和出口之间有多个队列($n$条轨道),且每个队列(轨道)可容纳多个元素(多列列车),为便于区分,队列用字母编号。分析如下:显然先入队的元素必须小于后入队的元素(否则,若$8$和$4$入同一队列,$8$在$4$前面,则出队时也只能$8$在$4$前面),这样$8$入队列$A$,$4$入队列$B$,$2$入队列$C$,$5$入队列$B$(按照前述原则“大的元素在小的元素后面”也可将$5$入队列$C$,但这时剩下的元素$3$就必须放入一个新的队列中,无法确保“至少”,所以要最接近的一个队列),$3$入队列$C$,$9$入队列$A$,这时共占了$3$个队列,后面还有元素$1$,直接再用一个新的队列$D$,$1$从队列$D$出队后,剩下的元素$6$和$7$或入队列$B$,或入队列$C$。综上,共占用了$4$个队列。 + +## 循环队列 + +**例题** 已知循环队列存储在一维数组$A [0\cdots n-1]$中,且队列非空时$front$和$rear$分别指向队头元素和队尾元素。若初始时队列为空,且要求第一个进入队列的元素存储在$A[0]$处,则初始时$front$和$rear$的值分别是()。 + +$A.0$,$0$ + +$B.0$,$n-1$ + +$C.n-1$,$0$ + +$D.n-1$,$n-1$ + +解:$B$。根据题意,第一个元素进入队列后存储在$A[0]$处,此时$front$和$rear$值都为$0$。入队时由于要执行$(rear+1)\%n$操作,所以若入队后指针指向$0$,则$rear$初值为$n-1$,而由于第一个元素在$A[0]$中,插入操作只改变$rear$指针,所以$front$为$0$不变。 + +【2016统考真题】 diff --git a/Data-Structrue/3-queue.md b/Data-Structrue/3-queue.md index 72d84c3..0452914 100644 --- a/Data-Structrue/3-queue.md +++ b/Data-Structrue/3-queue.md @@ -44,6 +44,11 @@ ## 队列应用 -+ 树的层次遍历。 +### 树的层次遍历 + +1. 根结点入队。 +2. 若队空(所有结点都已处理完毕),则结束遍历,否则重复三操作。 +3. 队列中第一个结点出队,并访问之。若其有左孩子,则将左孩子入队;若其有右孩子,则将右孩子入队,返回二。 + + 图的广度优先遍历。 + 进程争用$FCFS$策略。