【数据结构三】栈和队列

130 阅读3分钟

  • 定义:只允许在一端进行插入或删除操作的线性表(LIFO)
  • 重要术语:栈顶、栈底、空栈
  • 特点:先进后出

图片.png

//-----------顺序栈
#define MaxSize 10 //栈中元素的最大个数
typedef struct{
	int data[MaxSize]; //静态数组存放栈中元素
	int top; //栈顶指针 
}SqStack; 
// 初始化栈
void InitStack(SqStack &S){
	S.top = -1; //初始化栈顶指针 
} 
//新元素入栈
bool Push(SqStack &S, int x){
	if(S.top == MaxSize-1) //栈满,报错
		return false;
	S.top = S.top +1 ;  // 指针先+1 
	S.data[S.top] = x; // 新元素入栈 
} 
// 出栈
bool Pop(SqStack &S, int &x){
	if(S.top == -1) //栈空,报错
		return false;
	x = S.data[S.top]; // 栈顶元素先出栈
	S.top = S.top -1; // 指正再减1
	// 也可以这样写
//	x = S.data[S.top--]; 
	return true; 
} 
// 共享栈
#define MaxSize 10 //定义栈中元素的最大个数
typedef struct{
	int data[MaxSize]; //静态数组存放栈中元素
	int top0; //0号栈栈顶指针
	int top1; //1号栈栈顶指针
}ShStack; 
// 初始化栈
void InitStack(ShStack &S){
	S.top0 = -1; //初始化栈顶指针
	S.top1 = MaxSize;
}
 

图片.png

图片.png

队列

定义:只允许在一端进行插入,在另一端删除的线性表(FIFO)

术语:队头、队尾、空队列

图片.png

//------------队列 
#define MaxSize 10  //定义队列中元素的最大个数
typedef struct{
	int data[MaxSize]; //用静态数组存放队列元素
	int front,rear; // 队头指针和队尾指针 
} SqQueue; 
//初始化
void InitQueue(SqQueue &S){
	S.rear = S.front = 0; //队头,队尾指针指向0 
} 
//判断队列是否为空
bool QueueEmpty(SqQueue Q){
	if(Q.front == Q.rear) return true; //队空条件 
	else return false;
} 
//入队
bool EnQueue(SqQueue &Q, int x){ 
	if((Q.rear + 1) % MaxSize == Q.front)
		return false; //队满则报错 
	Q.data[Q.rear] = x; //将x插入队尾
	Q.rear = (Q.rear +1) % MaxSize; //队尾指针+1取模 
	return true; 
} 
//出队(删除一个队头元素,并用x返回)
bool DeQueue(SqQueue &Q, int &x){
	if(Q.rear == Q.front)
		return false; // 队空则报错 
	x = Q.data[Q.front];
	Q.front = (Q.front + 1) % MaxSize;
	return true;
} 
//获取对头元素的值,用x返回
bool GetHead(SqQueue Q, int &x){
	if(Q.rear == Q.front)
		return false; //队空则报错
	x = Q.data[Q.front];
	// 队列元素个数
	(Q.rear + MaxSize-Q.front) % MaxSize   
	return true; 
} 

图片.png

链式队列

图片.png


//---------队列的链式实现
typedef struct LinkNode{ // 链式队列结点 
	int data;
	struct LinkNode *next;
}LinkNode; 
typedef struct{//链式队列 
	LinkNode *front, *rear; //队列的队头和队尾指针 
}LinkQueue;

//初始化队列(带头结点)
void InitQueue(LinkQueue &Q){
	//初始时,front, rear都指向头结点
	Q.front = Q.rear = (LinkNode *)malloc(sizeof(LinkNode));
	Q.front->next = NULL; 
} 
//初始化队列(不带头结点) 
void InitQueue2(LinkQueue &Q){
	//初始时,front, rear都指向NULL
	Q.front = NULL;
	Q.rear = NULL; 
}
//判断队列是否为空(带头结点) 
bool IsEmpty(LinkQueue Q){
	if(Q.front == Q.rear) return true;
	else return false;
} 
//判断队列是否为空(不带头结点) 
bool IsEmpty2(LinkQueue Q){
	if(Q.front == NULL) return true;
	else return false;
}
//新元素入队(带头结点)
void EnQueue(LinkQueue &Q, int x){
	LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
	s->data = x;
	s->next = NULL;
	Q.rear->next = s; //新结点插入到rear之后
	Q.rear = s; //修改表尾指针 
} 
//新元素入队(不带头结点)
void EnQueue2(LinkQueue &Q, int x){
	LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
	s->data = x;
	s->next = NULL;
	if(Q.front == NULL){
		//在空队列中插入第一个元素
		Q.front = s; //修改队头队尾指针 
		Q.rear = s; 
	} else {
		Q.rear->next = s; //新结点插入到rear结点之后 
		Q.rear = s;//修改rear指针 
	}
} 
//队头元素出队(带头结点)
bool DeQueue(LinkQueue &Q, int &x){
	if(Q.front == Q.rear) return false; //空队
	LinkNode *p = Q.front->next;
	x = p->data; //用变量x返回队头元素
	Q.front->next = p->next; //修改头结点的next指针
	if(Q.rear == p) //此次是最后一个结点出队
		Q.rear = Q.front; //修改rear指针
	free(p); //释放结点空间
	return false; 
} 
//队头元素出队(不带头结点)
bool DeQueue2(LinkQueue &Q, int &x){
	if(Q.front == NULL) return false; //空队
	LinkNode *p = Q.front; //p指向此次出队的结点
	x = p->data; //返回队头元素
	Q.front = p->next; //修改front指针
	if(Q.rear == p){//此次是最后一个结点出队
		Q.front = NULL;
		Q.rear = NULL; 
	} 
	free(p); //释放
	return true;  
} 
void test(){
	LinkQueue Q; //声明一个队列
	InitQueue(Q); //初始化队列 
}

双端队列

定义: 只允许从两端插入,两端删除的线性表

图片.png

图片.png

图片.png