栈与队列(链表形式c/c++)

目录

一、栈

1.栈的思想

2.链栈的组成

【1】栈的结构

【2】栈的功能函数

(1)初始化链栈

(2)链栈判断是否为空

(3)求栈的长度

(4)求栈顶元素

(5)进栈

(6)出栈

(7)遍历栈的内容

3.栈的全部代码

二、队列

1.队列的思想

2.链队的结构

3.链队的基本操作

4.链队代码实现

【1】初始化队列

【2】队列判空

【3】队列长度

直接求cnt的值即可

【4】进栈

【5】出队

【6】遍历并输出队列

【7】全部代码


一、栈

(注意:本文章仅为个人笔记作用,无法保证绝对的准确性与规范性,仅保证程序实现算法需求)

1.栈的思想

栈是一种特殊的数据结构,一切数据只能在栈顶进出,不能像链表一样在头部或者中间插入删除。相对与链表的自由和灵活,栈显得更规范,更有针对性,比如递归的原理就是栈。

(学习链栈所需知识:链表的基本操作、指针的基础了解)

2.链栈的组成

【1】栈的结构

链栈由链表组成,以指针所指节点为栈顶

//数据域
typedef struct Node{
	int num;//数据域可以包括更多东西,这里的int num仅用于讲解方便
	struct Node *next;
}Node;

//链栈的结构体
typedef struct Stack{
	Node *top;//栈顶
	int cnt;//栈节点的个数
}Stack;

【2】栈的功能函数

(下面申请空间的语句如Node *node=new Node

C语言改为Node *node=(Node*)malloc( sizeof(Node) ) 即可,不影响程序正常使用)

(1)初始化链栈

因为链栈不需要头节点,故栈顶指针初始化为空即可

//栈初始化 
int InitStack(Stack *s)
{
	s->top=NULL;
	s->cnt=0;
}

(2)链栈判断是否为空

直接判断s->top是否等于NULL即可,这里因为有记录栈元素的个数,也可以判断个数(如下)

//栈判空,空返回1
int StackEmpty(Stack *s)
{
	if(s->cnt==0)
		return 1;
	else
		return 0;
}

(3)求栈的长度

即求s->cnt为多少

//求栈的长度
int StackSize(Stack *s)
{
	return s->cnt;	
} 

(4)求栈顶元素

//求栈顶元素
int TopData(Stack *s)
{
	return s->top->num;	
} 

(5)进栈

申请一个新节点,把数据存进节点,再让该节点的指针指向栈顶元素,最后令栈顶指针指向新节点,栈的个数加一,完成进栈

//进栈 
int Push(Stack *s,int data)
{
	Node *node=new Node;
    if(node==NULL)
        return 0;
	node->num=data;
	node->next=s->top;
	s->top=node;	
	s->cnt++;	
    return 1;
}

(6)出栈

创建一个新指针指向栈顶元素,保存栈顶信息,令栈顶指针指向栈顶的下一个元素,释放栈顶元素的空间,栈的个数减一,完成出栈

//出栈 
int Pop(Stack *s,int *e)
{
	Node *p=s->top;
	s->top=s->top->next;
	*e=p->num;
	delete p;
	s->cnt--;
    return 1;
}

(7)遍历栈的内容

新建指针指向栈顶元素,打印信息并继续指向下一个元素,直至指针为空

//打印栈内容 
void Show(Stack *s)
{
	Node *p=s->top;
	while(p){
		cout<<"data="<<p->num<<endl;
		p=p->next;
	}
}

3.栈的全部代码

//栈
#include<iostream>
using namespace std;

typedef struct Node{
	int num;
	struct Node *next;
}Node;

typedef struct Stack{
	Node *top;
	int cnt;
}Stack;

//栈初始化 
int InitStack(Stack *s)
{
	s->top=NULL;
	s->cnt=0;
}

//栈判空 
int StackEmpty(Stack *s)
{
	if(s->cnt==0)
		return 1;
	else
		return 0;
}

//求栈顶元素
int TopData(Stack *s)
{
	return s->top->num;	
} 

//求栈的长度
int StackSize(Stack *s)
{
	return s->cnt;	
} 

//进栈 
int Push(Stack *s,int data)
{
	Node *node=new Node;
	if(node==NULL)
		return 0;
	node->num=data;
	node->next=s->top;
	s->top=node;	
	s->cnt++;	
	return 1;
}

//出栈 
int Pop(Stack *s,int *e)
{
	Node *p=s->top;
	s->top=s->top->next;
	*e=p->num;
	delete p;
	s->cnt--;
	return 1;
}

//打印栈内容 
void Show(Stack *s)
{
	Node *p=s->top;
	while(p){
		cout<<"data="<<p->num<<endl;
		p=p->next;
	}
}

