数据结构栈和队列的使用


这是我最近学习的笔记,还会持续更新,如果兄弟们看见那里需要修改的地方请告诉我

前述:栈和队列是一种特殊的线性结构,是连续存储或离散存储的一种应用

线性结构的应用------栈

定义:一种可以实现的先进后出存储结构,类似于箱子

在这里插入图片描述
分类:1 .静态栈 2. 动态栈
算法:1.出栈 2. 压栈
应用:1.函数调用 2. 中断 3.表达式求值 4. 内存分配 5.缓冲处理 6.迷宫

动态栈的分配

int main(void)
{
  int p;                          
  int * m = (int *)malloc(100);
}

如静态变量p和m是在栈中分配,有操作系统自动分配和释放。而(int *)malloc(100);执行后,将在堆中分配一块100字节的内存,由程序员手动分配。

栈的结构示意图
在这里插入图片描述
具体实现(遵循先进后出的原则)
点击查看十进制转八进制源码
1.结构体定义

typedef struct Node
{
	int data;//数据域
	struct Node *pNext;//指针域
}NODE,*PNODE;
typedef struct Stack
{
	PNODE pTop;//头节点
	PNODE pBottom;//尾节点
}STACK,*PSTACK;

2.初始化

//初始化
void InitCreat(PSTACK pHead)
{

	pHead->pTop = (PNODE)malloc(sizeof(NODE));
	if (NULL == pHead->pTop)
	{
		printf("分配内存失败");
		exit(-1);
	}
	pHead->pBottom= pHead->pTop;//不能颠倒,记住
	pHead->pTop->pNext = NULL;
}

3.入栈

void Push(PSTACK pHead,int val)
{
	PNODE pNew = (PNODE)malloc(sizeof(NODE));
	if (NULL == pNew)
	{
		printf("分配内存失败");
		exit(-1);
	}
	pNew->data = val;
	pNew->pNext = pHead->pTop;
	pHead->pTop  = pNew;

}

4.出栈

//将获得的值存入到地址val中,以便于一个个输出
void pop(PSTACK pHead, int *val)
{
	PNODE p = pHead->pTop;
	if (empty(pHead))
	{
		return;
	}
	else
	{
		*val= p->data;
		pHead->pTop = p->pNext;
		free(p);
		p = NULL;
		return;
	}
}

线性结构的应用------队列

定义
一种可以实现“先进先出”的存储结构

在这里插入图片描述
分类
链式队列: -----用链表实现(比较简单)
静态队列: -----用数组实现 静态队列通常都必须是循环队列
应用
所有和时间有关的事件都有队列的影子

具体实现:链式队列插入删除操作

//1.create创建链表  2.traverse遍历链表  3.empty判断是否为空 4.链表长度length  7.排序sort 5.插入insert 6。删除delete
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct Node{
	int data;//数据域
	struct Node *pNext;//指针域
}NODE,*PNODE;

PNODE create_list();//创建链表
void traverse_list(PNODE pHead);//遍历链表
void sort_list(PNODE);//排序
int length_list(PNODE pHead);
bool delete_list(PNODE pHead, int pos, int * pVal);  //删除链表第pos个节点,并将删除的结点的值存入pVal所指向的变量中,  并且pos的值是从1开始
bool is_empty(PNODE pHead);//判断是否为空
bool insert_list(PNODE pHead,int pos,int val);//插入

int main(void){
	PNODE pHead=NULL;//等价于 struct Node * pHead = NULL
	pHead=create_list();//create_list()功能:创建一个非循环单链表,并将该链表的头结点的地址付给pHead
	traverse_list(pHead);
	int len = length_list(pHead);
    printf("链表长度%d\n", len);
    sort_list(pHead);
	traverse_list(pHead);
	printf("请输入你要在第几行插入数字几:");
	int pos,val;
	scanf("%d %d",&pos,&val);
	insert_list(pHead,pos,val);
	traverse_list(pHead);
	if ( delete_list(pHead, 4, &val) )
	{
		printf("删除成功,您删除的元素是: %d\n", val);
	}
	else
	{
		printf("删除失败!您删除的元素不存在!\n");
	}

	traverse_list(pHead);
	return 0;
}

PNODE create_list(){
	int len;
	int val;
	PNODE pHead=(PNODE)malloc(sizeof(NODE));//创建头结点

	if(NULL==pHead){
		printf("分配内存失败\n");
		exit(-1);//终止程序
	}

	PNODE pTail=pHead;//pTail指向头结点
	pTail->pNext=NULL;//头结点指针域清空
	printf("请输入你要的节点个数");
	scanf("%d",&len);

	for(int i=0;i<len;i++){
		PNODE pNew = (PNODE)malloc(sizeof(NODE));//不断循环产生新节点
		printf("第%d个节点数值是:",i+1);
		scanf("%d",&val);
		if (NULL == pNew)
		{
			printf("分配内存失败\n");
			exit(-1);
		}
		pNew->data=val;//将val的值赋值给data
		pTail->pNext=pNew;//pTail等于节点
		pNew->pNext=NULL;
		pTail=pNew;//指向下一个节点
	}

	return pHead;
}

