重点:栈、队列、及移位运算符
栈和队列
1.栈:
特点:FILO;
用处:常用与括号匹配;火车进站出站的顺序排列,发生的可能性;
<1>顺序栈:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
#define INI 1000
#define INC 1000
#define OK 1
#define ERROR 0
#define TRUE 1
#define OVERFLOW -2
using namespace std;
struct Stack
{
int* top;
int* base;
int Size;
}s;
int Init(Stack& S)
{
S.base=(int *)malloc(INI*sizeof(int));
if(!S.base) exit(OVERFLOW);
S.top=S.base;
S.Size=INI;
return OK;
}
int Push(Stack& S,int e)
{
if(S.top-S.base>=S.Size)
{
S.base=(int *)realloc(S.base,(INC+S.Size)*sizeof(int));
if(!S.base) exit(OVERFLOW);
S.top=S.base+S.Size;
S.Size=S.Size+INC;
}
*(S.top++)=e;
return OK;
}
int Pop(Stack& S,int& e)
{
if(S.top==S.base)
return ERROR;
e=*--S.top;
return OK;
}
int Gettop(Stack S,int &e)
{
if(S.top==S.base) return ERROR;
e=*--S.top;
return OK;
}
int display(Stack S)
{
while(S.base<S.top)
{
cout<<*(--S.top)<<" ";
}
cout<<endl;
return OK;
}
int isEmpty(Stack S)
{
if(S.top==S.base) return TRUE;
return ERROR;
}
int Length(Stack S)
{
return S.top-S.base;
}
int Clear(Stack& S)
{
if(S.base)
S.top=S.base;
return OK;
}
int Destory(Stack& S)
{
if(S.base)
{
free(S.base);
S.base=S.top=NULL;
S.Size=0;
}
return OK;
}
int main(){
Stack S;
int N,e;
cout<<"1.构造一个空顺序栈"<<endl;
cout<<"2.链栈的入栈 "<<endl;
cout<<"3.链栈的出栈"<<endl;
cout<<"4.取栈顶元素"<<endl;
cout<<"5.判断是否为空栈"<<endl;
cout<<"6.栈的长度"<<endl;
cout<<"7.清除栈"<<endl;
cout<<"8.销毁栈"<<endl;
cout<<"9.打印"<<endl;
while(1){
cout<<"输入操作数,输入负数结束"<<endl;
cin>>N;
if(N==1)
{
if(Init(S)==OK)cout<<"构造空栈成功 "<<endl;
}
else if(N==2)
{
int cnt1=0,cnt=0;
cout<<"输入入栈元素(0结束)"<<endl;
while(true)
{
cin>>e;
if(e==0) break;
cnt1++;
if(Push(S,e)==OK)cnt++;
}
if(cnt1==cnt) cout<<"入栈成功"<<endl;
}
else if(N==3)
{
if(Pop(S,e)==OK)
cout<<"栈顶元素:"<<e<<" 出栈成功"<<endl;
}
else if(N==4)
{
if(Gettop(S,e))
cout<<"栈顶元素是"<<e<<endl;
else
cout<<"栈已空"<<endl;
}
else if(N==5)
{
if(isEmpty(S))
cout<<"栈为空"<<endl;
else
cout<<"栈不为空"<<endl;
}
else if(N==6)
{
cout<<"该栈的长度是:"<<Length(S)<<endl;
}
else if(N==7)
{
if(Clear(S))
cout<<"成功清除"<<endl;
}
else if(N==8)
{
if(Destory(S))
cout<<"成功销毁"<<endl;
}
else if(N==9)
{
display(S);
}
else if(N<=-1)
{
exit(0);
}
else
{
cout<<"请输入正确的序号"<<endl;
}
}
return 0;
}
<2>链栈#include<iostream>
#include<cstring>
#include<string>
#include<cstdlib>
using namespace std;
#define INI 1000
#define INC 1000
#define NULL 0
#define OK 1
#define ERROR 0
#define TRUE 1
#define OVERFLOW -2
struct Stack
{
int data;
Stack* next;
};
int Init(Stack*& S)
{
S=NULL;
return OK;
}
int Push(Stack*& S,int e)
{
Stack* p=(Stack*)malloc(sizeof(Stack));
if(!p) exit(OVERFLOW);
p->data=e;
p->next=S;
S=p;
return OK;
}
int Pop(Stack*& S,int& e)
{
Stack* p=(Stack*)malloc(sizeof(Stack));
p=S;
if(p==NULL) return ERROR;
e=p->data;
S=S->next;
free(p);
return OK;
}
int Gettop(Stack* S,int &e)
{
e=S->data;
return OK;
}
int display(Stack* S)
{
while(S!=NULL)
{
cout<<S->data<<" ";
S=S->next;
}
return OK;
}
int isEmpty(Stack* S)
{
if(S==NULL) return TRUE;
return ERROR;
}
int Length(Stack* S)
{
int n=0;
while(S!=NULL)
{
S=S->next;
++n;
}
return n;
}
int Clear(Stack*& S)
{
if(S!=NULL)
{
S=NULL;
}
return OK;
}
int Destory(Stack*& S)
{
while(S!=NULL)
{
free(S);
S=S->next;
}
return OK;
}
int main(){
Stack* S;
int N,e;
cout<<"1.构造一个空顺序栈"<<endl;
cout<<"2.链栈的入栈 "<<endl;
cout<<"3.链栈的出栈"<<endl;
cout<<"4.取栈顶元素"<<endl;
cout<<"5.判断是否为空栈"<<endl;
cout<<"6.栈的长度"<<endl;
cout<<"7.清除栈"<<endl;
cout<<"8.销毁栈"<<endl;
cout<<"9.打印"<<endl;
while(1){
cout<<"输入操作数,输入负数结束"<<endl;
cin>>N;
if(N==1)
{
if(Init(S)==OK)cout<<"构造空栈成功 "<<endl;
}
else if(N==2)
{
int cnt1=0,cnt=0;
cout<<"输入入栈元素(0结束)"<<endl;
while(true)
{
cin>>e;
if(e==0) break;
cnt1++;
if(Push(S,e)==OK)cnt++;
}
if(cnt1==cnt) cout<<"入栈成功"<<endl;
}
else if(N==3)
{
if(Pop(S,e)==OK)
cout<<"栈顶元素:"<<e<<" 出栈成功"<<endl;
else
cout<<"栈已空"<<endl;
}
else if(N==4)
{
if(Gettop(S,e))
cout<<"栈顶元素是"<<e<<endl;
else
cout<<"栈已空"<<endl;
}
else if(N==5)
{
if(isEmpty(S))
cout<<"栈为空"<<endl;
else
cout<<"栈不为空"<<endl;
}
else if(N==6)
{
cout<<"该栈的长度是:"<<Length(S)<<endl;
}
else if(N==7)
{
if(Clear(S))
cout<<"成功清除"<<endl;
}
else if(N==8)
{
if(Destory(S))
cout<<"成功销毁"<<endl;
}
else if(N==9)
{
display(S);
}
else if(N<=-1)
{
exit(0);
}
else
{
cout<<"请输入正确的序号"<<endl;
}
}
return 0;
}
2.队列:
特点:FIFO;(表前删除,表后添加)
形式:
1).方法一:顺序队列
#include<iostream>
#include<cstring>
#include<algorithm>
#define OK 1
#define ERROR 0
#define TRUE 1
#define OVERFLOW -2
#define maxSize 10
using namespace std;
struct Queue
{
int *elem;
int rear;
int front;
};
int Init(Queue& Q)
{
Q.elem=(int*)malloc(maxSize*sizeof(int));
if(!Q.elem) exit(OVERFLOW);
Q.rear=Q.front=0;
return OK;
}
int EnQueue(Queue& Q,int e)
{
if((Q.rear+1)%maxSize==Q.front)
return ERROR;
Q.elem[Q.rear]=e;
Q.rear=(Q.rear+1)%maxSize;
return OK;
}
int DeQueue(Queue& Q,int& e)
{
if(Q.rear==Q.front) return ERROR;
e=Q.elem[Q.front];
Q.front=(Q.front+1)%maxSize;
return OK;
}
int isEmpty(Queue Q)
{
cout<<"Q.rear:"<<Q.rear<<" Q.front:"<<Q.front<<endl;
return !Q.rear-Q.front;
}
int Leng(Queue Q)
{
int len=(maxSize+Q.rear-Q.front)%maxSize;
return len;
}
int Traverse(Queue Q)
{
if(!Q.elem||Q.front==Q.rear)
return ERROR;
while(Q.front!=Q.rear)
{
cout<<Q.elem[Q.front]<<" ";
Q.front=(Q.front+1)%maxSize;
}
cout<<endl;
return OK;
}
int Clear(Queue& Q)
{
if(Q.front)
{
Q.rear=Q.front;
}
return OK;
}
int Destory(Queue& Q)
{
if(Q.elem)
{
free(Q.elem);
}
return OK;
}
int main()
{
Queue Q;
int e,n;
Init(Q);
cout<<"1.入队"<<endl;
cout<<"2.出队"<<endl;
cout<<"3.队长度"<<endl;
cout<<"4.队是否为空"<<endl;
cout<<"5.队的清除"<<endl;
cout<<"6.队的销毁"<<endl;
cout<<"7.队的遍历"<<endl;
while(true)
{
cout<<"输入你的选项:"<<endl;
cin>>n;
switch(n)
{
case 1:
{
int cnt=0,cnt1=0;
cout<<"输入正整数(0结束):"<<endl;
while(true)
{
cin>>e;
if(!e) break;
cnt++;
if(EnQueue(Q,e))
cnt1++;
}
cout<<"入队成功!"<<endl;
} break;
case 2:
{
if(DeQueue(Q,e))
cout<<"出队元素为:"<<e<<endl;
else
cout<<"队为空!"<<endl;
}break;
case 3:
{
cout<<"队长度为:"<<Leng(Q)<<endl;
} break;
case 4:
{
if(isEmpty(Q))
cout<<"队列为空!"<<endl;
else
cout<<"队列不为空!"<<endl;
} break;
case 5:
{
if(Clear(Q))
cout<<"队清除成功!"<<endl;
else
cout<<"抱歉,没有成功!"<<endl;
} break;
case 6:
{
if(Destory(Q))
cout<<"销毁成功!"<<endl;
else
cout<<"操作失败!"<<endl;
}
break;
case 7:
{
if(!Traverse(Q))
{
cout<<"队列为空!"<<endl;
}
}
break;
default:
break;
}
}
}
2).方法二:链队列
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define OK 1
#define ERROR 0
#define TRUE 1
#define OVERFLOW -2
using namespace std;
typedef struct node
{
int data;
struct node* next;
}node,*link;
struct Queue
{
node* rear;
node* front;
};
int Init(Queue& Q)
{
Q.rear=Q.front=(link)malloc(sizeof(node));
if(!Q.front) exit(OVERFLOW);
Q.front->next=NULL;
return OK;
}
int EnQueue(Queue& Q,int e)
{
link p=(link)malloc(sizeof(node));
if(!p) exit(OVERFLOW);
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
return OK;
}
int DeQueue(Queue& Q,int& e)
{
if(Q.rear==Q.front) return ERROR;
link p=(link)malloc(sizeof(node));
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(p==Q.rear) Q.rear=Q.front;
free(p);
return OK;
}
int isEmpty(Queue Q)
{
return Q.rear-Q.front;
}
int Leng(Queue Q)
{
int n=0;
while(Q.front!=Q.rear)
{
Q.front=Q.front->next;
++n;
}
return n;
}
int Traverse(Queue Q)
{
while(Q.front!=Q.rear)
{
cout<<Q.front->next->data<<" ";
Q.front=Q.front->next;
}
cout<<endl;
return OK;
}
int Clear(Queue& Q)
{
if(Q.front)
{
Q.rear=Q.front;
}
return OK;
}
int Destory(Queue& Q)
{
while(Q.front)
{
Q.rear=Q.front->next;
free(Q.front);
Q.front=Q.rear;
}
return OK;
}
int main()
{
Queue Q;
int e,n;
Init(Q);
cout<<"1.入队"<<endl;
cout<<"2.出队"<<endl;
cout<<"3.队长度"<<endl;
cout<<"4.队是否为空"<<endl;
cout<<"5.队的清除"<<endl;
cout<<"6.队的销毁"<<endl;
cout<<"7.队的遍历"<<endl;
while(true)
{
cout<<"输入你的选项:"<<endl;
cin>>n;
switch(n)
{
case 1:
{
int cnt=0,cnt1=0;
cout<<"输入正整数(0结束):"<<endl;
while(true)
{
cin>>e;
if(!e) break;
cnt++;
if(EnQueue(Q,e))
cnt1++;
}
cout<<"入队成功!"<<endl;
} break;
case 2:
{
if(DeQueue(Q,e))
cout<<"出队元素为:"<<e<<endl;
else
cout<<"队为空!"<<endl;
}break;
case 3:
{
cout<<"队长度为:"<<Leng(Q)<<endl;
} break;
case 4:
{
if(isEmpty(Q))
cout<<"队列为空!"<<endl;
else
cout<<"队列不为空!"<<endl;
} break;
case 5:
{
if(Clear(Q))
cout<<"队清除成功!"<<endl;
else
cout<<"抱歉,没有成功!"<<endl;
} break;
case 6:
{
if(Destory(Q))
cout<<"销毁成功!"<<endl;
else
cout<<"操作失败!"<<endl;
}
break;
case 7:
{
if(!Traverse(Q))
{
cout<<"队列为空!"<<endl;
}
}
break;
default:
break;
}
}
}
3).方法三:STL库
#include<queue>
using namespacestd;
queue<int>Q;
入列:Q.push(入列元素);
出列:Q.pop();
栈and队列在STL使用:
1、栈
加上“stack”的头文件,常用的函数有:
stack<int>p;
p.push();p.pop();p.top();p.size();p.empty();
2、队列
加上<queue>的头文件,常用的函数有:
queue<int>q;
p.push();p.pop();q.front();q.back();p.size();p.empty();
队列中有个特殊的地方,优先队列priority_queue;
priority_queue<int>q;
自定义优先级:
struct cmp
{
operator bool ()(int x, int y)
{
return x > y; // x小的优先级高
//也可以写成其他方式,如: return p[x] > p[y];表示p[i]小的优先级高
}
};
priority_queue<int,vector<int>, cmp>q;//定义方法
结构体的优先级定义:
structnode
{
int x, y;
friend bool operator < (node a, node b)
{
return a.x > b.x; //结构体中,x小的优先级高
}
};
priority_queue<node>q;//定义方法
3.移位运算符
可分为两种:
1).与符号无关
形如:<<<(向左运算符)和>>>(向右运算符);
2).与符号有关
形如:<<(向左运算符)和>>(向右运算符);
a.<<向左运算符
8<<1(符号为正):表示二进制的数向左移动1位;
8的二进制是:00001000向左移动1位->变为00010000(想象一下动态的小链条向左移动,最后在最右边补0);
-8<<1(符号为负):我们易得-8的二进制是:10001000->向左移动1位->10010000(符号位不变,在最右边补0);
b.>>向右运算符
8>>1(符号为正):表示二进制的数向右移动1位;
8的二进制是:00001000向右移动1位->变为00000100(想象一下动态的小链条向右移动,最后在最左边补0);
-8>>1(符号为负):我们易得-8的二进制是:10001000->向右移动1位->11000100(符号位不变,在最左边补1);