栈和队列
栈和队列¶
Part I | Part II |
---|---|
栈 | 队列 |
栈¶
1-顺序栈¶
顺序栈的定义
顺序栈的初始化
bool InitStack(SqStack &S)
{
S.base = new ElemType[MAXSIZE]; //顺序栈:同一般的线性表的顺序存储结构完全相同,利用(数组)一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,栈底一般在低地址端
//在堆区开辟数组,返回该数据对应的类型的指针,指向数组的首地址
if (!S.base)
{
cerr << "failed to get memory" << endl;
return false;
}
S.top = S.base;
S.stacksize = MAXSIZE;
return true;
}
压栈
bool Push(SqStack &S, ElemType &e)
{
//判断栈是否已满
if((S.top-S.base) == S.stacksize)
{
cerr << "full of stack" << endl;
return false;
}
*(S.top) = e;
++(S.top);
return true;
}
创建一个栈
bool CreatStack(SqStack &S, const int n)
{
for (int i = 0; i < n;++i)
{
ElemType input;
cin >> input;
if(!Push(S,input))
{
cerr << "error happend at-" << i << endl;
return false;
}
}
return true;
}
弹栈
bool Pop(SqStack &S, ElemType &e)
{
if(!IsEmpty(S))
{
cerr << "empty stack!error" << endl;
return false;
}
--(S.top);
e = *(S.top);
return true;
}
判断顺序栈是否为空
获取栈的元素个数
清空顺序栈
销毁顺序栈
void DestoyStack(SqStack &S)
{
if(S.base)
{
delete[] S.base; //S.base在堆区开辟的数组
S.stacksize = 0;
S.base = S.top = nullptr;
}
}
2-链式栈¶
链式栈的定义
栈的初始化
void InitStack(LinkStack &S)
{
//创建头结点
S = new StackNode;
S->next = nullptr;
S->data = 0; //表示栈的元素个数
}
//王老师的视频中没有设置头结点
//由于ELemType等价于int,因此我设置了一个头结点,在头结点的数据域中保存栈的元素个数
压栈
void Push(LinkStack &S, const ElemType &e)
{
//插入元素
StackNode *temp = new StackNode;
temp->data = e;
temp->next = S->next;
S->next = temp;
++(S->data);//元素个数加一
}
弹栈
void Pop(LinkStack &S, ElemType &e)
{
//删除元素
StackNode *p = S->next;
e = p->data; //保存弹出结点的数据
S->next = p->next;
--(S->data);
delete p;
}
创建栈
void CreatStack(LinkStack &S, const int n)
{
ElemType input;
for (int i = 0; i < n;++i)
{
cin >> input;
Push(S, input); //压栈
}
}
获取栈的元素个数
判断栈是否为空
清空栈
bool ClearStack(LinkStack &S)
{
if(!(S->next))
{
cerr << "empty Stack" << endl;
return false;
}
StackNode *q, *p = S->next;
while(p)
{
q = p; //取出当前结点
p = p->next; //指向下一节点
delete q; //删除当前结点
}
S->data = 0;
S->next = nullptr;
return true;
}
销毁栈
bool DestoryStack(LinkStack &S)
{
//if(S)
//{
// cerr << "error" << endl;
// return false;
//}
while(S)
{
StackNode *temp = S;
S = S->next;
delete temp;
}
return true;
}
队列¶
1-顺序队列¶
顺序队列定义
顺序队列初始化
判断队是否为空
判断是否满队
bool IsFull(SqQueue &Q)
{
//少用一个元素空间的方式
auto rear_next = (Q.rear + 1) % MAXSIZE;
if (rear_next == Q.front)
return true;
else
return false;
}
进队
bool InsertQueue(SqQueue &Q, const ElemType &e)
{
//如果队尾+1等于队头,表明队已经满了(该队列是少用一个空间的循环队列,满队和空队的判断条件不一致)
if (IsFull(Q))
{
cerr << "full of Queue" << endl;
return false;
}
Q.elem[Q.rear] = e;
Q.rear = (Q.rear + 1) % MAXSIZE;
return true;
}
批量进队
void CreatQueue(SqQueue &Q, const int n)
{
cout << "input msg" << endl;
ElemType input;
for (int i = 0; i < n;++i)
{
cin >> input;
InsertQueue(Q, input);
}
}
出队
bool EraseQueue(SqQueue &Q)
{
//如果队头等于队尾,表明队里没有元素,不执行该程序
if (IsEmpty(Q))
{
cerr << "no elem to erase" << endl;
return false;
}
//e = Q.elem[Q.front];
Q.front = (Q.front + 1) % MAXSIZE;
return true;
}
求队列的元素个数
打印队列
void PrintQueue(SqQueue &Q)
{
cout << "Queue:" << endl;
for (auto i = Q.front; i != Q.rear; i = (i + 1) % MAXSIZE)
{
cout << Q.elem[i] << endl;
}
}
2-链式队列¶
定义链队
struct Qnode
{
ELemType data;
Qnode *next;
};
struct LinkQueue //再定义一个抽象数据类型,一次性建立两个Qnode指针
{
Qnode *front; //头指针
Qnode *rear; //尾指针 //指向Qnode类型数据的头尾指针
};
初始化
void InitQueue(LinkQueue &Q)
{ //Q.front、Q.rear是Qnode*
Q.front = Q.rear = new Qnode;
Q.front->data = 0; //用于保存链队的元素个数
Q.rear->next = nullptr;
}
进队
void InsertQueue(LinkQueue &Q, const ELemType &e)
{
//把元素插在最后面
Qnode *temp = new Qnode;
temp->data = e;
temp->next = nullptr;
Q.rear->next = temp;
Q.rear = temp;
++Q.front->data; //元素个数加1
}
创建链队
void CreatQueue(LinkQueue &Q, const int n)
{
cout << "input msg" << endl;
ELemType input;
for (int i = 0; i < n; ++i)
{
cin >> input;
InsertQueue(Q, input);
}
}
出队
bool EraseQueue(LinkQueue &Q)
{
if (Q.front->next == nullptr)
{
cerr << "empty Queue" << endl;
return false;
}
Qnode *p = Q.front->next;
Q.front->next = p->next;
delete p;
--Q.front->data; //元素个数-1
return true;
}
打印链队
void PrintQueue(LinkQueue &Q)
{
Qnode *p = Q.front->next;
while (p)
{
cout << p->data << endl;
p = p->next;
}
}
本篇完~