队列的链式存储代码实现
//带头节点 Q.front->next才指向第一个元素
typedef struct QNode{
ElemType data;
struct QNode *next;
}QNode, *QueuePtr;
typedef struct{
QueuePtr front;
QueuePtr rear;
}LinkQueue;
void InintQueue(LinkQueue &Q)
{
Q.front = Q.rear = (QNode*)malloc(sizeof(QNode))
Q.front->next = NULL;
}
bool EmptyQueue(LinkQueue &Q)
{
return (Q.front == Q.rear);
}
Status EnQueue(LinkQueue &Q, ElemType x)
{
QNode *p = (QNode*)malloc(sizeof(QNode));
p->data = x;
p->next = NULL;
Q.rear->next = p;
Q.rear = p;
return OK;
}
Status DeQueue(LinkQueue &Q, &e)
{
if(Q.front == Q.rear)
return False;
QNode *p= Q.front->next;
e = p->data;
Q.front->next = p->next;
if(Q.rear == p)
{
Q.rear = Q.front;
}
free(p);
return OK;
}
ElemType GetHead(LinkQueue Q)
{
if(Q.front->next == NULL)
return NULL;
return Q.front->next->data;
}
typedef struct QNode{
ElemType data;
struct QNode *next;
}QNode, *QueuePtr;
typedef struct{
QueuePtr front;
QueuePtr rear;
}LinkQueue;
//不带头节点 头指针是直接指向第一个队头元素
void InitQueue(LinkQueue &Q)
{
Q.front = Q.rear = NULL;
}
bool EmptyQueue(LinkQueue &Q)
{
return (Q.front == NULL);
}
Status EnQueue(LinkQueue &Q, ElemType x)
{
QNode *p = (QNode*)malloc(sizeof(QNode));
p->data = x;
p->next = NULL;
if(Q.front == NULL)
{
Q.front = p;
Q.rear = p;
}
Q.rear->next = p;
Q.rear = p;
}
Status DeQueue(LinkQueue &Q, &e)
{
if(Q.front == NULL)
return False;
p = Q.front;
Q.front = p->next;
if(p == Q.rear)
{
Q.rear = Q.front;
}
free(p);
return OK;
}
ElemType GetHead(LinkQueue Q)
{
if(Q.front != NULL)
return Q.front->data;
return NULL;
}
队列的具体应用
- 计算八进制
void conversion(int N)
{
Stack S;
InitStatck(S);
while(N>0)
{
push(S, N % 8);
N /= 8;
}
while(!EmptyStack(S))
{
cout << Pop(S) << endl;
}
}
- 括号匹配
bool matching(char a[], int len)
{
Stack S;
InitStack(S);
for(int i = 0; i < len; i++)
{
if(a[i] == '(' || a[i] == '[' || a[i] == '{')
push(S, a[i]);
else
{
if(EmptyStack(S))
return false
e = GetTop(S);
if(e == '(' && a[i] == ')' || e == '[' && a[i] == ']'|| e == '{' && a[i] == '}')
{
Pop(S);
}
else
return false;
}
}
if(!EmptyStack(S))
return false;
return true;
}
4.表达式计算
规则:
1.遇到操作数直接加入操作数栈中
2.遇到运算符:运算符栈顶元素 和 当前运算符 进行优先级比较
1.运算符栈顶元素 >= 当前运算符 弹出运算符栈 操作数栈弹出最上层的两个栈顶元素进行改弹出运算符的运算并将结果放回操作数栈中,依次继续和栈顶元素进行比较,比出来<就停止
2.运算符栈顶元素 < 当前运算符 栈顶元素继续呆在运算符栈
都要将当前运算符入栈
3.遇到括号界定符:
1. 遍历到“(”入栈
2. 遍历到“)”,弹出运算符,并弹出最上层的两个栈顶元素进行运算并将结果放回操作数栈中,直到弹出“)”
//NUM 操作数栈 OPR运算符栈
char EvaluateExpression()
{
Push(OPR,'#')
cin >> ch;
while(ch != '#' && GetTop(OPR) != '#')\
{
if(!operators(ch))
{
push(NUM, ch);
cin >> ch;
}
else
switch(precede(GetTop(OPR), ch))
{
case '<':
//运算符栈顶元素 < 当前运算符
push(OPR, ch)
cin >> ch;
break;
case '>':
//这里优先级包含左优先,但当栈顶元素是(时,不弹出。
//规定左括号运算级别最高,右括号运算级别最低,则括号内的运算符基本运算完成后还剩下其他运算符时,一和右括号比较,优先级肯定高 也会弹出栈进行运算
//运算符栈顶元素 >= 当前运算符,弹出运算,!!继续将当前元素和栈顶元素比较!
Pop(OPR, op);
Pop(NUM, a);
Pop(NUM, b);
push(NUM, operate(a,op,b))
case '=':
//只有一种情况 左括号遇到右括号时 弹出
Pop(OPR,op);
cin >> ch;
}
}
}
- 和舞伴一起跳舞(实际应用,只用基本函数并声明一下)
void DancePartner(Person dance[], int num)
{
InitQueue(Mdancers);
InitQueue(Fdancers);
for(int i = 0; i < num; i++)
{
if(person[i].sex = 'M')
EnQueue(Mdancers, person[i]);
else
EnQueue(Fdancers, person[i]);
}
while(!EmptyQueue(Fdancers) && !EmptyQueue(Mdancers))
{
DeQueue(Mdancers, man);
DeQueue(Fdancers, woman);
cout << "欢迎" << man.name << "男士和" << woman.name << "女士一起跳舞" << endl;
}
if(!EmptyQueue(Fdancers))
{
woman = GetTop(Fdancers);
cout << "下一场第一个跳舞的女士是" << woman.name << endl;
}
if(!EmptyQueue(Mdancers))
{
man = GetTop(Mdancers);
cout << "下一场第一个跳舞的女士是" << man.name << endl;
}
}