这个作业属于哪个班级 | C语言–网络2011/2012 |
---|---|
这个作业的地址 | DS博客作业02–栈和队列 |
这个作业的目标 | 学习栈和队列的结构设计及运算操作 |
姓名 | 骆锟宏 |
the photo of stack is followed:
*
#include
就可以使用,不过值得一提的是,C++中的typedef int ElementType;
typedef int Position;
struct SNode
{
ElementType* Data;
Position Top;
int MaxSize;
};
typedef struct SNode* SQStack;
top = 0
;void CreateSQStack(SQStack& S, int MaxSize)
{
S = new struct SNode;
S->Data = new ElementType;
S->Top = -1;
S->MaxSize = MaxSize;
}
S->Top == S->MaxSize
;S->Data[S->Top++] = X;
;bool Push(SQStack S, ElementType X)//顺序堆栈的入栈操作
{
//入栈操作要先判断是否栈满
if (S->Top == S->MaxSize-1)//栈满了
{
printf("SQStack Full\n");
return false;
}
//正常入栈
S->Data[++S->Top] = X;
return true;
}
S->Top == 0
;return S->Data[--S->Top]
;ElementType Pop(SQStack S)//顺序栈的出栈操作
{
/*先判断栈是否为空*/
if (S->Top == -1)
{
printf("SQStack Empty\n");
return ERROR;
}
//正常出栈
return S->Data[S->Top--];
}
关于获取当前栈的元素个数:
return S->Top+1
;return S->Top
;准确来说还有一个销毁栈的操作,对于顺序栈而言,一般直接delete栈就行。
typedef int ElementType;
typedef int Position;
struct SNode {
ElementType* Data;
Position Top1, Top2;
int MaxSize;
};
typedef struct SNode* SharedStack;
void CreateSharedStack(SharedStack& S,int MaxSize)//创建共享栈
{
S = new struct SNode;
S->Data = new ElementType;
S->Top1 = -1;
S->Top2 = MaxSize;
}
bool Push(SharedStack S, ElementType X, int Tag)//共享栈的进栈操作
{
/*进栈要考虑栈是否满*/
if (S->Top1 + 1 == S->Top2)
{
printf("SharedStack Full\n");
return false;
}
if (Tag == 1)
{
S->Data[++S->Top1] = X;
return true;
}
else
{
S->Data[--S->Top2] = X;
return true;
}
}
ElementType Pop(SharedStack S, int Tag)//共享栈的出栈操作
{
/*共享栈要分开考虑栈是否为空的情况*/
if (Tag == 1)
{
/*栈空判断*/
if (S->Top1 == -1)
{
printf("SharedStack %d Empty\n", Tag);
return ERROR;
}
return S->Data[S->Top1--];
}
else
{
/*栈空判断*/
if (S->Top2 == S->MaxSize)
{
printf("SharedStack %d Empty\n", Tag);
return ERROR;
}
return S->Data[S->Top2++];
}
}
共享栈的取栈顶操作:
S->Data[S->Top1]
;S->Data[S->Top2]
;准确来说还有一个销毁栈的操作,对于顺序栈而言,一般直接delete栈就行。
链栈的结构基础其实仍然是链表,出于栈只能在一端进行入栈和出栈的操作的考虑,所以一般选择
链表的第一个结点处为栈顶,而取链表为栈底,又由于栈的入栈和出栈操作本质上就是链表的插入和
删除操作,所以保留表头方便再头处(也就是栈顶)进行入栈和出栈操作,总之,可以把链栈看成一
个带有头指针的只在头处进行插入删除操作的链表来使用就行。
链栈的结构基本定义:(本质上还是链表的定义)
typedef int Elmetype;
struct SNode
{
Elmetype data;
struct SNode* next;
};
typedef struct SNode* LinkStack;
void CreateLinkStack(LinkStack& S,int n)
{
S = new SNode;
S->next = NULL;
for (int i = 0; i < n; i++)
{
LinkStack NewS = new SNode;
/*数据载入*/
cin >> NewS->data;
/*头插法插入新数据*/
NewS->next = S->next;
S->next = NewS;
}
}
void Push(LinkStack& S, Elmetype X)
{
LinkStack NewS = new SNode;
/*数据载入*/
NewS->data = X;
/*头插法插入新数据*/
NewS->next = S->next;
S->next = NewS;
}
bool Pop(LinkStack& S, Elmetype& e)
{
/*首先要判断栈顶是否为空*/
if (S->next == NULL)
{
return false;
}
e = S->next->data;
LinkStack delSNode = S->next;
S->next = delSNode->next;
delete delSNode;
return true;
}
链栈的取栈顶元素操作:
S->next->Data
;链栈的销毁操作:
void DestoryLinkStack(LinkStack& S)
{
LinkStack delS = S;
while (S != NULL)
{
S = S->next;
delete delS;
delS = S;
}
}
'+' '-' '*' '/' '(' ')'
这六个符号。the photo of queue is followed:
#include
便可以使用了。typedef int ElemType;
#define MaxSize 100// 100只是一个例子具体情况视题目而定。
typedef struct
{
ElemType data[MaxSize];
int front, rear; //队首和队尾指针
}Queue;
typedef Queue* SqQueue;
void CreatSqQueue(SqQueue& Que)
{
Que = new Queue;
Que->front = Que->rear = 0;
//初始化的状态是队空的状态
//一般我们默认让front代表队头的位置,让rear代表队尾的下一个位置
}
bool EnQueue(SqQueue& Q, Elmetype e)//加入队列
{
/*要先判断是否队满*/
if (Q->rear == Maxsize)
{
return false;
}
Q->data[Q->rear++] = e;
return true;
}
bool QueueEmpty(SqQueue& Q)//队列是否为空
{
if (Q->front == Q->rear)
{
return true;
}
return false;
}
bool DeQueue(SqQueue& Q, Elmetype& e)//出队列
{
if (QueueEmpty(Q))
{
return false;
}
e = Q->data[Q->front++];
return true;
}
有始有终,使用完了后,得将队列销毁,此处由于结构比较简单可以直接delete
。
在这里不妨思考一个问题,刚才顺序队列中,当我们出队的时候,当下队头前的空间实际是可以使用的
但是当前的数据结构却不允许我们使用前面的空间,试想当数据量十分庞大的时候,使用这样的数据结构岂
不是会浪费很大的空间?那有没有什么办法能够利用到前面的的空间呢?
———把数组首尾连接起来,变成一个环形,你会发现就能解决这样的问题,于是新的结构营运而生,它便是环形队列!
typedef int ElementType;
typedef int Position;
struct QNode {
ElementType* Data; /* 存储元素的数组 */
Position Front; /* 队列的头指针 */
Position Rear; /* 队列的尾指针 */
int MaxSize; /* 队列最大容量 */
};
typedef struct QNode* RingQueue;
Q->Front = Q->Rear = 0;
这便是循环队列为空的条件。void CreateRingQueue(RingQueue& Q,int MaxSize)
{
Q = new struct QNode;
Q->Data = new ElementType[MaxSize];
Q->Front = Q->Rear = 0;
Q->MaxSize = MaxSize;
}
bool EnQueue(RingQueue& Q, ElementType X)
{
if ((Q->Rear+1)%Q->MaxSize == Q->Front)//Queue Full
{
return false;
}
Q->Data[Q->Rear] = X;
Q->Rear = (Q->Rear + 1) % Q->MaxSize;
return true;
}
bool DeQueue(RingQueue& Q, ElementType e)
{
if (Q->Front == Q->Rear)//Queue Empty
{
return false;
}
e = Q->Data[Q->Front];
Q->Front = (Q->Front + 1) % Q->MaxSize;
return true;
}
delete
。typedef int Elmenttype;
typedef Queue* PtrtoQueue;
typedef struct
{
Elmenttype data;
PtrtoQueue next;
}Queue;
typedef struct
{
PtrtoQueue Front;
PtrtoQueue Rear;
}LinkQueue;
void CreatLinkQueue(LinkQueue& LQ)
{
LQ.Rear = LQ.Front = new Queue;
LQ.Front->next = NULL;
}
bool EnQueue(LinkQueue& LQ, Elmenttype X)
{
PtrtoQueue NewNode = new Queue;
NewNode->data = X;
NewNode->next = LQ.Rear->next;
LQ.Rear->next = NewNode;
LQ.Rear = NewNode;
}
bool Empty(LinkQueue LQ)
{
if (LQ.Front == LQ.Rear)
{
return true;
}
return false;
}
bool DeQueue(LinkQueue& LQ, Elmenttype& X)
{
if (!Empty(LQ))
{
X = LQ.Front->next->data;
PtrtoQueue DelNode;
DelNode = LQ.Front->next;
LQ.Front->next = DelNode->next;
delete DelNode;
return true;
}
return false;
}
int QueueLen(SqQueue Q)//队列长度
{
int len = Q->rear - Q->front;
return len;
}
int EnQueue(SqQueue& Q, Person e)//加入队列
{
if (Q->rear == MAXQSIZE)
{
return ERROR;
}
Q->data[Q->rear++] = e;
}
int QueueEmpty(SqQueue& Q)//队列是否为空
{
if (Q->front == Q->rear)
{
return OK;
}
return ERROR;
}
int DeQueue(SqQueue& Q, Person& e)//出队列
{
if (QueueEmpty(Q))
{
return ERROR;
}
e = Q->data[Q->front++];
}
void DancePartner(Person dancer[], int num)//配对舞伴
{
Person man;
Person woman;
/*先分队*/
for (int i = 0; i < num; i++)
{
if (dancer[i].sex == 'F')
{
EnQueue(Fdancers, dancer[i]);
}
else
{
EnQueue(Mdancers, dancer[i]);
}
}
/*再出队配对*/
while (!QueueEmpty(Fdancers) && !QueueEmpty(Mdancers))
{
DeQueue(Fdancers,woman);
DeQueue(Mdancers, man);
cout << woman.name << " " << man.name << endl;
}
}
符号配对
银行业务队列简单模拟的代码
解题思路:
伪代码如下:
//input
while(未到最后一行)
{
getline(单行str)
总str += 单行str;
}
//match
用string[]分别建好左右的符号表。
while(遍历总str中)
{
if(cur_sign为左符号) 执行push;
if (cur_sign为右符号)
{
if(stack不空)
{
if (左右符号匹配) 执行pop;
else 执行输出缺右符号
}
else 执行输出缺左符号
}
if(stack empty)-> all matched
else 执行输出缺右符号
}
//other function
遍历string[]找相同的string元素。
getline(cin,string,end_char)
,getline函数可以设置一个char常量为输入的结束点。解题思路如下:
伪代码如下:
输入顾客总数,
输入顾客编号组成的数组,
在输入数组数据的过程中,对编号进行判断
if(编号是奇数),向队列A执行入队操作。
if(编号是偶数),向队列B执行入队操作。
业务处理过程函数()。
以下是业务处理过程函数的伪代码,本质上是对队列执行出队操作
并按格式要求打印出出队的数据。
首先是对两个队列进行同时遍历
while(队A不空 && 队B不空)
{
先出队一次队A元素并打印(末尾有空格)
再次判断if(队A不空)
再出队一次队A元素并打印(末尾有空格)
再再次判断if(队A不空)
出队一次队B元素并打印(末尾有空格)
再再次判断if(队A为空 && 队列B仅剩一个元素)
出队一次队B元素并打印(末尾无空格)
}
//处理一个空一个不空的问题
while(A不为空)
{
若队列A仅剩一个元素时,出队一个队A元素并打印(末尾无空格)
若队列A不为空时,出队一个队A元素并打印(末尾有空格)
}
对队列B的处理同上。
class SortedStack {
public:
stack stk, help;
SortedStack() {
}
void push(int val) {
if (stk.empty()) stk.push(val);
else {
while (!stk.empty() && stk.top() < val) { //寻找储存栈中插入的位置(即,利用辅助栈help保存弹出元素
help.push(stk.top());
stk.pop();
}
stk.push(val); //找到合适位置后进行插入
while (!help.empty()) { //将之前弹出的元素重新导回储存栈
stk.push(help.top());
help.pop();
}
}
}
void pop() {
if (!stk.empty()) stk.pop();
}
int peek() {
return stk.empty() ? -1 : stk.top();
}
bool isEmpty() {
return stk.empty();
}
};
作者:wen-jian-69
链接:https://leetcode-cn.com/problems/sort-of-stacks-lcci/solution/cha-ru-pai-xu-si-xiang-by-wen-jian-69-4mxy/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
以下是原作者的设计思路
- 按照题目要求,就是要我们构造一个从栈底到栈顶的降序序列,因此可以参考插入排序,每次对元素val进行插入时先寻找其在有序序列的插入位置;
- 栈内寻找插入位置通过不断比较插入元素和栈顶元素的大小来实现;
- 若栈顶元素大于或等于插入元素,则可以直接入栈,若栈顶元素小于插入元素,则弹出栈顶,同时用辅助栈保存弹出的元素,
直到栈顶元素大于或等于插入元素,即可将val入栈,最后在将之前保存的弹出元素导回。
作者:wen-jian-69
链接:https://leetcode-cn.com/problems/sort-of-stacks-lcci/solution/cha-ru-pai-xu-si-xiang-by-wen-jian-69-4mxy/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
insertOrder():
in every Push():
if (dataStack is empty) then push(val) into dataStack;
else
{
while(find the insert location)
{
if (val > topdata) then push(topdata) into helpStack and pop(it);
}
when we find the location by the above circulation
push(val) into dataStack;
and then push all data in helpStack into dataStack by another circulation.
}
* In the end,what need we do is to run this insertOrder function
each time we insert a new data. And we can get a descending order
stack from button to top.
* 由于只使用了一层循环以及只使用了一个辅助栈来解决问题,所以该问题的时间复杂度和空间复杂度都是线性阶O(n)。
exp1 ? exp2 : exp3
说明这个运算符的使用很简洁,逻辑也很清晰,要学会使用。