特点:只允许在队尾入队,队头出队,遵循先进先出原则
不能随机访问,不能随机插入
定义两个指针分别指向队头,队尾。初始化队头,队尾为0;
SeqQueue *CreateSeqQueue(int MaxLen)
{
SeqQueue *pTmpQueue = NULL;
pTmpQueue = malloc(sizeof(SeqQueue));
if (NULL == pTmpQueue)
{
return NULL;
}
pTmpQueue->Head = pTmpQueue->Tail = 0;
pTmpQueue->Len = MaxLen;
pTmpQueue->pData = malloc(sizeof(DataType) * MaxLen);
if (NULL == pTmpQueue->pData)
{
return NULL;
}
return pTmpQueue;
}
当队尾与队头相同时,队列为空;当队尾+1对队头取余等于队头时表示队列存满;
int IsEmptySeqQueue(SeqQueue *pTmpQueue)
{
return pTmpQueue->Head == pTmpQueue->Tail ? 1 : 0;
}
int IsFullSeqQueue(SeqQueue *pTmpQueue)
{
return (pTmpQueue->Tail + 1) % pTmpQueue->Len == pTmpQueue->Head ? 1 : 0;
}
int EnterSeqQueue(SeqQueue *pTmpQueue, DataType TmpData)
{
if (IsFullSeqQueue(pTmpQueue))
{
return -1;
}
pTmpQueue->pData[pTmpQueue->Tail] = TmpData;
pTmpQueue->Tail = (pTmpQueue->Tail + 1) % pTmpQueue->Len;
return 0;
}
DataType QuitSeqQueue(SeqQueue *pTmpQueue)
{
DataType TmpData;
TmpData = pTmpQueue->pData[pTmpQueue->Head];
pTmpQueue->Head = (pTmpQueue->Head + 1) % pTmpQueue->Len;
return TmpData;
}
树:只有一个前驱,但是可以有多个后继
根节点:最顶层节点(没有前驱)
分支节点:有前驱也有后继
叶子节点:没有后继的节点
层:根节点所在为第一层,每过一个分支节点,层数+1
深度: 从根节点出发到达节点的分支节点个数称为该节点的深度
高度:从叶子节点出发到该节点最大的节点个数称为该节点的高度
树的高度:整个树形结构中高度最高的节点的高度称为树的高度
树的深度:整个树形结构中深度最深的节点的深度称为树的深度
树的层数 == 树的高度 == 树的深度
满二叉树:满二叉树是一种特殊的二叉树,其中每个层级的节点数都是最大值,即每个层级都是完全填充的
完全二叉树:所有节点展开后,节点编号排列连续
TreeNode *CreateDoubleTree(int Start, int End)
{
TreeNode *pTmpTree = NULL;
pTmpTree = malloc(sizeof(TreeNode));
if (NULL == pTmpTree)
{
return NULL;
}
pTmpTree->No = Start;
pTmpTree->pChildLeft = pTmpTree->pChildRight = NULL;
if (2 * Start <= End)
{
pTmpTree->pChildLeft = CreateDoubleTree(2 * Start, End);
}
if (2 * Start + 1 <= End)
{
pTmpTree->pChildRight = CreateDoubleTree(2 * Start + 1, End);
}
return pTmpTree;
}
前序遍历,中序遍历,后续遍历
//前序遍历(根左右)
int PreOrderTreeNode(TreeNode *pRoot)
{
printf("%c ", pRoot->data);
if (pRoot->pChildLeft != NULL)
{
PreOrderTreeNode(pRoot->pChildLeft);
}
if (pRoot->pChildRight != NULL)
{
PreOrderTreeNode(pRoot->pChildRight);
}
return 0;
}
//中序遍历(左根右)
int InOrderTreeNode(TreeNode *pRoot)
{
if (pRoot->pChildLeft != NULL)
{
InOrderTreeNode(pRoot->pChildLeft);
}
printf("%c ", pRoot->data);
if (pRoot->pChildRight != NULL)
{
InOrderTreeNode(pRoot->pChildRight);
}
return 0;
}
//后续遍历(左右根)
int LastOrderTreeNode(TreeNode *pRoot)
{
if (pRoot->pChildLeft != NULL)
{
LastOrderTreeNode(pRoot->pChildLeft);
}
if (pRoot->pChildRight != NULL)
{
LastOrderTreeNode(pRoot->pChildRight);
}
printf("%c ", pRoot->data);
return 0;
}
层序遍历,前序遍历,中序遍历
//层序遍历
int LayerOrderBinTree(TreeNode *pRoot)
{
struct list_head head;
Que_t *pTmpNode = NULL;
Que_t *pFreeNode = NULL;
//树形结构为NULL直接返回
if (pRoot == NULL)
{
return -1;
}
//初始化队列
INIT_LIST_HEAD(&head);
//申请一个节点(将树形结构地址放入链表中)
pTmpNode = malloc(sizeof(Que_t));
if (pTmpNode == NULL)
{
return -1;
}
pTmpNode->pData = pRoot;
//入队
list_add_tail(&pTmpNode->node, &head);
//只要队列不为NULL,出队一个元素,打印该元素,左右孩子不为NULL,入队
while (!list_empty(&head))
{
//获得队头元素
pFreeNode = list_entry(head.next, Que_t, node);
printf("%c ", pFreeNode->pData->data);
//队头元素的左孩子入队
if (NULL != pFreeNode->pData->pChildLeft)
{
pTmpNode = malloc(sizeof(Que_t));
if (NULL == pTmpNode)
{
return -1;
}
pTmpNode->pData = pFreeNode->pData->pChildLeft;
list_add_tail(&pTmpNode->node, &head);
}
//队头元素的右孩子入队
if (NULL != pFreeNode->pData->pChildRight)
{
pTmpNode = malloc(sizeof(Que_t));
if (NULL == pTmpNode)
{
return -1;
}
pTmpNode->pData = pFreeNode->pData->pChildRight;
list_add_tail(&pTmpNode->node, &head);
}
//队头元素出队
list_del(&pFreeNode->node);
//释放该节点
free(pFreeNode);
}
return 0;
}
//前序遍历(非递归)
int PreOrderTreeNodeByStack(TreeNode *pRoot)
{
struct list_head stack;
TreeNode *pTmpNode = NULL;
Que_t *pFreeNode = NULL;
Que_t *pHeadNode = NULL;
//树型结构为NULL时返回
if (NULL == pRoot)
{
return -1;
}
//初始栈
INIT_LIST_HEAD(&stack);
//定义指针指向根
pTmpNode = pRoot;
//遍历树型结构,当栈为空时结束
while (1)
{
//当根不为空时,循环
while (pTmpNode != NULL)
{
//申请空间
pHeadNode = malloc(sizeof(Que_t));
if (pHeadNode == NULL)
{
return -1;
}
//将根指针存入
pHeadNode->pData = pTmpNode;
//加入栈
printf("%c ", pHeadNode->pData->data);
list_add(&pHeadNode->node, &stack);
//当左孩子为空时结束
pTmpNode = pTmpNode->pChildLeft;
}
if (list_empty(&stack))
{
break;
}
//出栈
pFreeNode = list_entry(stack.next, Que_t, node);
list_del(&pFreeNode->node);
//做孩子为空时判断右孩子
pTmpNode = pFreeNode->pData->pChildRight;
//释放空间
free(pFreeNode);
}
return 0;
}
//中序遍历(非递归)
int InOrderTreeNodeByStack(TreeNode *pRoot)
{
struct list_head stack;
Que_t *pNewNode = NULL;
Que_t *pFreeNode = NULL;
TreeNode *pTmpNode = NULL;
if (NULL == pRoot)
{
return -1;
}
INIT_LIST_HEAD(&stack);
pTmpNode = pRoot;
while (1)
{
while (pTmpNode != NULL)
{
pNewNode = malloc(sizeof(Que_t));
if (NULL == pNewNode)
{
return -1;
}
pNewNode->pData = pTmpNode;
list_add(&pNewNode->node, &stack);
pTmpNode = pTmpNode->pChildLeft;
}
if (list_empty(&stack))
{
break;
}
pFreeNode = list_entry(stack.next, Que_t, node);
list_del(&pFreeNode->node);
printf("%c ", pFreeNode->pData->data);
pTmpNode = pFreeNode->pData->pChildRight;
free(pFreeNode);
}
return 0;
}
树的高度=层数=深度
int GetBinTreeHeigh(TreeNode *pRoot)
{
int LeftHeigh = 0;
int RightHeigh = 0;
if (NULL == pRoot)
{
return 0;
}
LeftHeigh = GetBinTreeHeigh(pRoot->pChildLeft);
RightHeigh = GetBinTreeHeigh(pRoot->pChildRight);
return (LeftHeigh > RightHeigh ? LeftHeigh : RightHeigh) + 1;
}
//创建非完全二叉树
TreeNode *CreateIncompleteBinTree(void)
{
char pTmpData = 0;
TreeNode *pTmpNode = NULL;
scanf(" %c", &pTmpData);
if ('#' == pTmpData)
{
return NULL;
}
else
{
pTmpNode = malloc(sizeof(TreeNode));
if (pTmpNode == NULL)
{
return NULL;
}
pTmpNode->data = pTmpData;
pTmpNode->pChildLeft = CreateIncompleteBinTree();
pTmpNode->pChildRight = CreateIncompleteBinTree();
}
return pTmpNode;
}