void traverse_list(PNODE pHead){
	PNODE p=pHead->pNext;
	while(p!=NULL){
		printf("%d  ",p->data);
			p=p->pNext;
	}
	printf("\n");
	return;
}
bool is_empty(PNODE pHead){
	if(NULL==pHead->pNext){
		return true;
	}
	else{
		return false;
	}
}
int length_list(PNODE pHead){
	PNODE p=pHead->pNext;
	int len=0;
	while(p!=NULL){
		len++;
		p=p->pNext;
	}
	return len;
}
void sort_list(PNODE pHead){
	int i,j,t;
	PNODE p,q;
	int len=length_list(pHead);
	for(i=0,p=pHead->pNext;i<len-1;i++,p=p->pNext){
		for(j=i+1,q=p->pNext;j<len;j++,q=q->pNext){
			if(p->data>q->data){//类似于数组:  a[i] > a[j]
				t=p->data;
				p->data=q->data;
				q->data=t;
			}
		}
	}
		return;
}
bool insert_list(PNODE pHead,int pos,int val){
	PNODE p=pHead;
	int i=0;
	while(p!=NULL&&i<pos-1){
		p=p->pNext;
		i++;
	}
	if(p==NULL||i>pos-1){
		return false;
	}
	PNODE pNew=(PNODE)malloc(sizeof(NODE));//
	if(pNew==NULL){
		printf("分配失败!");
		exit(-1);//
	}
	PNODE q=p->pNext;
	p->pNext=pNew;
	pNew->pNext=q;
	pNew->data=val;
	return true;
}
bool delete_list(PNODE pHead, int pos, int * pVal)
{
	int i = 0;
	PNODE p = pHead;

	while (NULL!=p->pNext && i<pos-1)
	{
		p = p->pNext;
		++i;
	}

	if (i>pos-1 || NULL==p->pNext)
		return false;
	
	PNODE q = p->pNext;  //q指向待删除的节点
	*pVal = q->data;  

	//指向下个节点的节点,就是节点删除了,需要跳过它指向下一个,达到线性关系
	p->pNext = p->pNext->pNext;
	
	//释放q节点所占用的内存
	free(q);
	q = NULL;
	
	return true;

}

循环队列的讲解
(1)静态队列为什么必须是循环队列
在这里插入图片描述

  1. 队列初始化front(首部)和rear(尾部)的值都为零
  2. 队列非空 :(1)front代表的是队列的第一个元素(2)rear代表的是队列的最后一个有效元素的下一个元素
  3. 队列为空frontreal的值相等,但不一定为零
  4. 入队rear = (rear+1)%数组的长度
  5. 出队Front =(front +1)%数组的长度
  6. 判断队满:(rear+1)%数组长度==front

具体实现

# include <stdio.h>
# include <malloc.h>

typedef struct Queue
{
	int * pBase;
	int front;
	int rear;
}QUEUE;  

void init(QUEUE *);
bool en_queue(QUEUE *, int val);  //入队
void traverse_queue(QUEUE *);
bool full_queue(QUEUE *);
bool out_queue(QUEUE *, int *);
bool emput_queue(QUEUE *);

int main(void)
{
	QUEUE Q;
	int val;

	init(&Q);
	en_queue(&Q, 1);
	en_queue(&Q, 2);
	en_queue(&Q, 3);
	en_queue(&Q, 4);
	en_queue(&Q, 5);
	en_queue(&Q, 6);
	en_queue(&Q, 7);
	en_queue(&Q, 8);

	traverse_queue(&Q);

	if ( out_queue(&Q, &val) )
	{
		printf("出队成功,队列出队的元素是: %d\n", val);
	}
	else
	{
		printf("出队失败!\n");
	}
	traverse_queue(&Q);

	return 0;
}

void init(QUEUE *pQ)
{
	pQ->pBase = (int *)malloc(sizeof(int) * 6);
	pQ->front = 0;
	pQ->rear = 0;
}

bool full_queue(QUEUE * pQ)
{
	if ( (pQ->rear + 1) % 6 == pQ->front  )//判断队列是否满
		return true;
	else
		return false;
}

bool en_queue(QUEUE * pQ, int val)
{
	if ( full_queue(pQ) )
	{
		return false;
	}
	else
	{
		pQ->pBase[pQ->rear] = val;
		pQ->rear = (pQ->rear+1) % 6;

		return true;
	}
}

void traverse_queue(QUEUE * pQ)
{
	int i = pQ->front;

	while (i != pQ->rear)
	{
		printf("%d  ", pQ->pBase[i]);
		i = (i+1) % 6;
	}
	printf("\n");

	return;
}

bool emput_queue(QUEUE * pQ)
{
	if ( pQ->front == pQ->rear )
		return true;
	else
		return false;
}

bool out_queue(QUEUE * pQ, int * pVal)
{
	if ( emput_queue(pQ) )
	{
		return false;
	}
	else
	{
		*pVal = pQ->pBase[pQ->front];
		pQ->front = (pQ->front+1) % 6;

		return true;
	}
}
发布了13 篇原创文章 · 获赞 147 · 访问量 2045

猜你喜欢

转载自blog.csdn.net/weixin_46654114/article/details/105214631