栈
栈的定义
顺序栈
基本算法
- 声明顺序栈
typedef struct{
ElemType data[MaxSize]; //存放栈中的数据元素
int top; //栈顶指针,即存放栈顶元素在data数组中的下标
}SqStack;
- 初始化栈
void InitStack(SqStack * & s){
s = (SqStack * )malloc(sizeof(SqStack)); //分配一个顺序栈空间,首地址存放在s中
s->top = -1;
}
- 销毁栈
void DestroyStack(SqStack * &s){
free(s);
}
- 判断栈是否为空
bool StackEmpty(SqStack * s){
return(s->top == -1);
}
- 进栈
bool Push(SqStack * &s,ElemType e){
if(s->top == MaxSize-1) //栈满情况,即栈上溢出
return false;
s->top++; //栈顶指针增1
s->data[s->top] = e; //元素e放在栈顶指针处
return true;
}
- 出栈
bool Pop(SqStack * &s,ElemType &e){
if(s->top == -1) //栈为空的情况,即栈下溢出
return false;
e = s->data[s->top]; //取栈顶元素
s->top--; //栈顶指针减1
return true;
}
- 取栈顶元素
bool GetTop(SqStack * s,ElemType &e){
if(s->top == -1) //栈为空的情况,即栈下溢出
return false;
e = s->data[s->top] //取栈顶元素
return true;
}
应用
bool symmetry(ElemType str[]){ //判断str是否为对称串
int i;ElemType e;
SqStack * st; //定义顺序栈指针
InitStack(st); //初始化栈
for(i = 0;str[i]!='\0';i++){ //将str的所有元素进栈
Push(st,str[i]);
}
for(i = 0;str[i]!='\0';i++){ //处理str的所有字符
Pop(st,e); //退栈元素e
if(str[i]!=e) //若e与当前串字符不同,说明不是对称串
{
DestroyStack(st);
return false;
}
DestroyStack(st); //销毁
return true;
}
}
共享栈
typedef struct{
ElemType data[MaxSize]; //存放共享栈中的元素
int top1,top2; //两个栈的栈顶指针
}DStack;
链栈
- 定义
栈中数据元素的逻辑关系呈线性关系,所以栈可以像线性表一样采用链式存储结构。采用链式存储结构的栈称为链栈
- 声明
typedef struct linknode{
ElemType data; //数据域
struct linknode * next; //指针域
}LinkStNode; //链栈结点类型
- 初始化栈
void InitStack(LinkStNode * &s){
s = (LinkStNode * )malloc(sizeof(LinkStNode));
s->next = NULL;
}
- 销毁栈
void DestroyStack(LinkStNode * &s){
LinkStNode * pre = s,*p = s->next; //pre指向头结点,p指向首结点
while(p != NULL){ //循环到p为空
free(pre); //释放pre结点
pre = p; //pre、p同步后移
p = pre->next;
}
free(pre);
}
- 判断栈是否为空
bool StackEmpty(LinkStNode * s){
return(s->next == NULL);
}
- 进栈
void Push(LinkStNode * &s,ElemType e){
LinkStNode * p;
p = (LinkStNode *)malloc(sizeof(LinkStNode));
p->data = e;
p->next = s->next; //将p结点插入作为首结点
s->next = p ;
}
- 出栈
bool Pop(LinkStNode * &s,ElemType &e){
LinkStNode *p;
if(s->next == NULL) //栈空情况
return false;
p = s->next; //p指向首结点
e = p->data; //提取首结点值
s->next = p->next; //删除首结点
free(p); //释放被删结点的存储空间
return true;
}
- 取栈顶元素
bool GetTop(LinkStNode 8 s,ElemType &e){
if(s->next == NULL){
return false;
}
e = s->next->data;
return false;
}
- 应用
bool Match(char exp[],int n){
int i = 0;char e;
bool match = true;
LinkStNode * st;
InitStack(st); //初始化链栈
while(i<n && match){ //扫描exp中的所有字符
if(exp[i] == '(') //当前字符为左括号,将七进栈
Push(st,exp[i]);
else if(exp[i] == ')') //当前字符为右括号
{
if(GetTop(st,e) == true){//成功取栈顶元素e
if(e !='('){
metch = false; //当栈顶元素不为(时,表示不匹配
}
else{
Pop(st,e); //当扎顶元素为(时,将栈顶元素出栈
}
}
}
i++; //继续处理其他字符
}
if(!StackEmpty(st)) //栈不为空时表示不匹配
match = false;
DestroyStack(st); //销毁栈
return match;
}
队列
定义
顺序队
- 声明队列
typedef struct{
ElemType data[MaxSize];
int front,rear; //队头和队尾指针
}SqQueue;
- 初始化队列
void InitQueue(SqQueue * &q){
q = (SqQueue *)malloc(sizeof(SqQueue));
q->front = q->rear =-1;
}
- 销毁队列
void DestroyQueue(SqQueue * &q){
free(q);
}
- 判断队列是否为空
bool QueueEmpty(SqQueue * &q){
return(q->front == q->rear);
}
- 进队
bool enQueue(SqQueue * &q,ElemType e){
if(q->rear == MaxSize-1) //队满上溢出
return false;
q->rear++; //队尾增1
q->data[q->rear] = e; //rear位置插入元素e
return true;
}
- 出队
bool deQueue(SqQueue * &q,ElemType &e){
if(q->front == q->rear) //队空下溢出
return false;
q->front++;
e = q->data[q->front];
return true;
}
环形队
-
定义
-
初始化队列
void InitQueue(SqQueue * &q){
q = (SqQueue *)malloc(sizeo(SqQueue));
q->front = q->rear = 0;
}
- 销毁队列
void DestroyQueue(SqQueue * &q){
free(q);
}
- 判断队列是否为空
bool QueueEmpty(SqQueue * q){
return(q->front == q->rear);
}
- 进队列
bool enQueue(SqQueue * &q,ElemType e){
if((q->rear+1)%MaxSize == q->front) //队满上溢出
return false;
q->rear=(q->rear+1)%MaxSize; //队尾增1
q->data[q->rear] = e; //rear位置插入元素e
return true;
}
- 出队列
bool deQueue(SqQueue * &q,ElemType &e){
if(q->front == q->rear) //队空下溢出
return false;
q->front = (q->front+1)%MaxSize;
e = q->data[q->front];
return true;
}
链队
- 声明
链队中数据结点声明:
typedef struct qnode{
ElemType data;
struct qnode * next;
}DataNode;
链队头结点声明:
typedef struct{
DataNode * front;
DataNode * rear;
}LinkQuNode;
- 初始化
void InitQueue(LinkQuNode * &q){
q=(LinkQuNode * )malloc(sizeof(LinkQuNode));
q->front = q->rear = NULL;
}
- 销毁队列
void DestroyQueeu(LinkQuNode * &q){
DataNode *pre = q->front,*p; //pre指向队首结点
if(pre!=NULL){
p = pre->next; //p指向pre的后继结点
while(p!=NULL){
free(pre);
pre = p;p = p->next; //pre、p同步后移
}
free(pre); //释放最后一个数据结点
}
free(q); //释放链队结点
}
- 判断队列是否为空
bool QneneEmpty(LinkQuNode * q){
return(q->rear == NULL);
}
- 进队列
void enQueue(LinkQuNode * &q,ElemType e){
DataNode *p;
p = (DataNode *)malloc(sizeof(DataNode)); //创建新结点
p->data = e;
p->next = NULL;
if(q->rear == NULL) //若链队为空,则新结点既是队首结点又是队尾结点
q->front = q->rear = p;
else{ //若链队不为空
q->rear->next = p; //将结点p链到队尾,并将rear指向它
q->rear = p;
}
}
- 出队列
bool deQueue(LinkQuNode * &q,ElemType &e){
DataNode *t;
if(q=>rear == NULL) //原来队列为空
return false;
t = q->front; //t指向首结点
if(q->front == q->rear) //原来队列中只有一个数结点时
q->front = q->rear = NULL;
else //原来队列中有两个或两个以上结点时
q->front = q->front->next;
e = t->data;
free(t);
return true;
}
- 应用
void number(int n){
int i;ElemType e;
SqQueue *q; //环形队列指针q
InitQueue(q); //初始化队列q
for(i = 1;i<=n;i++) //构建初始序列
enQueue(q,i);
printf("报数出列顺序:");
while(!QueueEmpty(q)){ //队列不空循环
deQueue(q,e); //出队一个元素e
printf("%d",e); //删除元素编号
if(!QueueEmpty(q)) //队列不空
{
deQueue(q,e); //出队一个元素e
enQueue(q,e); //将刚出队的元素进队
}
printf("\n");
DestroyQueue(q); //销毁队列q
}
}
int main(){
int i,n = 8;
printf("初始序列:");
for(i = 1;i<=n;i++)
printf("%d",i);
prinf("\n");
number(n);
return 1;
}
没看懂!
双端队列
- 实现“从队尾删除”运算的算法如下:
bool deQueuel(SqQueue * &q,ElemType &e){ //从队尾删除算法
if(q->front == q->rear) //队空返回假
return false;
e = q->data[q->rear]; //提取队尾元素
q->rear = (q->rear-1+MaxSize)%MaxSize; //修改队尾指针
return true;
}
- 实现“从队头插入”运算的算法如下:
bool enQueuel(SqQueue * &q,ElemType e){
if((q->rear + 1)%MaxSize == q->front) //队满返回假
return false;
q->data[q->front] = e; //元素e进队
q->front = (q->front-1+MaxSize)%MaxSize; //修改队头指针
}