int main()
{
	Stack s;//这里不用指针形式的结构体,因为链表中head节点属于*node而s包含*top
	//不属于指针节点,故不用指针形式 
	InitStack(&s);
	for(int i=0;i<6;i++)
	{
		cout<<"进栈了元素:"<<i<<endl; 
		Push(&s,i);
	}
	cout<<"栈为空吗:"<<StackEmpty(&s)<<endl;
	cout<<"栈的长度为:"<<s.cnt<<endl;
	cout<<"栈顶元素为:"<<s.top->num<<endl;
	cout<<"\n第一次遍历:\n"; 
	Show(&s); 
	int a;
	Pop(&s,&a);
	cout<<"出栈元素a="<<a<<endl;
	Pop(&s,&a);
	cout<<"出栈元素a="<<a<<endl;
	cout<<"\n第二次遍历:\n";
	Show(&s);
}

二、队列

1.队列的思想

队列是一种只允许再一端插入和另一端删除的数据结构,模拟人们平时排队的情景,队头出队,队尾进队。

2.链队的结构

队头(front):插入数据的一端

队尾(rear):删除数据的一端

空队列:没有任何元素的空队

结构体

typedef struct Node{//和链表的节点一样,用来存数据
	int num;//这里是数据域,为了方便演示,数据域暂时定义为int型的数字
	struct Node *next;
}Node; 

//队链的q是一个结构体而不是指针结构体,故不用像链表一样设为*node,直接Queue q 
typedef struct Queue{
	struct Node *front,*rear;//队头和队尾
    int cnt;//队列长度
}Queue;

3.链队的基本操作

初始化队列:void InitQueue(Queue *q)

队列判空:int Empty(Queue *q)

队列长度:int Size(Queue *q)

进队:int Push(Queue *q)

出队:int Pop(Queue *q)

遍历并展示队列:void Show(Queue *q)

4.链队代码实现

【1】初始化队列

链队需要一个头节点,便于删除队列的第一个元素,同时也能在该头节点记录队列长度等数据

//初始化队链
int InitQueue(Queue *q)
{
	q->front=q->rear=new Node;
	q->front->next=NULL;//和链表一样,头节点的next指针指向空	
    q->cnt=0;//队列长度初始化为0
} 

【2】队列判空

当头指针和尾指针指在同一个节点(即头节点)时,队列为空,空则返回1,不空返回0

//判空
int QueueEmpty(Queue *q)
{
	if(q->front==q->rear)
		return 1;
	else 
		return 0;
} 

【3】队列长度

直接求cnt的值即可

//求队列的长度
int QueueSize(Queue *q)
{
	return q->cnt;
} 

【4】进栈

同等于链表的尾插法,头指针(front)不移动,尾指针(rear)指向当前尾指针的下一个元素(即新插入的元素)

//进队
int Push(Queue *q,int data)
{
	Node *node=new Node;
	node->num=data;
	node->next=NULL;
	q->rear->next=node;
	q->rear=node;	
	q->cnt++;
} 

【5】出队

删除头节点的下一个元素(即第一个元素),同链表删除第一个元素一样,但要注意,当队列仅剩一个元素时,要把尾指针(rear)指在头节点,不然尾指针会丢失

//出队
int Pop(Queue *q,int *e)
{
	Node *p=q->front->next;
	*e=p->num;
	q->front->next=p->next;
	if(p==q->rear){
		q->rear=q->front;
	}	
	delete p;
	q->cnt--;
} 

【6】遍历并输出队列

//展示
void Show(Queue *s)
{
	Node *p=s->front->next;
	while(p){
		cout<<p->num<<" ";
		p=p->next;
	}	
} 

【7】全部代码

//队列
#include<iostream>
using namespace std;

typedef struct Node{
	int num;
	struct Node *next;
}Node; 

//队链的q是一个结构体而不是指针结构体,故不用像链表一样设为*node,直接Queue q 
typedef struct Queue{
	int cnt;
	struct Node *front,*rear;
}Queue;

//初始化队链
int InitQueue(Queue *q)
{
	q->front=q->rear=new Node;
	q->front->next=NULL;
	q->cnt=0;	
} 

//判空
int QueueEmpty(Queue *q)
{
	if(q->front==q->rear)
		return 1;
	else 
		return 0;
} 

//求队列的长度
int QueueSize(Queue *q)
{
	return q->cnt;
} 



//进队
int Push(Queue *q,int data)
{
	Node *node=new Node;
	node->num=data;
	node->next=NULL;
	q->rear->next=node;
	q->rear=node;	
	q->cnt++;
} 

//出队
int Pop(Queue *q,int *e)
{
	Node *p=q->front->next;
	*e=p->num;
	q->front->next=p->next;
	if(p==q->rear){
		q->rear=q->front;
	}	
	delete p;
	q->cnt--;
} 

//展示
void Show(Queue *s)
{
	Node *p=s->front->next;
	while(p){
		cout<<p->num<<" ";
		p=p->next;
	}	
} 

int main()
{
	Queue s;
	InitQueue(&s);
	for(int i=0;i<6;i++)
	{
		Push(&s,i);
	}
	Show(&s);
	cout<<endl;
	int a;
	Pop(&s,&a);
	cout<<"a="<<a<<endl;
	cout<<"是否为空:"<<QueueEmpty(&s)<<endl;
	cout<<"队的长度:"<<QueueSize(&s)<<endl;
}

以上是全部内容,如有不对之处希望大家能在评论区指出,一起进步~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值