数据结构——栈 和 队列

  • 一个顺序的数据链表,插入和删除只能在一端完成,栈只是一种思想,线性表只是实现这种思想的手段之一,也可以用数组等方法来实现
  • 压栈:向栈里面添加数据。
  • 弹栈:在栈里面向外取出数据。
  • 作用:用栈的来实现递归。
    递归的实现就是压栈和弹栈的过程,但是递归的层数不能太大,可能会爆栈。
    笔试面试中二叉树的便利必须用栈来实现
  • n个不同的元素进栈出栈,元素不用会有1/(n+1)Cn,2n中不同的排列次数
  • stack 创建一个空投
  • IsEmpt 判断栈里有没有元素
  • Push 压栈
  • FreeStach 释放栈
  • Pop 获取栈顶节点,并删除
  • Top 获取栈顶节点,不删除

栈的定义

struct Node
{
	int a;
	struct Node* PNext;
	struct Node* Pre;
};

stack 创建空投

  1. 栈不满的时候,栈顶指针加一
// stack 创建空投
struct Node* Stack()
{
	// 申请节点
	struct Node* pTemp = (struct Node*)malloc(sizeof(struct Node));
	if (pTemp == NULL)
	{
		return pTemp;
	}
	pTemp->a = -1;
	pTemp->PNext = pTemp;
	pTemp->Pre = pTemp;

	return pTemp;
}

IsEmpty判断有没有元素

// IsEmpty判断有没有元素
_Bool IsEmpty(struct Node* pStack)
{
	if (pStack->PNext == pStack)
		return 1;
	else
		return 0;


}

压栈


//压栈 Push
void Push(struct Node* pStack, int a)
{
	if (NULL == pStack)
	{
		return;
	}
	// 结点申请
	struct Node* pTemp = (struct Node*)malloc(sizeof(struct Node));
	if(NULL==pTemp)
	{
		return;
	}
	// 成员节点赋值
	pTemp->a = a;
	pTemp->PNext = NULL;
	pTemp->Pre = NULL;

	// 节点连接  先连后断
	pTemp->Pre = pStack->Pre;
	pTemp->PNext = pStack;
	pStack->Pre->PNext = pTemp;
	pStack->Pre = pTemp;


}

弹栈 FreeStack


// 弹栈 FreeStack
void FreeStack(struct Node** pStack) 
// 这里要修改指针的指向要传递二级指针
{
	if (*pStack == NULL)
		return;
	struct Node* pTemp = *pStack;
	do
	{
		struct Node* pT = pTemp;
		pTemp = pTemp->PNext;
		free(pT);
	} while (pTemp != *pStack);

	*pStack = NULL;

}

Top 获取栈顶结点

// Top 获取栈顶结点
struct Node* Top(struct Node* pStack)
{
	if (IsEmpty(pStack))
	{
		return NULL;
	}
	return pStack->Pre;
}

// 删除栈顶结点
void Pop(struct Node* pStack)
{
	if (IsEmpty(pStack))
	{
		return ;
	}
	// 记录要删除的结点
	struct Node* pT = pStack->Pre;
	pT->Pre->PNext = pStack;
	pStack->Pre = pT->Pre;

	free(pT);
}

队列

  • 通过线性表的插入删除操作在异端完成(在一段近在另一端出)

    1. 头删除,尾添加 -> 各种链表都可以
    2. 头添加,尾删除 -> 双向链表和双向顺环链表都可以;单项链表不太适合,效率不行,尾部还得循环栈
    3. 入队序列是什么,出度序列就是什么
  • Queue :创建队列的空头

  • IsEmpty : 判断是否为NULL

  • Front :队头结点

  • Back :队尾结点

  • Push :入队

  • Pop :出队

创建空队列

// 创建空头队列
struct Node* Queue()
{
	struct Node* pT = (struct Node*)malloc(sizeof(struct Node));
	
	if(pT==NULL)
	{
		return NULL;
	}
	pT->a = -1;  // 随便
	pT->pNext = pT;
	pT->Per = pT;

	return pT;
	
}

判 空

空列表染回1,非空返回0

// 判断是否为空
bool IsEmpty(struct Node* pQueue)
{
	if (pQueue == NULL || pQueue->pNext == pQueue) // 传递参数出错或者结构为空
	{
		return true;
	}
	else
	{
		return false;
	}
}

// 
struct Node* Front(struct Node* pQueue)
{
	if (IsEmpty(pQueue))
	{
		return NULL;
	}
	return pQueue->Per;
}

// 
struct Node* Back(struct Node* pQueue)
{
	if (IsEmpty(pQueue))
	{
		return NULL;
	}
	return pQueue->pNext;
}

入队

// Push
void Push(struct Node* pQueue, int a)
{
	if (pQueue == NULL)
	{
		return;
	}
	//申请空间
	struct Node* pT = (struct Node*)malloc(sizeof(struct Node));
	
	if (pT == NULL)
	{
		return;
	}

	//成员赋值
	pT->a = a; 
	pT->pNext = NULL;
	pT->Per = NULL;
	//连接头添加
	pT->pNext = pQueue->pNext;
	pT->Per = pQueue;

	pQueue->pNext->Per = pT;
	pQueue->pNext = pT;
}

出队

// Pop
void Pop(struct Node* pQueue)
{
	if (IsEmpty(pQueue))
	{
		return;
	}
	// 记录
	struct Node* pT = pQueue->Per;
	pT->Per->pNext = pQueue;
	pQueue->Per = pT->Per;

	free(pT);
}

释放队列

// 释放整个队列
void Free(struct Node** pQueue)
{
	if (IsEmpty(*pQueue))
	{
		free(*pQueue);
		*pQueue = NULL;
		return;
	}
	struct Node* pT = *pQueue;
	do
	{
		struct Node* pTemp = pT;
		pT = pT->pNext;
		free(pTemp);
	} while (pT != *pQueue);
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值