1
0
mirror of https://github.com/Didnelpsun/CS408.git synced 2026-02-04 03:14:30 +08:00

更新数据结构

This commit is contained in:
Didnelpsun
2021-09-15 23:47:38 +08:00
parent 028cf20dde
commit b1998ca91c
13 changed files with 1059 additions and 465 deletions

View File

@@ -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);
};
return true;
}

View File

@@ -1,4 +1,4 @@
// 初始化最大长度
// 初始化最大长度
#define MAXSIZE 5
// 定义默认值
#define DEFAULTELEM '0'

View File

@@ -1,7 +1,9 @@
#include <cstdio>
#include <cstdio>
#include <cstdlib>
#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-1start到达求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-1start到达求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() {

View File

@@ -0,0 +1,76 @@
#include <cstdlib>
#include <iostream>
#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;
}

View File

@@ -1,4 +1,4 @@
#include <cstdlib>
#include <cstdlib>
#include <iostream>
#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;
}

View File

@@ -0,0 +1,134 @@
#include <cstdlib>
#include <iostream>
#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];
}

View File

@@ -0,0 +1,207 @@
#include <cstdlib>
#include <iostream>
#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];
}

View File

@@ -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;
};
// 构造函
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);
}

View File

@@ -3,7 +3,7 @@
int main()
{
//SequenceListTest();
// SequenceListTest();
LinkListTest();
return 0;
}

View File

@@ -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;
}

View File

@@ -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`,所以也成立。

View File

@@ -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 {
## 双链表
为了解决单链表只能单一方向扫描而无法两项遍历的缺点使用了两个指针priornext分别指向前驱和后继。
为了解决单链表只能单一方向扫描而无法两项遍历的缺点,使用了两个指针,`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`)。
循环双链表为空表时头结点的priornext域都等于list指向自身
循环双链表为空表时,头结点的`prior``next`域都等于`list`(即,指向自身)。
### 循环链表定义
循环链表和链表的结点定义是一致的。
### 循环链表操作
<!-- ### 循环链表操作
#### 循环单链表初始化
@@ -243,7 +266,7 @@ typedef struct LinkListNode {
#### 循环双链表插入
#### 循环双链表删除
#### 循环双链表删除 -->
## 静态链表
@@ -253,9 +276,11 @@ typedef struct LinkListNode {
静态链表和顺序表一样需要预先分配一块连续的内存空间。
数组0号元素充当链表的头结点且不包含数据。
数组$0$号元素充当链表的头结点且不包含数据。
如果一个结点是尾结点,其游标设置为-1。
如果一个结点是尾结点,其游标设置为$-1$
具体的实现方式有多种,也可以$0$号元素数据保存头节点下标。
考的比较少。

View File

@@ -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)$。
## 链栈
链栈基本上就是只能操作一头的链表,所以从定义上其基本上没有区别。
链栈基本上就是只能操作一头的链表,所以从定义上其基本上没有区别。基本上以表头为栈顶。
## 栈的应用