diff --git a/Code/CPP-Code/head/double_link_list.h b/Code/CPP-Code/head/double_link_list.h index b6f0957..ac69e24 100644 --- a/Code/CPP-Code/head/double_link_list.h +++ b/Code/CPP-Code/head/double_link_list.h @@ -8,7 +8,7 @@ private: // 数据 element_type _data{}; // 指针 - DoubleLinkListNode *_prior, *_next{}; + DoubleLinkListNode *_prior{}, *_next{}; public: // 设置数据 bool SetData(element_type elem); @@ -17,10 +17,10 @@ public: element_type GetData() const; // 设置prior - bool SetPrior(DoubleLinkListNode *prior) + bool SetPrior(DoubleLinkListNode *prior); // 获取prior - DoubleLinkList *GetPrior(); + DoubleLinkListNode *GetPrior(); // 设置next bool SetNext(DoubleLinkListNode *next); @@ -35,37 +35,37 @@ public: DoubleLinkListNode(element_type elem, DoubleLinkListNode *next); - DoubleLinkListNode(element_type elem, DoubleLinkListNode *prior, DoubleLinkListNode *next) + DoubleLinkListNode(element_type elem, DoubleLinkListNode *prior, DoubleLinkListNode *next); // 销毁 bool Destory(); }; bool DoubleLinkListNode::SetData(element_type elem) { - this._data = elem; + this->_data = elem; return true; } element_type DoubleLinkListNode::GetData() const { - return this._data; + return this->_data; } bool DoubleLinkListNode::SetPrior(DoubleLinkListNode *prior) { - this._prior = prior; + this->_prior = prior; return true; } -DoubleLinkListNode *DoubleLinkListNode::GetPrior() const { - return this._prior; +DoubleLinkListNode *DoubleLinkListNode::GetPrior() { + return this->_prior; } bool DoubleLinkListNode::SetNext(DoubleLinkListNode *next) { - this._next=next; + this->_next=next; return true; } -DoubleLinkListNode *DoubleLinkListNode::GetNext() const { - return this._next; +DoubleLinkListNode *DoubleLinkListNode::GetNext() { + return this->_next; } DoubleLinkListNode::DoubleLinkListNode() { @@ -92,10 +92,11 @@ DoubleLinkListNode::DoubleLinkListNode(element_type elem, DoubleLinkListNode *pr this->SetData(elem); } -bool DoubleLinkListNode::Destroy{ - free(this.GetPrior()); - free(this.GetNext()); +bool DoubleLinkListNode::Destory() { + free(this->GetPrior()); + free(this->GetNext()); this->SetPrior(nullptr); this->SetNext(nullptr); this->SetData(NULL); -}; \ No newline at end of file + return true; +} \ No newline at end of file diff --git a/Code/CPP-Code/head/head.h b/Code/CPP-Code/head/head.h index cf10def..6ab723b 100644 --- a/Code/CPP-Code/head/head.h +++ b/Code/CPP-Code/head/head.h @@ -1,4 +1,4 @@ -// 初始化最大长度 +// 初始化最大长度 #define MAXSIZE 5 // 定义默认值 #define DEFAULTELEM '0' diff --git a/Code/CPP-Code/head/link_list.h b/Code/CPP-Code/head/link_list.h index 38dda47..9de23c0 100644 --- a/Code/CPP-Code/head/link_list.h +++ b/Code/CPP-Code/head/link_list.h @@ -1,7 +1,9 @@ -#include +#include #include #include "head.h" +using namespace std; + // 单链表结点 class LinkListNode { private: @@ -33,6 +35,48 @@ public: bool Destory(); }; +bool LinkListNode::SetData(element_type elem) { + this->_data = elem; + return true; +} + +element_type LinkListNode::GetData() const { + return this->_data; +} + +bool LinkListNode::SetNext(LinkListNode *next) { + this->_next = next; + return true; +} + +LinkListNode *LinkListNode::GetNext() { + return this->_next; +} + +LinkListNode::LinkListNode() { + this->SetData(NULL); + this->SetNext(nullptr); +} + +LinkListNode::LinkListNode(element_type elem) { + this->SetData(elem); + this->SetNext(nullptr); +} + +LinkListNode::LinkListNode(element_type elem, LinkListNode *next) { + this->SetData(elem); + this->SetNext(next); +} + +bool LinkListNode::Destory() { + if (this->GetNext() != nullptr) { + free(this->GetNext()); + } + this->SetData(NULL); + this->SetNext(nullptr); + return true; +} + class LinkList { private: // 指针 @@ -97,96 +141,6 @@ public: virtual bool Destroy(); }; -class LinkListWithHead : public LinkList { -public: - // 构造函数 - LinkListWithHead(); - - // 打印 - bool Print() override; - - // 插入 - bool Insert(int index, element_type elem) override; - - // 删除 - element_type *Delete(int index, int length) override; -}; - -class LinkListWithoutHead : public LinkList { -private: - // 数据 - element_type _data{}; -public: - // 设置数据 - bool SetData(element_type elem); - - // 获取数据 - element_type GetData() const; - - // 构造函数 - LinkListWithoutHead(); - - // 打印 - bool Print() override; - - // 插入 - bool Insert(int index, element_type elem) override; - - // 删除 - element_type *Delete(int index, int length) override; - - // 按位查找 - element_type GetElem(int index) override; - - // 按值查找 - int Locate(element_type elem) override; - - // 销毁 - bool Destroy() override; -}; - -bool LinkListNode::SetData(element_type elem) { - this->_data = elem; - return true; -} - -element_type LinkListNode::GetData() const { - return this->_data; -} - -bool LinkListNode::SetNext(LinkListNode *next) { - this->_next = next; - return true; -} - -LinkListNode *LinkListNode::GetNext() { - return this->_next; -} - -LinkListNode::LinkListNode() { - this->SetData(NULL); - this->SetNext(nullptr); -} - -LinkListNode::LinkListNode(element_type elem) { - this->SetData(elem); - this->SetNext(nullptr); -} - -LinkListNode::LinkListNode(element_type elem, LinkListNode *next) { - this->SetData(elem); - this->SetNext(next); -} - -bool LinkListNode::Destory() { - if (this->GetNext() != nullptr) { - free(this->GetNext()); - } - this->SetData(NULL); - this->SetNext(nullptr); - return true; -} - bool LinkList::SetNext(LinkListNode *next) { this->_next = next; return true; @@ -227,7 +181,7 @@ LinkList::LinkList() { element_type LinkList::GetElem(int index) { if (index >= this->GetLength() || index < 0) { cout << "GetElem:查找索引" << index << "超过索引范围!" << endl; - return DEFAULTELEM; + return NULL; } LinkListNode *node = this->GetNext(); for (int i = 1; i < index; i++) { @@ -247,31 +201,84 @@ int LinkList::Locate(element_type elem) { return -1; } -LinkListWithHead::LinkListWithHead() { - this->SetType(true); -}; +bool LinkList::Empty() const { + return this->GetLength() == 0; +} -bool LinkListWithoutHead::SetData(element_type elem) { - this->_data = elem; +bool LinkList::PriorInsert(element_type *elem, int start, int length) { + if (this->GetType()) { + for (int i = 0; i < length; i++) { + bool result = this->Insert(1, elem[i + start]); + if (!result) { + cout << "PriorInsert:循环插入失败!索引值为" << i + start << endl; + return false; + } + } + return true; + } else { + for (int i = 0; i < length; i++) { + bool result = this->Insert(0, elem[i + start]); + if (!result) { + cout << "PriorInsert:循环插入失败!索引值为" << i + start << endl; + return false; + } + } + return true; + } +} + +bool LinkList::NextInsert(element_type *elem, int start, int length) { + if (this->GetType()) { + for (int i = 0; i < length; i++) { + bool result = this->Insert(i + 1, elem[i + start]); + if (!result) { + cout << "NextInsert:循环插入失败!索引值为" << i + start << endl; + return false; + } + } + return true; + } else { + for (int i = 0; i < length; i++) { + bool result = this->Insert(i, elem[i + start]); + if (!result) { + cout << "NextInsert:循环插入失败!索引值为" << i + start << endl; + return false; + } + } + return true; + } +} + +element_type LinkList::Delete(int index) { + return *(this->Delete(index, 1)); +} + +bool LinkList::Destroy() { + this->SetLength(0); + free(this->GetNext()); + this->SetNext(nullptr); + this->SetType(NULL); return true; } -element_type LinkListWithoutHead::GetData() const { - return this->_data; -} +class LinkListWithHead : public LinkList { +public: + // 构造函数 + LinkListWithHead(); -LinkListWithoutHead::LinkListWithoutHead() { - this->SetType(false); - this->SetData(NULL); -} + // 打印 + bool Print() override; -bool LinkList::Empty() const { - if (this->GetLength() == 0) { - return true; - } else { - return false; - } -} + // 插入 + bool Insert(int index, element_type elem) override; + + // 删除 + element_type *Delete(int index, int length) override; +}; + +LinkListWithHead::LinkListWithHead() { + this->SetType(true); +}; bool LinkListWithHead::Print() { int i = 1; @@ -289,22 +296,6 @@ bool LinkListWithHead::Print() { return true; } -bool LinkListWithoutHead::Print() { - int i = 0; - if (this->GetLength() == 0) { - return true; - } - cout << "第" << i << "个元素值为" << this->GetData() << endl; - // 当前遍历指针 - LinkListNode *node = this->GetNext(); - while (node != nullptr) { - i++; - cout << "第" << i << "个元素值为" << node->GetData() << endl; - node = node->GetNext(); - } - return true; -} - bool LinkListWithHead::Insert(int index, element_type elem) { if (index < 1) { cout << "Insert:插入索引值" << index << "过小!" << endl; @@ -350,6 +341,122 @@ bool LinkListWithHead::Insert(int index, element_type elem) { return true; } +element_type *LinkListWithHead::Delete(int index, int length) { + auto *data = new element_type[length]; + if (index < 1) { + cout << "Delete:删除索引值" << index << "过小!" << endl; + return data; + } + if (length < 1) { + cout << "Delete:删除长度" << length << "过小!" << endl; + return data; + } + // 定义一个结点指针start指向当前扫描到的结点,即要删除第一的元素的前一个 + LinkListNode *start; + // 定义一个结点指针start指向当前扫描到的结点,要删除最后的元素 + LinkListNode *end; + // 定义一个变量i表示当前扫描到的结点的索引号 + int i = 1; + // 将链表头结点的next指向start,为第1个结点 + start = this->GetNext(); + // 如果链表没有任何数据 + if (start == nullptr) { + cout << "Delete:链表为空!" << endl; + return data; + } + // 循环遍历到达指定索引号的单链表的结点 + // 条件是当前结点的下一个不为空且索引号到达,所到达的结点一定不是空结点 + while (start->GetNext() != nullptr && i < index - 1) { + start = start->GetNext(); + i++; + } + // 如果此时i小于index-1,表示遍历完还没有到达对应的索引 + if (i < index - 1) { + cout << "Delete:删除索引值" << index << "过大!" << endl; + return data; + } + // 此时i==index-1,start到达,求end + end = start; + for (int i = 0; i < length; i++) { + data[i] = end->GetData(); + end = end->GetNext(); + if (end == nullptr) { + cout << "Delete:删除索引最大值" << index + length - 1 << "大于链表最大索引" << length - 1 << "!" << endl; + return data; + } + } + if (index == 1) { + this->SetNext(end); + } else { + start->SetNext(end->GetNext()); + } + this->SetLength(this->GetLength() - length); + return data; +} + +class LinkListWithoutHead : public LinkList { +private: + // 数据 + element_type _data{}; +public: + // 设置数据 + bool SetData(element_type elem); + + // 获取数据 + element_type GetData() const; + + // 构造函数 + LinkListWithoutHead(); + + // 打印 + bool Print() override; + + // 插入 + bool Insert(int index, element_type elem) override; + + // 删除 + element_type *Delete(int index, int length) override; + + // 按位查找 + element_type GetElem(int index) override; + + // 按值查找 + int Locate(element_type elem) override; + + // 销毁 + bool Destroy() override; +}; + +bool LinkListWithoutHead::SetData(element_type elem) { + this->_data = elem; + return true; +} + +element_type LinkListWithoutHead::GetData() const { + return this->_data; +} + +LinkListWithoutHead::LinkListWithoutHead() { + this->SetType(false); + this->SetData(NULL); +} + +bool LinkListWithoutHead::Print() { + int i = 0; + if (this->GetLength() == 0) { + return true; + } + cout << "第" << i << "个元素值为" << this->GetData() << endl; + // 当前遍历指针 + LinkListNode *node = this->GetNext(); + while (node != nullptr) { + i++; + cout << "第" << i << "个元素值为" << node->GetData() << endl; + node = node->GetNext(); + } + return true; +} + bool LinkListWithoutHead::Insert(int index, element_type elem) { if (index < 0) { cout << "Insert:插入索引值" << index << "过小!" << endl; @@ -401,109 +508,8 @@ bool LinkListWithoutHead::Insert(int index, element_type elem) { return true; } -bool LinkList::PriorInsert(element_type *elem, int start, int length) { - if (this->GetType()) { - for (int i = 0; i < length; i++) { - bool result = this->Insert(1, elem[i + start]); - if (!result) { - cout << "PriorInsert:循环插入失败!索引值为" << i + start << endl; - return false; - } - } - return true; - } else { - for (int i = 0; i < length; i++) { - bool result = this->Insert(0, elem[i + start]); - if (!result) { - cout << "PriorInsert:循环插入失败!索引值为" << i + start << endl; - return false; - } - } - return true; - } -} - -bool LinkList::NextInsert(element_type *elem, int start, int length) { - if (this->GetType()) { - for (int i = 0; i < length; i++) { - bool result = this->Insert(i + 1, elem[i + start]); - if (!result) { - cout << "NextInsert:循环插入失败!索引值为" << i + start << endl; - return false; - } - } - return true; - } else { - for (int i = 0; i < length; i++) { - bool result = this->Insert(i, elem[i + start]); - if (!result) { - cout << "NextInsert:循环插入失败!索引值为" << i + start << endl; - return false; - } - } - return true; - } -} - -element_type LinkList::Delete(int index) { - return *(this->Delete(index, 1)); -} - -element_type *LinkListWithHead::Delete(int index, int length) { - auto *data = (element_type *) malloc(length * sizeof(element_type)); - if (index < 1) { - cout << "Delete:删除索引值" << index << "过小!" << endl; - return data; - } - if (length < 1) { - cout << "Delete:删除长度" << length << "过小!" << endl; - return data; - } - // 定义一个结点指针start指向当前扫描到的结点,即要删除第一的元素的前一个 - LinkListNode *start; - // 定义一个结点指针start指向当前扫描到的结点,要删除最后的元素 - LinkListNode *end; - // 定义一个变量i表示当前扫描到的结点的索引号 - int i = 1; - // 将链表头结点的next指向start,为第1个结点 - start = this->GetNext(); - // 如果链表没有任何数据 - if (start == nullptr) { - cout << "Delete:链表为空!" << endl; - return data; - } - // 循环遍历到达指定索引号的单链表的结点 - // 条件是当前结点的下一个不为空且索引号到达,所到达的结点一定不是空结点 - while (start->GetNext() != nullptr && i < index - 1) { - start = start->GetNext(); - i++; - } - // 如果此时i小于index-1,表示遍历完还没有到达对应的索引 - if (i < index - 1) { - cout << "Delete:删除索引值" << index << "过大!" << endl; - return data; - } - // 此时i==index-1,start到达,求end - end = start; - for (int i = 0; i < length; i++) { - data[i] = end->GetData(); - end = end->GetNext(); - if (end == nullptr) { - cout << "Delete:删除索引最大值" << index + length - 1 << "大于链表最大索引" << length - 1 << "!" << endl; - return data; - } - } - if (index == 1) { - this->SetNext(end); - } else { - start->SetNext(end->GetNext()); - } - this->SetLength(this->GetLength() - length); - return data; -} - element_type *LinkListWithoutHead::Delete(int index, int length) { - auto *data = (element_type *) malloc(length * sizeof(element_type)); + auto *data = new element_type[length]; if (index < 0) { cout << "Delete:删除索引值" << index << "过小!" << endl; return data; @@ -563,27 +569,11 @@ element_type *LinkListWithoutHead::Delete(int index, int length) { } element_type LinkListWithoutHead::GetElem(int index) { - if (index == 0) { - return this->GetData(); - } else { - return LinkList::GetElem(index); - } + return index == 0 ? this->GetData() : LinkList::GetElem(index); } int LinkListWithoutHead::Locate(element_type elem) { - if (this->GetData() == elem) { - return 0; - } else { - return LinkList::Locate(elem); - } -} - -bool LinkList::Destroy() { - this->SetLength(0); - free(this->GetNext()); - this->SetNext(nullptr); - this->SetType(NULL); - return true; + return this->GetData() == elem ? 0 : LinkList::Locate(elem); } bool LinkListWithoutHead::Destroy() { diff --git a/Code/CPP-Code/head/link_stack.h b/Code/CPP-Code/head/link_stack.h new file mode 100644 index 0000000..12c1137 --- /dev/null +++ b/Code/CPP-Code/head/link_stack.h @@ -0,0 +1,76 @@ +#include +#include +#include "head.h" + +using namespace std; + +// 链栈 +class LinkStackNode{ +private: + // 数据 + element_type _data{}; + // 指针 + LinkStackNode* _next{}; +public: + // 设置数据 + bool SetData(element_type data); + + // 取数据 + element_type GetData(); + + // 设置指针 + bool SetNext(LinkStackNode* next); + + // 获取指针 + LinkStackNode* GetNext(); + + // 构造函数 + LinkStackNode(); + + explicit LinkStackNode(element_type data); + + LinkStackNode(element_type data, LinkStackNode* next); + + // 销毁 + bool Destroy(); +}; + +bool LinkStackNode::SetData(element_type data) { + this->_data = data; + return true; +} + +element_type LinkStackNode::GetData() { + return this->_data; +} + +bool LinkStackNode::SetNext(LinkStackNode *next) { + this->_next = next; + return true; +} + +LinkStackNode *LinkStackNode::GetNext() { + return this->_next; +} + +LinkStackNode::LinkStackNode() { + this->SetData(NULL); + this->SetNext(nullptr); +} + +LinkStackNode::LinkStackNode(element_type data) { + this->SetData(data); + this->SetNext(nullptr); +} + +LinkStackNode::LinkStackNode(element_type data, LinkStackNode *next) { + this->SetData(data); + this->SetNext(next); +} + +bool LinkStackNode::Destroy() { + this->SetData(NULL); + delete(this->GetNext()); + this->SetNext(nullptr); + return true; +} diff --git a/Code/CPP-Code/head/sequence_list.h b/Code/CPP-Code/head/sequence_list.h index a227bb7..409c54b 100644 --- a/Code/CPP-Code/head/sequence_list.h +++ b/Code/CPP-Code/head/sequence_list.h @@ -1,4 +1,4 @@ -#include +#include #include #include "head.h" @@ -16,71 +16,56 @@ private: int _length{}; public: // 设置数据 - bool SetData(element_type* elem); + bool SetData(element_type *elem); + bool SetData(int index, element_type elem); + // 获取数据 - element_type* GetData() const; + element_type *GetData() const; + element_type GetData(int index) const; + // 长度自加1 bool SetLength(); + // 设置长度 bool SetLength(int length); + // 设置长度 int GetLength() const; + // 构造函数 SequenceList(); + // 插入函数 virtual bool Insert(int index, element_type elem) = 0; + // 打印函数 bool Print() const; + // 循环插入函数 bool LoopInsert(element_type *elem, int index, int length); + // 删除函数 element_type Delete(int index); + // 多个删除函数 - element_type* LoopDelete(int index, int length); + element_type *LoopDelete(int index, int length); + // 按位获取元素 element_type GetElem(int index) const; + // 按值获取元素 int Locate(element_type elem) const; + // 判空 bool Empty() const; + // 销毁 bool Destroy() const; }; -// 静态顺序表 -class StaticSequenceList: public SequenceList{ -public: - // 构造函数 - StaticSequenceList(); - // 插入函数 - bool Insert(int index, element_type elem) override; -}; - -// 动态顺序表 -class DynamicSequenceList: public SequenceList{ -private: - // 已分配的最大容量 - int _max_size{}; -public: - // 设置最大容量 - bool SetMaxSize(int max_size); - // 获取最大容量 - int GetMaxSize() const; - // 构造函数 - DynamicSequenceList(); - // 插入函数 - bool Insert(int index, element_type elem) override; - -private: - // 分配其他地址增长动态顺序表的数据空间长度 - bool OtherIncrease(int len); - // 重新分配地址增长动态顺序表的数据空间长度 - bool ReIncrease(int len); -}; - -bool SequenceList::SetData(element_type* elem) { +bool SequenceList::SetData(element_type *elem) { this->_data = elem; return true; } @@ -99,7 +84,7 @@ element_type SequenceList::GetData(int index) const { } bool SequenceList::SetLength() { - this->_length ++; + this->_length++; return true; } @@ -116,33 +101,6 @@ SequenceList::SequenceList() { this->SetLength(0); } -StaticSequenceList::StaticSequenceList() : SequenceList() { - this->SetData((element_type*)malloc(MAXSIZE * sizeof(element_type))); -} - -bool DynamicSequenceList::SetMaxSize(int max_size) { - this->_max_size = max_size; - return true; -} - -int DynamicSequenceList::GetMaxSize() const { - return this->_max_size; -} - -DynamicSequenceList::DynamicSequenceList() : SequenceList() { - // 初初始化动态顺序表长度为0 - this->SetMaxSize(0); - // 申请一片连续的存储空间 - auto* space = (element_type*)malloc(MAXSIZE * sizeof(element_type)); - if (space) { - this->SetData(space); - this->SetMaxSize(MAXSIZE); - } - else { - cout << "InitSequenceList:分配空间失败!" << endl; - } -} - bool SequenceList::Print() const { for (int i = 0; i < this->GetLength(); i++) { cout << "第" << i + 1 << "个元素值为" << this->GetData(i) << endl; @@ -150,94 +108,6 @@ bool SequenceList::Print() const { return true; } -bool DynamicSequenceList::OtherIncrease(int len) { - if (len <= 0) { - cout << "OtherIncrease:申请空间应该大于0!" << endl; - return false; - } - // 申请一片连续的存储空间 - int new_length = this->GetMaxSize() + len; - auto* space = (element_type*)malloc(new_length * sizeof(element_type)); - if (space) { - // 建立中间变量 - this->SetData(space); - element_type* temp = this->GetData(); - for (int i = 0; i < this->GetLength(); i++) { - this->SetData(i, temp[i]); - } - this->SetMaxSize(new_length); - free(temp); - return true; - } - else { - cout << "OtherIncrease:重新分配空间失败!" << endl; - return false; - } -} - -bool DynamicSequenceList::ReIncrease(int length) { - if (length <= 0) { - cout << "ReIncrease:申请空间应该大于0!" << endl; - return false; - } - // 申请一片连续的存储空间 - int new_length = this->GetMaxSize() + length; - auto* space = (element_type*)realloc(this->GetData(), new_length * sizeof(element_type)); - if (space) { - this->SetData(space); - this->SetMaxSize(this->GetMaxSize()+length); - return true; - } - else { - this->SetMaxSize(0); - this->SetLength(0); - cout << "ReIncrease:分配其他地址空间失败!" << endl; - return false; - } -} - -bool StaticSequenceList::Insert(int index, element_type elem) { - // 当静态顺序表已经满了就不能插入任何元素 - if (this->GetLength() >= MAXSIZE) { - cout << "Insert:静态顺序表空间不足,插入失败!" << endl; - return false; - } - // 索引位置从0开始,所以可以插入的范围是0到list->length - if (index > this->GetLength() || index < 0) { - cout << "Insert:插入索引" << index << "超过索引范围!" << endl; - return false; - } - // 从最后一个元素开始交换后移,list->length是空的 - for (int i = this->GetLength(); i > index; i--) { - this->SetData(i, this->GetData(i-1)); - } - this->SetData(index, elem); - this->SetLength(); - return true; -} - -bool DynamicSequenceList::Insert(int index, element_type elem) { - if (index > this->GetLength() || index < 0) { - cout << "Insert:插入索引" << index << "超过索引范围!" << endl; - return false; - } - // 当动态顺序表已经满了,需要新增一个位置 - // 为了避免索引无效而多增加一个空间,所以放在检查索引值的后面 - if (this->GetLength() >= MAXSIZE) { - bool result = this->ReIncrease(1); - if (!result) { - cout << "Insert:申请空间失败!" << endl; - return false; - } - } - for (int i = this->GetLength(); i > index; i--) { - this->SetData(i, this->GetData(i-1)); - } - this->SetData(index, elem); - this->SetLength(); - return true; -} - bool SequenceList::LoopInsert(element_type *elem, int index, int length) { for (int i = 0; i < length; i++) { bool result = this->Insert(i, elem[i + index]); @@ -255,18 +125,18 @@ element_type SequenceList::Delete(int index) { return false; } for (int i = index; i < this->GetLength(); i++) { - this->SetData(i, this->GetData(i+1)); + this->SetData(i, this->GetData(i + 1)); } - this->SetLength(this->GetLength()-1); + this->SetLength(this->GetLength() - 1); return this->GetData(index); } -element_type* SequenceList::LoopDelete(int index, int length) { +element_type *SequenceList::LoopDelete(int index, int length) { if (index + length > this->GetLength() || index < 0) { cout << "LoopDelete:删除索引" << index + length << "超过索引范围!" << endl; return nullptr; } - auto* elem = (element_type*)malloc(length * sizeof(element_type)); + auto *elem = new element_type[length]; if (elem) { for (int i = index; i <= this->GetLength() - length; i++) { if (i < index + length) { @@ -275,8 +145,7 @@ element_type* SequenceList::LoopDelete(int index, int length) { this->SetData(i, this->GetData(i + length)); } this->SetLength(this->GetLength() - length); - } - else { + } else { cout << "LoopDelete:申请空间失败!" << endl; } return elem; @@ -285,7 +154,7 @@ element_type* SequenceList::LoopDelete(int index, int length) { element_type SequenceList::GetElem(int index) const { if (index >= this->GetLength() || index < 0) { cout << "GetElem:查找索引" << index << "超过索引范围!" << endl; - return DEFAULTELEM; + return NULL; } return this->GetData(index); } @@ -302,12 +171,7 @@ int SequenceList::Locate(element_type elem) const { } bool SequenceList::Empty() const { - if (this->GetLength() == 0) { - return false; - } - else { - return true; - } + return this->GetLength() == 0; } bool SequenceList::Destroy() const { @@ -317,3 +181,150 @@ bool SequenceList::Destroy() const { return true; } +// 静态顺序表 +class StaticSequenceList : public SequenceList { +public: + // 构造函数 + StaticSequenceList(); + + // 插入函数 + bool Insert(int index, element_type elem) override; +}; + +StaticSequenceList::StaticSequenceList() : SequenceList() { + this->SetData(new element_type[MAXSIZE]); +} + +bool StaticSequenceList::Insert(int index, element_type elem) { + // 当静态顺序表已经满了就不能插入任何元素 + if (this->GetLength() >= MAXSIZE) { + cout << "Insert:静态顺序表空间不足,插入失败!" << endl; + return false; + } + // 索引位置从0开始,所以可以插入的范围是0到list->length + if (index > this->GetLength() || index < 0) { + cout << "Insert:插入索引" << index << "超过索引范围!" << endl; + return false; + } + // 从最后一个元素开始交换后移,list->length是空的 + for (int i = this->GetLength(); i > index; i--) { + this->SetData(i, this->GetData(i - 1)); + } + this->SetData(index, elem); + this->SetLength(); + return true; +} + +// 动态顺序表 +class DynamicSequenceList : public SequenceList { +private: + // 已分配的最大容量 + int _max_size{}; +public: + // 设置最大容量 + bool SetMaxSize(int max_size); + + // 获取最大容量 + int GetMaxSize() const; + + // 构造函数 + DynamicSequenceList(); + + // 插入函数 + bool Insert(int index, element_type elem) override; + +private: + // 分配其他地址增长动态顺序表的数据空间长度 + bool OtherIncrease(int len); + + // 重新分配地址增长动态顺序表的数据空间长度 + bool ReIncrease(int len); +}; + +bool DynamicSequenceList::SetMaxSize(int max_size) { + this->_max_size = max_size; + return true; +} + +int DynamicSequenceList::GetMaxSize() const { + return this->_max_size; +} + +DynamicSequenceList::DynamicSequenceList() : SequenceList() { + // 初初始化动态顺序表长度为0 + this->SetMaxSize(0); + // 申请一片连续的存储空间 + auto *space = new element_type[MAXSIZE]; + if (space) { + this->SetData(space); + this->SetMaxSize(MAXSIZE); + } else { + cout << "SequenceList:分配空间失败!" << endl; + } +} + +bool DynamicSequenceList::OtherIncrease(int len) { + if (len <= 0) { + cout << "OtherIncrease:申请空间应该大于0!" << endl; + return false; + } + // 申请一片连续的存储空间 + int new_length = this->GetMaxSize() + len; + auto *space = new element_type[new_length]; + if (space) { + // 建立中间变量 + this->SetData(space); + element_type *temp = this->GetData(); + for (int i = 0; i < this->GetLength(); i++) { + this->SetData(i, temp[i]); + } + this->SetMaxSize(new_length); + free(temp); + return true; + } else { + cout << "OtherIncrease:重新分配空间失败!" << endl; + return false; + } +} + +bool DynamicSequenceList::ReIncrease(int length) { + if (length <= 0) { + cout << "ReIncrease:申请空间应该大于0!" << endl; + return false; + } + // 申请一片连续的存储空间 + int new_length = this->GetMaxSize() + length; + auto *space = (element_type *) realloc(this->GetData(), new_length * sizeof(element_type)); + if (space) { + this->SetData(space); + this->SetMaxSize(this->GetMaxSize() + length); + return true; + } else { + this->SetMaxSize(0); + this->SetLength(0); + cout << "ReIncrease:分配其他地址空间失败!" << endl; + return false; + } +} + +bool DynamicSequenceList::Insert(int index, element_type elem) { + if (index > this->GetLength() || index < 0) { + cout << "Insert:插入索引" << index << "超过索引范围!" << endl; + return false; + } + // 当动态顺序表已经满了,需要新增一个位置 + // 为了避免索引无效而多增加一个空间,所以放在检查索引值的后面 + if (this->GetLength() >= MAXSIZE) { + bool result = this->ReIncrease(1); + if (!result) { + cout << "Insert:申请空间失败!" << endl; + return false; + } + } + for (int i = this->GetLength(); i > index; i--) { + this->SetData(i, this->GetData(i - 1)); + } + this->SetData(index, elem); + this->SetLength(); + return true; +} diff --git a/Code/CPP-Code/head/sequence_stack.h b/Code/CPP-Code/head/sequence_stack.h new file mode 100644 index 0000000..a7ec1dc --- /dev/null +++ b/Code/CPP-Code/head/sequence_stack.h @@ -0,0 +1,134 @@ +#include +#include +#include "head.h" + +using namespace std; + +// 顺序栈 +class SequenceStack { +private: + // 栈内元素 + element_type *_data{}; + // 栈顶指针 + int _top{}; + // 最大容量 + int _max_size{}; +public: + // 设置数据 + bool SetData(element_type *data); + + // 栈顶指针自加 + bool SetTop(); + + // 设置栈顶指针 + bool SetTop(int top); + + // 获取栈顶指针 + int GetTop() const; + + // 设置最大容量 + bool SetMaxSize(int max_size); + + // 获取最大容量 + int GetMaxSize() const; + + // 构造函数 + SequenceStack(); + + explicit SequenceStack(int max_size); + + // 判空 + bool Empty() const; + + // 判满 + bool Full() const; + + // 栈长 + int Length() const; + + // 进栈 + bool Push(element_type elem); + + // 出栈 + element_type Pop(); + + // 读栈顶 + element_type Top(); +}; + +bool SequenceStack::SetData(element_type *data) { + this->_data = data; + return true; +} + +bool SequenceStack::SetTop() { + this->_top++; + return true; +} + +bool SequenceStack::SetTop(int top) { + this->_top = top; + return true; +} + +int SequenceStack::GetTop() const { + return this->_top; +} + +bool SequenceStack::SetMaxSize(int max_size) { + this->_max_size = max_size; + return true; +} + +int SequenceStack::GetMaxSize() const { + return this->_max_size; +} + +SequenceStack::SequenceStack() { + this->SetData(new element_type[MAXSIZE]); + this->SetTop(-1); + this->SetMaxSize(MAXSIZE); +} + +SequenceStack::SequenceStack(int max_size) { + this->SetData(new element_type[max_size]); + this->SetTop(-1); + this->SetMaxSize(max_size); +} + +bool SequenceStack::Empty() const { + return this->GetTop() == -1; +} + +bool SequenceStack::Full() const { + return this->GetTop() == this->GetMaxSize() - 1; +} + +int SequenceStack::Length() const { + return this->GetTop() + 1; +} + +bool SequenceStack::Push(element_type elem) { + if (this->Full()) { + cout << "Push:栈满无法进栈!" << endl; + return false; + } + this->_data[this->SetTop()] = elem; + return true; +} + +element_type SequenceStack::Pop() { + if (this->Empty()) { + cout << "Pop:栈空无法出栈!" << endl; + return NULL; + } + return this->_data[this->SetTop(this->GetTop() - 1)]; +} + +element_type SequenceStack::Top() { + if (this->Empty()) { + cout << "Top:栈空无法读栈顶元素!" << endl; + return NULL; + } + return this->_data[this->GetTop() - 1]; +} diff --git a/Code/CPP-Code/head/share_stack.h b/Code/CPP-Code/head/share_stack.h new file mode 100644 index 0000000..4b7cf88 --- /dev/null +++ b/Code/CPP-Code/head/share_stack.h @@ -0,0 +1,207 @@ +#include +#include +#include "head.h" + +using namespace std; + +// 共享栈 +class ShareStack{ +private: + // 栈内元素 + element_type *_data{}; + // 栈顶指针,left从0开始,right从MAXSIZE开始 + int _top_left{}, _top_right{}; + // 最大容量 + int _max_size{}; +public: + // 设置数据 + bool SetData(element_type *data); + + // 左栈顶指针自加 + bool SetTopLeft(); + + // 左设置栈顶指针 + bool SetTopLeft(int top); + + // 左获取栈顶指针 + int GetTopLeft() const; + + // 右栈顶指针自减 + bool SetTopRight(); + + // 右设置栈顶指针 + bool SetTopRight(int top); + + // 右获取栈顶指针 + int GetTopRight() const; + + // 设置最大容量 + bool SetMaxSize(int max_size); + + // 获取最大容量 + int GetMaxSize() const; + + // 构造函数 + ShareStack(); + + explicit ShareStack(int max_size); + + // 判左栈空 + bool EmptyLeft() const; + + // 判右栈空 + bool EmptyRight() const; + + // 判栈满 + bool Full() const; + + // 左栈长 + int LengthLeft() const; + + // 右栈长 + int LengthRight() const; + + // 进左栈 + bool PushLeft(element_type elem); + + // 进右栈 + bool PushRight(element_type elem); + + // 出左栈 + element_type PopLeft(); + + // 出右栈 + element_type PopRight(); + + // 读左栈顶 + element_type TopLeft(); + + // 读右栈顶 + element_type TopRight(); +}; + +bool ShareStack::SetData(element_type *data) { + this->_data = data; + return true; +} + +bool ShareStack::SetTopLeft() { + this->_top_left++; + return true; +} + +bool ShareStack::SetTopRight() { + this->_top_right--; + return true; +} + +bool ShareStack::SetTopLeft(int top) { + this->_top_left = top; + return true; +} + +bool ShareStack::SetTopRight(int top) { + this->_top_right = top; + return true; +} + +int ShareStack::GetTopLeft() const { + return this->_top_left; +} + +int ShareStack::GetTopRight() const { + return this->_top_right; +} + +bool ShareStack::SetMaxSize(int max_size) { + this->_max_size = max_size; + return true; +} + +int ShareStack::GetMaxSize() const { + return this->_max_size; +} + +ShareStack::ShareStack() { + this->SetData(new element_type[MAXSIZE]); + this->SetMaxSize(MAXSIZE); + this->SetTopLeft(-1); + this->SetTopRight(MAXSIZE); +} + +ShareStack::ShareStack(int max_size) { + this->SetData(new element_type[max_size]); + this->SetMaxSize(max_size); + this->SetTopLeft(-1); + this->SetTopRight(max_size); +} + +bool ShareStack::EmptyLeft() const { + return this->GetTopLeft() == -1; +} + +bool ShareStack::EmptyRight() const { + return this->GetTopRight() == this->GetMaxSize(); +} + +bool ShareStack::Full() const { + return this->GetTopRight() - this->GetTopLeft() == 1; +} + +int ShareStack::LengthLeft() const { + return this->GetTopLeft() + 1; +} + +int ShareStack::LengthRight() const { + return this->GetMaxSize() - this->GetTopRight(); +} + +bool ShareStack::PushLeft(element_type elem) { + if (this->Full()) { + cout << "PushLeft:栈满无法进栈!" << endl; + return false; + } + this->_data[this->SetTopLeft()] = elem; + return true; +} + +bool ShareStack::PushRight(element_type elem) { + if(this->Full()){ + cout << "PushRight:栈满无法进栈!" << endl; + return false; + } + this->_data[this->SetTopRight()] = elem; + return true; +} + +element_type ShareStack::PopLeft() { + if (this->EmptyLeft()) { + cout << "PopLeft:栈空无法出栈!" << endl; + return NULL; + } + return this->_data[this->SetTopLeft(this->GetTopLeft() - 1)]; +} + +element_type ShareStack::PopRight() { + if (this->EmptyRight()) { + cout << "PopRight:栈空无法出栈!" << endl; + return NULL; + } + return this->_data[this->SetTopRight(this->GetTopRight() + 1)]; +} + +element_type ShareStack::TopLeft() { + if (this->EmptyLeft()) { + cout << "TopLeft:栈空无法读栈顶元素!" << endl; + return NULL; + } + return this->_data[this->GetTopLeft() - 1]; +} + +element_type ShareStack::TopRight() { + if (this->EmptyRight()) { + cout << "TopRight:栈空无法读栈顶元素!" << endl; + return NULL; + } + return this->_data[this->GetTopRight() + 1]; +} \ No newline at end of file diff --git a/Code/CPP-Code/head/static_link_list.h b/Code/CPP-Code/head/static_link_list.h index d827a6a..830ed43 100644 --- a/Code/CPP-Code/head/static_link_list.h +++ b/Code/CPP-Code/head/static_link_list.h @@ -5,23 +5,23 @@ class StaticLinkListNode { private: // 数据元素 - element_type _data; + element_type _data{}; // 下一个元素的数组下标 - int _next; + int _next{}; public: // 设置元素 bool SetData(element_type elem); // 获取元素 - element_type GetData(); + element_type GetData() const; // 设置下标 bool SetNext(int index); // 获取下标 - int GetNext(); + int GetNext() const; // 构造函数 StaticLinkListNode(); - StaticLinkListNode(element_type elem); + explicit StaticLinkListNode(element_type elem); StaticLinkListNode(element_type elem, int next); @@ -29,20 +29,62 @@ public: bool Destroy(); }; +bool StaticLinkListNode::SetData(element_type elem) { + this->_data = elem; + return true; +} + +element_type StaticLinkListNode::GetData() const { + return this->_data; +} + +bool StaticLinkListNode::SetNext(int index) { + this->_next = index; + return true; +} + +int StaticLinkListNode::GetNext() const { + return this->_next; +} + +StaticLinkListNode::StaticLinkListNode() { + this->SetData(NULL); + this->SetNext(-1); +} + +StaticLinkListNode::StaticLinkListNode(element_type elem) { + this->SetData(elem); + this->SetNext(-1); +} + +StaticLinkListNode::StaticLinkListNode(element_type elem, int next) { + this->SetData(elem); + this->SetNext(next); +} + +bool StaticLinkListNode::Destroy() { + this->SetData(NULL); + this->SetNext(NULL); + return true; +} + class StaticLinkList { private: // 首元素地址 - int _first; + int _first{}; // 数据长度 - int _length; + int _length{}; // 数据当前最大长度 - int _max_size; + int _max_size{}; public: + // 数据 + StaticLinkListNode *data; + // 设置首元素地址 - bool SetFirst(int index); + bool SetFirst(int first); // 获取首元素地址 - int GetFirst(); + int GetFirst() const; // 数据长度自加 bool SetLength(); @@ -51,14 +93,64 @@ public: bool SetLength(int length); // 获取数据长度 - int GetLength(); + int GetLength() const; // 设置数据当前最大长度 bool SetMaxSize(int max_size); // 获取数据当前最大长度 - int GetMaxSize(); + int GetMaxSize() const; - // 数据 - StaticLinkListNode *data; -}; \ No newline at end of file + // 构造函数 + StaticLinkList(); + + StaticLinkList(int first, element_type elem); +}; + +bool StaticLinkList::SetFirst(int first) { + this->_first = first; + return true; +} + +int StaticLinkList::GetFirst() const { + return this->_first; +} + +bool StaticLinkList::SetLength() { + this->_length++; + return true; +} + +bool StaticLinkList::SetLength(int length) { + this->_length = length; + return true; +} + +int StaticLinkList::GetLength() const { + return this->_length; +} + +bool StaticLinkList::SetMaxSize(int max_size) { + this->_max_size = max_size; + return true; +} + +int StaticLinkList::GetMaxSize() const { + return this->_max_size; +} + +StaticLinkList::StaticLinkList() { + this->SetFirst(NULL); + this->SetLength(0); + this->SetMaxSize(MAXSIZE); + this->data = new StaticLinkListNode[MAXSIZE]; +} + +StaticLinkList::StaticLinkList(int first, element_type elem) { + this->SetFirst(first); + this->SetLength(1); + this->SetMaxSize(MAXSIZE); + this->data = new StaticLinkListNode[MAXSIZE]; + this->data[first].SetData(elem); + this->data[first].SetNext(-1); +} diff --git a/Code/CPP-Code/source/main.cpp b/Code/CPP-Code/source/main.cpp index 4dd56af..9474a29 100644 --- a/Code/CPP-Code/source/main.cpp +++ b/Code/CPP-Code/source/main.cpp @@ -3,7 +3,7 @@ int main() { - //SequenceListTest(); +// SequenceListTest(); LinkListTest(); return 0; } \ No newline at end of file diff --git a/Code/CPP-Code/source/test.cpp b/Code/CPP-Code/source/test.cpp index bc85e1b..5deedf2 100644 --- a/Code/CPP-Code/source/test.cpp +++ b/Code/CPP-Code/source/test.cpp @@ -1,13 +1,19 @@ -// 测试文件 +// 测试文件 #include "../head/sequence_list.h" #include "../head/link_list.h" +#include "../head/double_link_list.h" +#include "../head/static_link_list.h" +#include "../head/sequence_stack.h" +#include "../head/share_stack.h" +#include "../head/link_stack.h" bool SequenceListTest() { DynamicSequenceList list; element_type a[6] = {'1','2','3','4','5','6'}; list.LoopInsert(a, 0, 6); list.Print(); + element_type * data = list.GetData(); element_type* b = list.LoopDelete(1, 3); list.Print(); for (int i = 0; i < 3; i++) { @@ -32,7 +38,7 @@ bool LinkListTest() { auto* list = new LinkListWithoutHead(); list->NextInsert(a, 0 ,5); list->Print(); - int len = 5; + int len = 2; element_type* b = list->Delete(2, len); for (int i = 0; i < len; i++) { cout << b[i] << endl; @@ -40,4 +46,8 @@ bool LinkListTest() { list->Print(); cout << list->Locate('1') << endl; return true; +} + +bool StaticLinkListTest(){ + return true; } \ No newline at end of file diff --git a/Data-Structrue/1-linear-list-ex.md b/Data-Structrue/1-linear-list-ex.md index ac052b7..53fa784 100644 --- a/Data-Structrue/1-linear-list-ex.md +++ b/Data-Structrue/1-linear-list-ex.md @@ -33,3 +33,33 @@ $C.$Ⅰ、Ⅱ $D.$Ⅱ、Ⅲ 解:$C$。对于Ⅱ,顺序表仅需$3$次交换操作;链表则需要分别找到两个结点前驱,第$4$个结点断链后再插入到第$2$个结点后,效率较低。对于Ⅲ,需依次顺序访问每个元素,时间复杂度相同。 + +## 链表 + +### 结构选择 + +**例题** 一个链表最常用的操作是在末尾插入结点和删除结点,则选用()最节省时间。 + +$A.$带头结点的双循环链表 + +$B.$单循环链表 + +$C.$带尾指针的单循环链表 + +$D.$单链表 + +解:$A$。首先分析要求。末尾删除和插入结点,则需要对尾部操作。$B$是循环链表,但是方向是头结点到尾部,如果操作尾部需要$O(n)$的时间。$C$带了尾指针,所以可以对尾指针直接插入元素,但是不能删除尾指针所指向的最后一个元素,因为是单链表,所以不能找到尾指针的前驱。$D$单链表只能从头开始找,所以不合适。对于$A$。虽然它是带头结点,但是是循环链表,所以头节点的前驱就是尾结点,且是双链表,所以可以向前。若是删除尾结点直接删除头节点的前驱,同理插入尾节点,直接对头节点的前驱操作。 + +### 链表逻辑 + +**例题** 某线性表用带头结点的循环单链表存储,头指针为`head`,当 `head->next->next=head`成立时,线性表长度可能是()。 + +$A.0$ + +$B.1$ + +$C.2$ + +$D.$可能为$0$或$1$ + +解:$D$。这个题目很容易就会选择$B$。对于$B$,若是有一个元素,则$head->next$就指向该元素,该元素后面没有了,就指向头节点从而`head->next->next=head`。若元素有$0$个,则`head->next=head`,则`head->next->next=head->next=head`,所以也成立。 diff --git a/Data-Structrue/1-linear-list.md b/Data-Structrue/1-linear-list.md index 09ac37b..862d2a6 100644 --- a/Data-Structrue/1-linear-list.md +++ b/Data-Structrue/1-linear-list.md @@ -150,15 +150,15 @@ typedef struct LinkListNode { + 前插入。 + 后插入。 -假定从第一个结点开始就是第0索引的结点。 +假定从第一个结点开始就是第$0$索引的结点。 -带头结点的单链表头结点就是0号结点,不带头节点的第一个数据结点就是0号结点。 +带头结点的单链表头结点就是$0$号结点,不带头节点的第一个数据结点就是$0$号结点。 -带头结点的单链表只能往头结点之后插入,所以插入索引必须从1开始。 +带头结点的单链表只能往头结点之后插入,所以插入索引必须从$1$开始。 头插法建立单链表: -+ 每个结点的插入时间为$O(1)$,设单链表长为n,则总时间复杂度为$O(n)$。 ++ 每个结点的插入时间为$O(1)$,设单链表长为$n$,则总时间复杂度为$O(n)$。 + 实现了输入数据的就地逆置。 尾插法建立单链表 @@ -191,7 +191,7 @@ typedef struct LinkListNode { 按位查找时间复杂度为$O(n)$。 -这样插入元素函数InsertLinkListWithHead只用`GetLinkListNode(list,i-1)`和`InsertNextLinkNode(p,elem)`两个函数完成。 +这样插入元素函数`InsertLinkListWithHead`只用`GetLinkListNode(list,i-1)`和`InsertNextLinkNode(p,elem)`两个函数完成。 #### 单链表建立 @@ -203,7 +203,7 @@ typedef struct LinkListNode { ## 双链表 -为了解决单链表只能单一方向扫描而无法两项遍历的缺点,使用了两个指针,prior和next,分别指向前驱和后继。 +为了解决单链表只能单一方向扫描而无法两项遍历的缺点,使用了两个指针,`prior`和`next`,分别指向前驱和后继。 ### 双链表定义 @@ -211,31 +211,54 @@ typedef struct LinkListNode { ### 双链表操作 -#### 双链表初始化 + #### 双链表插入 +假如`p`的结点后要插入结点`s`,则基本代码如下: + +```c +// 将插入的结点的后续接上原来的p的后续 +s->next=p->next +// 将p后的结点的前驱连接到s上 +p->next->prior=s; +// 将s的前驱连接到p上 +s->prior=p; +// 将p的后继连接到s上 +p->next=s; +``` + +操作上都是成对的,其中第一条第二条指令必须在最后一条指令之前,否则`p`的后继就会丢掉。 + #### 双链表删除 +若删除结点`p`的后继结点`q`: + +```c +p->next=q->next; +q->next->prior=p; +free(q); +``` + ## 循环链表 分为循环单链表和循环双链表。基本上变化不大。 -原来的单链表的尾部指向NULL,但是循环单链表的尾部是指向头部。 +原来的单链表的尾部指向`NULL`,但是循环单链表的尾部是指向头部。 循环单链表即使没有头结点的地址,也可以通过循环得到整个单链表的信息。 从头到尾单链表需要遍历整个链表,而循环单链表只用移动一位就可以从头到尾。 -循环双链表除此之外,头结点的prior指针还要指表尾结点(即某结点*p为尾结点时,p->next==list)。 +循环双链表除此之外,头结点的`prior`指针还要指表尾结点(即某结点`*p`为尾结点时,`p->next==list`)。 -循环双链表为空表时,头结点的prior和next域都等于list(即,指向自身)。 +循环双链表为空表时,头结点的`prior`和`next`域都等于`list`(即,指向自身)。 ### 循环链表定义 循环链表和链表的结点定义是一致的。 -### 循环链表操作 + ## 静态链表 @@ -253,9 +276,11 @@ typedef struct LinkListNode { 静态链表和顺序表一样需要预先分配一块连续的内存空间。 -数组0号元素充当链表的头结点且不包含数据。 +数组$0$号元素充当链表的头结点且不包含数据。 -如果一个结点是尾结点,其游标设置为-1。 +如果一个结点是尾结点,其游标设置为$-1$。 + +具体的实现方式有多种,也可以$0$号元素数据保存头节点下标。 考的比较少。 diff --git a/Data-Structrue/2-stack.md b/Data-Structrue/2-stack.md index db3bcf5..0f768c5 100644 --- a/Data-Structrue/2-stack.md +++ b/Data-Structrue/2-stack.md @@ -1,10 +1,10 @@ # 栈 -栈结构与线性表类似,是只允许一端(表尾)进入或删除的线性表。即后进先出LIFO。 +栈结构与线性表类似,是只允许一端(表尾)进入或删除的线性表。即后进先出$LIFO$。 栈顶就是允许插入和删除的一端,而另一端就是栈底。 -进栈顺序:A->B->C->D,出栈顺序:D->C->B->A。 +进栈顺序:$A\rightarrow B\rightarrow C\rightarrow D$,出栈顺序:$D\rightarrow C\rightarrow B\rightarrow A$。 如果有$n$个不同的元素进栈,出栈元素不同排列的个数为$\dfrac{1}{n+1}C_{2n}^n$,这就是卡特兰数。 @@ -12,15 +12,33 @@ ### 顺序栈定义 +设置栈顶指针可以为$0$(代表栈顶元素的下一个存储单元)也可以为$-1$(代表栈顶元素当前未知), + ### 顺序栈操作 #### 顺序栈初始化 -栈顶指针初始化为-1,因为索引最小为0。如果初始化为0也可以,不过其操作有所不同。 +栈顶指针初始化为$-1$,因为索引最小为$0$。如果初始化为$0$也可以,不过其操作有所不同。 + +#### 进栈 + +首先要判满,然后才能进栈。若栈顶指针指的是当前元素,即初值为$-1$,需要先自加再进栈,如果不先自加就会覆盖在原来的栈顶元素上。若栈顶指针指的是当前元素的下一个位置,即初值为$0$,则先进栈再自加,因为指向的下一个位置,所以指向的位置是空的,所以可以存入然后自加,若先自加则中间就空了一格。 + +#### 出栈 + +首先要判空,然后才能出栈。若栈顶指针指的是当前元素,即初值为$-1$,需要先出栈再自减,如果由于指的是当前元素所以要先将这个指向的元素弹出,然后自减,否则弹出的就是靠近栈底的下一个元素。若栈顶指针指的是当前元素的下一个位置,即初值为$0$,则先自减再出栈,因为指向的下一个位置,所以指向的位置是空的,要先自减指向有元素的一格才能出栈。 + +对于出栈元素的处理,既可以将原来的存储单元设置为`NULL`也可以不处理,因为栈顶指针不指向这些单元,用户是不知道里面是什么的,之后重新用到这些存储单元也会覆盖原来的数据。 + +### 共享栈 + +即根据栈底不变,让两个顺序栈共享一个一维数组,将两个栈的栈底设在数组两端,栈顶向共享空间延申。 + +存取数据时间复杂度为$O(1)$。 ## 链栈 -链栈基本上就是只能操作一头的链表,所以从定义上其基本上没有区别。 +链栈基本上就是只能操作一头的链表,所以从定义上其基本上没有区别。基本上以表头为栈顶。 ## 栈的应用