队列--栈--二叉树的基本操作和面试题
Queue
//#ifndef __TREE_H__
//#define __TREE_H__
#pragma once
extern struct BinTreeNode;
typedef struct BinTreeNode* QueueDataType;
typedef struct QueueNode
{
QueueDataType _data;
struct Node* _pNext;
}QueueNode, *PQueueNode;
typedef struct Queue
{
PQueueNode _pHead;
PQueueNode _pTail;
}Queue;
// 队列的初始化
void QueueInit(Queue* q);
// 入队列
void QueuePush(Queue* q, QueueDataType data);
// 出队列
void QueuePop(Queue* q);
// 取队头元素
QueueDataType QueueFront(Queue* q);
// 取队尾元素
QueueDataType QueueBack(Queue* q);
// 获取队列中元素的个数
int QueueSize(Queue* q);
// 检测队列是否为空
int QueueEmpty(Queue* q);
//#endif
Linkstack.h
#ifndef __STACK_H__
#define __STACK_H__
#include<stdlib.h>
#include<stdio.h>
#include<malloc.h>
extern struct BinTreeNode;
typedef struct BinTreeNode* DataType;
typedef struct StackNode
{
DataType data;
struct StackNode * next;
}StackNode,*pStackNode;
typedef struct LinkStack{
StackNode *top;//栈顶指针
int stackSize;//栈的当前容量
}LinkStack,*pLinkStack;
void StackInit(LinkStack *s);
// 入栈
void StackPush(pLinkStack s, DataType data);
// 出栈
void StackPop(pLinkStack s);
// 获取栈顶元素
DataType StackTop(pLinkStack s);
// 有效元素的个数
int StackSize(pLinkStack s);
// 检测栈是否为空
int StackEmpty(pLinkStack s);
//打印
void PrintfLinkStack(LinkStack s);
#endif
Queue.c
#include "Queue.h"
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>
// 队列的初始化
void QueueInit(Queue* q){
assert(q);
q->_pHead = NULL;
q->_pTail = NULL;
}
// 检测队列是否为空
int QueueEmpty(Queue* q){
assert(q);
if (q->_pHead == NULL)
return 1;
return 0;
}
PQueueNode Queue_BuyNode(QueueDataType data){
PQueueNode pNewNode = NULL;
pNewNode = (PQueueNode)malloc(sizeof(QueueNode));
if (pNewNode == NULL)
return NULL;
pNewNode->_data = data;
pNewNode->_pNext = NULL;
return pNewNode;
}
// 入队列
void QueuePush(Queue* q, QueueDataType data){
assert(q);
PQueueNode pNewNode = NULL;
pNewNode = Queue_BuyNode(data);
if (QueueEmpty(q))
{
q->_pHead = pNewNode;
q->_pTail = pNewNode;
}
else{ q->_pTail->_pNext = pNewNode;
q->_pTail = q->_pTail->_pNext;
}
}
// 出队列
void QueuePop(Queue* q){
PQueueNode pcur = NULL;
assert(q);
if (QueueEmpty(q))
return;
pcur = q->_pHead;
q->_pHead = q->_pHead->_pNext;
free(pcur);
}
// 取队头元素
QueueDataType QueueFront(Queue* q){
assert(q);
if (QueueEmpty(q))
return NULL;
return (q->_pHead)->_data;
}
// 取队尾元素
QueueDataType QueueBack(Queue* q){
assert(q);
if (QueueEmpty(q))
return NULL;
return (q->_pTail)->_data;
}
// 获取队列中元素的个数
int QueueSize(Queue* q){
int count = 1;
assert(q);
if (QueueEmpty(q))
return 0;
while (q->_pTail!=q->_pHead)
{
count++;
q->_pHead = q->_pHead->_pNext;
}
return count;
}
LinkStack.c
#include "LinkStack.h"
void StackInit(LinkStack *s){
pStackNode p = NULL;
p = (pStackNode)malloc(sizeof(StackNode));
if (p == NULL)
return;
p->next = NULL;
s->top = p;
s->stackSize = 0;
}
//栈顶--->1--->2--->3---栈底--->NULL
// 入栈
void StackPush(pLinkStack s, DataType data){
pStackNode newnode = NULL;
newnode = (pStackNode)malloc(sizeof(StackNode));
if (newnode == NULL)return;
newnode->data = data;
newnode->next = s->top;
s->top = newnode;
(s->stackSize)++;
//printf("%d ", top->data);
}
// 出栈
void StackPop(pLinkStack s){
pStackNode pcur;
if(StackEmpty(s))
return;
pcur = s->top;
s->top = pcur->next;
free(pcur);
(s->stackSize)--;
//printf("%d ", (top)->data);
}
// 获取栈顶元素
DataType StackTop(pLinkStack s){
if (s->top != NULL)
return s->top->data;
return NULL;
}
// 有效元素的个数
int StackSize(pLinkStack s)
{
return s->stackSize;
}
// 检测栈是否为空
int StackEmpty(pLinkStack s){
return s->stackSize == 0;
}
void PrintfLinkStack(LinkStack s){
pStackNode pcur = NULL;
if (s.stackSize== NULL||s.top==NULL)
return;
pcur = s.top;
while (pcur->next)
{
printf("%d ", pcur->data);
pcur = pcur->next;
}
}
BinTree.h
#ifndef __TREE_H__
#define __TREE_H__
#include "LinkStack.h"
#include<assert.h>
#include<malloc.h>
#include<stdlib.h>
#include<stdio.h>
typedef char Bin_DataType;
typedef struct BinTreeNode
{
struct BinTreeNode *_pLeft;
struct BinTreeNode *_pRight;
Bin_DataType _data;
}Node, *pNode;
void CreateBinTree(pNode *pRoot, char array[], int size, int *index, Bin_DataType Nouse);
void Print_PreBinTree(pNode pRoot);
void Print_MidBinTree(pNode pRoot);
void Print_FinBinTree(pNode pRoot);
void Print_PreBinTreeNor(pNode pRoot);
void Print_FinBinTreeNor(pNode pRoot);
void Print_LevelBinTree(pNode pRoot);
// 二叉树的销毁
void DetroyBinTree(pNode* pRoot);
//二叉树的复制
pNode CopyBinTree(pNode pRoot);
// 二叉树的镜像---非递归
void MirrorBinTreeNor(pNode pRoot);
// 二叉树的镜像---递归
void MirrorBinTree(pNode pRoot);
// 求二叉树中结点的个数
int BinTreeSize(pNode pRoot);
// 求二叉树中叶子结点的个数
int BinTreeLeaf(pNode pRoot);
// 求二叉树中第K层结点的个数
int BinTreeKLevelNode(pNode pRoot, int K);
// 求二叉树的高度
int BinTreeHeight(pNode pRoot);
// 在二叉树中查找值为data的结点,找到返回该结点,否则返回空
pNode Find(pNode pRoot, Bin_DataType data);
// 检测一个节点是否在二叉树中
int IsNodeInBinTree(pNode pRoot, pNode ret);
// 检测一棵树是否为完全二叉树
int IsCompleteBinTree(pNode pRoot);
#endif
BinTree.c
#include "BinTree.h"
#include "Queue.h"
pNode BuyNode(Bin_DataType data){
pNode pNewNode;
pNewNode = (pNode)malloc(sizeof(Node));
pNewNode->_data = data;
pNewNode->_pLeft = NULL;
pNewNode->_pRight = NULL;
return pNewNode;
}
//创建二叉树
void CreateBinTree(pNode *pRoot, char array[], int size, int *index,Bin_DataType Nouse){
assert(pRoot);
if ((*index)<size&&array[*index]!=Nouse)
{
*pRoot = BuyNode(array[*index]);
++(*index);
CreateBinTree(&((*pRoot)->_pLeft), array, size, index,Nouse);
++(*index);
CreateBinTree(&((*pRoot)->_pRight), array, size, index,Nouse);
}
}
// 二叉树拷贝
pNode CopyBinTree(pNode pRoot){
pNode pNewRoot;
if(pRoot == NULL)
return NULL;
pNewRoot = BuyNode(pRoot->_data);
if (pNewRoot)
{
if (pRoot->_pLeft)
pNewRoot->_pLeft = CopyBinTree(pRoot->_pLeft);
if (pRoot->_pRight)
pNewRoot->_pRight = CopyBinTree(pRoot->_pRight);
}
return pNewRoot;
}
//打印二叉树
//---------前序遍历递归-------根节点-左子树-右子树
void Print_PreBinTree(pNode pRoot){
if (pRoot == NULL)
return;
printf("%c ",pRoot->_data);
Print_PreBinTree(pRoot->_pLeft);
Print_PreBinTree(pRoot->_pRight);
}
//---------前序遍历非递归-------根节点-左子树-右子树(利用栈实现非递归--把递归改为循环)
void Print_PreBinTreeNor(pNode pRoot){
LinkStack s;
pNode pcur=NULL;
if (pRoot == NULL)
return;
StackInit(&s);
StackPush(&s,pRoot);
while (!StackEmpty(&s))
{
pcur= StackTop(&s);
printf("%c ",pcur->_data);
StackPop(&s);
if (pcur->_pRight)
{
StackPush(&s, pcur->_pRight);
}
if (pcur->_pLeft)
{
StackPush(&s, pcur->_pLeft);
}
}
}
//---------中序遍历-------
void Print_MidBinTree(pNode pRoot){
if (pRoot == NULL)
return;
Print_MidBinTree(pRoot->_pLeft);
printf("%c ", pRoot->_data);
Print_MidBinTree(pRoot->_pRight);
}
// 中序遍历---非递归--左子树-根节点-右子树(利用栈实现非递归--把递归改为循环)
void Print_MidBinTreeNor(pNode pRoot){
LinkStack s;
pNode pcur = NULL;
if (pRoot == NULL)
return;
StackInit(&s);
pcur = pRoot;
while (pcur||!StackEmpty(&s))
{
while (pcur)
{
StackPush(&s,pcur);
pcur = pcur->_pLeft;
}
pcur = StackTop(&s);
printf("%c ",pcur->_data );
StackPop(&s);
pcur = pcur->_pRight;
}
}
//---------后序遍历-------
void Print_FinBinTree(pNode pRoot){
if (pRoot == NULL)
return;
Print_FinBinTree(pRoot->_pLeft);
Print_FinBinTree(pRoot->_pRight);
printf("%c ", pRoot->_data);
}
// 后序遍历---非递归--左子树-右子树-根节点(利用栈实现非递归--把递归改为循环)
void Print_FinBinTreeNor(pNode pRoot){
LinkStack s;
pNode pcur = NULL;
pNode ret = NULL;
int flag = 1;
if (pRoot == NULL)
return;
StackInit(&s);
pcur = pRoot;
if (pcur)
{
do
{
while (pcur)
{
StackPush(&s,pcur);
pcur = pcur->_pLeft;
}
flag = 1;
ret = NULL;
while (!StackEmpty(&s)&&flag==1)
{
pcur = StackTop(&s);
if (pcur->_pRight==ret)
{
printf("%c ", pcur->_data);
ret = pcur;
StackPop(&s);
}
else
{
pcur = pcur->_pRight;
flag = 0;
}
}
} while (!StackEmpty(&s));
}
}
// 层序遍历-----使用队列---先进先出
void Print_LevelBinTree(pNode pRoot){
Queue Que;
pNode ret = NULL;
if (pRoot == NULL)
return;
QueueInit(&Que);
QueuePush(&Que, pRoot);
while (!QueueEmpty(&Que))
{
ret = QueueFront(&Que);
printf("%c ", ret->_data);
QueuePop(&Que);
if (ret->_pLeft)
{
QueuePush(&Que, ret->_pLeft);
}
if (ret->_pRight)
{
QueuePush(&Que,ret->_pRight);
}
}
}
// 二叉树的销毁
void DetroyBinTree(pNode* pRoot){
assert(pRoot);
if (*pRoot)
{
DetroyBinTree(&(*pRoot)->_pLeft);
DetroyBinTree(&(*pRoot)->_pRight);
free(*pRoot);
(*pRoot) = NULL;
}
}
// 二叉树的镜像---非递归---利用层序遍历
void MirrorBinTreeNor(pNode pRoot){
Queue Que;
pNode ret = NULL;
pNode temp = NULL;
if (pRoot == NULL)
return;
QueueInit(&Que);
QueuePush(&Que, pRoot);
while (!QueueEmpty(&Que))
{
ret = QueueFront(&Que);
temp = ret->_pLeft;
ret->_pLeft = ret->_pRight;
ret->_pRight = temp;
if (ret->_pLeft)
{
QueuePush(&Que, ret->_pLeft);
}
if (ret->_pRight)
{
QueuePush(&Que, ret->_pRight);
}
QueuePop(&Que);
}
}
// 二叉树的镜像---递归----利用前序遍历
void MirrorBinTree(pNode pRoot){
pNode temp = NULL;
if (pRoot == NULL)
return;
temp = pRoot->_pLeft;
pRoot->_pLeft = pRoot->_pRight;
pRoot->_pRight = temp;
MirrorBinTree(pRoot->_pLeft);
MirrorBinTree(pRoot->_pRight);
}
// 求二叉树中结点的个数
int BinTreeSize(pNode pRoot){
if (pRoot == NULL)
return 0;
int left = BinTreeSize(pRoot->_pLeft);
int right = BinTreeSize(pRoot->_pRight);
return left + right+1;
}
// 求二叉树中叶子结点的个数
int BinTreeLeaf(pNode pRoot){
if (pRoot == NULL)
return 0;
if (pRoot->_pLeft == NULL&&pRoot->_pRight == NULL)
return 1;
int left = BinTreeLeaf(pRoot->_pLeft);
int right = BinTreeLeaf(pRoot->_pRight);
return left + right;
}
// 求二叉树中第K层结点的个数
int BinTreeKLevelNode(pNode pRoot, int K){
if (pRoot == NULL || K <= 0)
return 0;
if (K == 1)
return 1;
int left = BinTreeKLevelNode(pRoot->_pLeft, K - 1);
int right =BinTreeKLevelNode(pRoot->_pRight, K - 1);
return left + right;
}
// 求二叉树的高度
int BinTreeHeight(pNode pRoot){
if (pRoot == NULL)
return 0;
if (pRoot->_pLeft == NULL&&pRoot->_pRight == NULL)
return 1;
int left = BinTreeHeight(pRoot->_pLeft);
int right = BinTreeHeight(pRoot->_pRight);
return left >= right ? left+1 : right+1;
}
// 在二叉树中查找值为data的结点,找到返回该结点,否则返回空
pNode Find(pNode pRoot, Bin_DataType data){
if (pRoot == NULL)
return NULL;
if (pRoot->_data == data)
return pRoot;
Find(pRoot->_pLeft, data);
if (Find(pRoot->_pLeft, data) == NULL)
{
Find(pRoot->_pRight, data);
}
}
// 检测一个节点是否在二叉树中
int IsNodeInBinTree(pNode pRoot, pNode ret){
if (pRoot == NULL)
return NULL;
if (pRoot == ret)
return 1;
if (IsNodeInBinTree(pRoot->_pLeft, ret)==0)
{
IsNodeInBinTree(pRoot->_pRight, ret);
}
}
// 检测一棵树是否为完全二叉树
int IsCompleteBinTree(pNode pRoot){
Queue Que;
int flag = 0;
pNode ret = NULL;
if (pRoot == NULL)
return 0;
QueueInit(&Que);
QueuePush(&Que, pRoot);
while (!QueueEmpty(&Que))
{
ret = QueueFront(&Que);
QueuePop(&Que);
if (flag)
{
if (ret->_pLeft || ret->_pRight )
return 0;
}
else{
if (ret->_pLeft&&ret->_pRight)
{
QueuePush(&Que, ret->_pLeft);
QueuePush(&Que, ret->_pRight);
}
else if (ret->_pRight)
return 0;
else if (ret->_pLeft)
{
QueuePush(&Que, ret->_pLeft);
flag = 1;
}
else
flag = 1;
}
}
}