问题:为什么要构建链式结构的二叉树?
为了存储非完全二叉树结构,即不规则的二叉树结构,中间节点可能并没有存储元素。
例如:
注意:普通二叉树的增删查改没有意义。 学习二叉树的链式结构,是为了能够更好地控制它的结构,为后续学习更复杂的搜索二叉树打基础。
二叉树的遍历(Traversal)是按照某种特定的规则,依次对二叉树中的节点进行相应的操作,并且每个节点只操作一次。访问节点所做的操作依赖于具体的应用问题。 遍历是二叉树最重要的运算之一,也是二叉树进行其它运算的基础。
二叉树的遍历分为两类,一类是 深度优先遍历,一类是 广度优先遍历。
深度优先遍历: 前序遍历、中序遍历和后序遍历。因为前序遍历是最先访问根节点,再往深处遍历,所以最符合深度优先。
广度优先遍历:层序遍历。
任何一个二叉树,都要看做三个部分:根节点、左子树、右子树。
可以看出,二叉树是一种递归结构,因此二叉树的操作基本都是按照递归实现的。
前序遍历 先遍历根节点,再遍历左子树,最后遍历右子树。
思路:先遍历根节点,再遍历左子树,左子树又可以分解为:根节点、左子树和右子树,直到将所有左子树的部分遍历完,然后遍历右子树,右子树又可以分解为:根节点、左子树和右子树。
中序遍历 先遍历左子树,再遍历根节点,最后遍历右子树。
思路:先遍历左子树,左子树又可以分解为:左子树、根节点和右子树,直到将所有左子树的部分遍历完,然后遍历根节点,最后遍历右子树,右子树又可以分解为:左子树、根节点和右子树。
后序遍历 先遍历左子树,再遍历右子树,最后遍历根节点。
思路:先遍历左子树,左子树又可以分解为:左子树、右子树和根节点,直到把所有左子树的部分遍历完,然后遍历右子树,右子树又可以分解为,左子树、右子树和根节点,最后遍历根节点。
从上至下,从左至右的逐层访问。
遍历结果:1 2 4 3 NULL 5 6 NULL NULL NULL NULL NULL NULL
代码的实现将放在以下文件中,分别是 BinaryTree.h(用于声明)、BinaryTree.c(用于定义)、Test.c(用于测试)、Queue.h(队列)、Queue.c(队列)。
BinaryTree.h 文件
#include
#include #include #include typedef char BTDataType; typedef struct BinaryTreeNode{ BTDataType data; // 节点 struct BinaryTreeNode* left; // 左子树 struct BinaryTreeNode* right; // 右子树 }BTNode; // 二叉树的初始化 BTNode* BuyNode(BTDataType x); // 创建二叉树 BTNode* CreatBinaryTree(); // 二叉树的前序遍历 void PreOrder(BTNode* root); // 二叉树的中序遍历 void InOrder(BTNode* root); // 二叉树的后序遍历 void PostOrder(BTNode* root); // 二叉树的节点个数 int BinaryTreeSize1(BTNode* root); void BinaryTreeSize2(BTNode* root, int* pCount); // 二叉树的叶子节点个数 int BinaryTreeLeafSize(BTNode* root); // 二叉树的第 k 层节点个数 int BinaryTreeLevelKSize(BTNode* root, int k); // 二叉树的深度/高度 int BinaryTreeDepth(BTNode* root); // 二叉树查找值为 x 的节点 BTNode* BinaryTreeFind(BTNode* root, BTDataType x); // 二叉树的层序遍历 void BinaryTreeLevelOrder(BTNode* root); // 判断一棵二叉树是否是完全二叉树 bool BinaryTreeComplete(BTNode* root); // 二叉树的销毁 void BinaryTreeDestory(BTNode* root);
BinaryTree.c 文件
#include "BinaryTree.h" // 二叉树的初始化 BTNode* BuyNode(BTDataType x){ BTNode* newnode = (BTNode*)malloc(sizeof(BTNode)); if (newnode == NULL){ printf("malloc fail\n"); exit(-1); } newnode->data = x; newnode->left = newnode->right = NULL; return newnode; }
BinaryTree.c 文件
#include "BinaryTree.h" // 创建二叉树 BTNode* CreatBinaryTree(){ BTNode* nodeA = BuyNode('A'); BTNode* nodeB = BuyNode('B'); BTNode* nodeC = BuyNode('C'); BTNode* nodeD = BuyNode('D'); BTNode* nodeE = BuyNode('E'); nodeA->left = nodeB; nodeA->right = nodeC; nodeB->left = nodeD; nodeB->right = nodeE; return nodeA; }
BinaryTree.c 文件
#include "BinaryTree.h" // 前序遍历 void PreOrder(BTNode* root){ if (root == NULL){ printf("NULL "); return; } printf("%c ", root->data); // 访问根节点 PreOrder(root->left); // 遍历左子树 PreOrder(root->right); // 遍历右子树 }
Test.c 文件
#include "BinaryTree.h" void TestBinaryTree1(){ BTNode* root = CreatBinaryTree(); printf("前序遍历:"); PreOrder(root); } int main(){ TestBinaryTree1(); system("pause"); return 0; }
运行结果:
BinaryTree.c 文件
#include "BinaryTree.h" // 中序遍历 void InOrder(BTNode* root){ if (root == NULL){ printf("NULL "); return; } InOrder(root->left); // 遍历左子树 printf("%c ", root->data); // 访问根节点 InOrder(root->right); // 遍历右子树 }
Test.c 文件
#include "BinaryTree.h" void TestBinaryTree1(){ BTNode* root = CreatBinaryTree(); printf("中序遍历:"); InOrder(root); printf("\n\n"); } int main(){ TestBinaryTree1(); system("pause"); return 0; }
运行结果:
BinaryTree.c 文件
#include "BinaryTree.h" // 后序遍历 void PostOrder(BTNode* root){ if (root == NULL){ printf("NULL "); return; } PostOrder(root->left); // 遍历左子树 PostOrder(root->right); // 遍历右子树 printf("%c ", root->data); // 访问根节点 }
Test.c 文件
#include "BinaryTree.h" void TestBinaryTree1(){ BTNode* root = CreatBinaryTree(); printf("后序遍历:"); PostOrder(root); printf("\n\n"); } int main(){ TestBinaryTree1(); system("pause"); return 0; }
运行结果:
思路一:
采用分治思想,将复杂问题分成更小规模子问题,直到子问题不可再分割,能直接能出结果。
空树,最小规模子问题,节点数返回 0。
非空,左子树节点数 + 右子树节点数 + 1(自己)。
思路二: 遍历 + 计数(遍历时将遍历地址传过去)。
BinaryTree.c 文件
#include "BinaryTree.h" // 方法一(最优) int BinaryTreeSize1(BTNode* root){ return root == NULL ? 0 : BinaryTreeSize1(root->left) + BinaryTreeSize1(root->right) + 1; } // 方法二 void BinaryTreeSize2(BTNode* root, int* pCount){ if (root == NULL){ return; } ++(*pCount); BinaryTreeSize2(root->left, pCount); BinaryTreeSize2(root->right, pCount); }
Test.c 文件
#include "BinaryTree.h" void TestBinaryTree1(){ BTNode* root = CreatBinaryTree(); printf("二叉树节点个数,方法一:"); printf("%d\n\n", BinaryTreeSize1(root)); printf("二叉树节点个数,方法二:"); int count = 0; BinaryTreeSize2(root, &count); printf("%d\n\n", count); } int main(){ TestBinaryTree1(); system("pause"); return 0; }
运行结果:
思路: 叶子节点是度为 0 的节点。采用分治思想,遍历它的左子树和右子树的叶子节点并相加。
BinaryTree.c 文件
#include "BinaryTree.h" // 二叉树的叶子节点个数 int BinaryTreeLeafSize(BTNode* root){ // 树为空,没有叶子节点 if (root == NULL){ return 0; } // 只有一个节点,说明只有一个叶子节点 if (root->left == NULL && root->right == NULL){ return 1; } // 上述两种情况都存在,就去遍历左子树和右子树 return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right); }
Test.c 文件
#include "BinaryTree.h" void TestBinaryTree1(){ BTNode* root = CreatBinaryTree(); printf("二叉树的叶子节点个数:"); printf("%d\n\n", BinaryTreeLeafSize(root)); } int main(){ TestBinaryTree1(); system("pause"); return 0; }
运行结果:
思路:
(1)空数,返回 0。
(2)非空,且 k == 1,返回 1。
(3)非空,且 k > 1,转换成求 左子树 k-1 层节点个数 + 右子树 k-1 层节点个数。
BinaryTree.c 文件
#include "BinaryTree.h" // 二叉树的第 k 层节点个数 int BinaryTreeLevelKSize(BTNode* root, int k){ //检查 K 的合法性 assert(k >= 1); if (root == NULL){ return 0; } if (k == 1){ return 1; } // root 不等于空,k 也不等于 1,说明 root 这棵树的第 k 节点在字树里面 // 转换成求左右子树的第 k-1 层的节点数量; return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1); }
Test.c 文件
#include "BinaryTree.h" void TestBinaryTree1(){ BTNode* root = CreatBinaryTree(); printf("二叉树第 3 层节点个数:"); int k = 3; printf("%d\n\n", BinaryTreeLevelKSize(root, k)); } int main(){ TestBinaryTree1(); system("pause"); return 0; }
运行结果:
思路:
(1)判断根节点是否为要找的节点,是则返回节点地址。
(2)不是则进左子树中去找,找到返回节点地址,找不到返回空。
(3)再进右子树取找,找到返回节点地址,找不到返回空。
BinaryTree.c 文件
#include "BinaryTree.h" // 二叉树查找值为 x 的节点 BTNode* BinaryTreeFind(BTNode* root, BTDataType x){ // 如果树为空,则找不到 if (root == NULL){ return NULL; } // 根节点与找的值相等 if (root->data == x){ return root; } // 遍历左子树查找 BTNode* leftRet = BinaryTreeFind(root->left, x); if (leftRet){ return leftRet; } // 遍历右子树查找 BTNode* rightRet = BinaryTreeFind(root->right, x); if (rightRet){ return rightRet; } // 遍历完未找到 return NULL; }
Test.c 文件
#include "BinaryTree.h" void TestBinaryTree1(){ BTNode* root = CreatBinaryTree(); printf("查找二叉树中值为 E 的节点:\n"); char node = 'E'; printf("E 的地址:%p\n\n", BinaryTreeFind(root, node)); } int main(){ TestBinaryTree1(); system("pause"); return 0; }
运行结果:
思路: 二叉树的深度/高度 = 左、右子树里高度的最大值 + 1。
BinaryTree.c 文件
#include "BinaryTree.h" // 二叉树的深度/高度 int BinaryTreeDepth(BTNode* root){ if (root == NULL){ return 0; } int leftDepth = BinaryTreeDepth(root->left); int rightDepth = BinaryTreeDepth(root->right); return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1; }
Test.c 文件
#include "BinaryTree.h" void TestBinaryTree1(){ BTNode* root = CreatBinaryTree(); printf("二叉树深度:"); printf("%d\n\n", BinaryTreeDepth(root)); } int main(){ TestBinaryTree1(); system("pause"); return 0; }
运行结果:
思路: 层序遍历需要用到队列(先进先出的性质)。
(1)先将根节点放入队列中。
(2)判断队列是否为空,不为空则出队头数据,同时将它的左右子节点放到队列中。
(3)重复第二步,直到队列为空。
Queue.h、Queue.c 代码见下方总结。
BinaryTree.c 文件
#include "BinaryTree.h" #include "Queue.h" // 层序遍历 void BinaryTreeLevelOrder(BTNode* root){ if (root == NULL){ return; } Queue q; QueueInit(&q); QueuePush(&q, root); while (!QueueEmpty(&q)){ BTNode* front = QueueFront(&q); QueuePop(&q); printf("%c ", front->data); // 孩子带进队列 if (front->left){ QueuePush(&q, front->left); } if (front->right){ QueuePush(&q, front->right); } } printf("\n"); QueueDestroy(&q); }
Test.c 文件
#include "BinaryTree.h" void TestBinaryTree1(){ BTNode* root = CreatBinaryTree(); printf("层序遍历:"); BinaryTreeLevelOrder(root); printf("\n"); } int main(){ TestBinaryTree1(); system("pause"); return 0; }
运行结果:
思路: 首先创建一个队列,利用层序遍历,将每一层都遍历一遍。如果遇到 NULL,则结束循环,再遍历之后的节点,如果不是 NULL,则不是完全二叉树,如果全为 NULL,则是完全二叉树。
BinaryTree.c 文件
#include "BinaryTree.h" #include "Queue.h" // 判断一棵二叉树是否是完全二叉树 // 是则返回 1,不是则返回 0 bool BinaryTreeComplete(BTNode* root){ Queue q; QueueInit(&q); QueuePush(&q, root); while (!QueueEmpty(&q)){ BTNode* front = QueueFront(&q); QueuePop(&q); // 孩子带进队列 if (front == NULL){ break; } else{ QueuePush(&q, front->left); QueuePush(&q, front->right); } } // 遇到空以后,检查队列中剩下的节点 // 1.剩下的全是空,则是完全二叉树 // 2.剩下的是非空,则不是完全二叉树 while (!QueueEmpty(&q)){ BTNode* front = QueueFront(&q); QueuePop(&q); if (front != NULL){ QueueDestroy(&q); return false; } } QueueDestroy(&q); return true; }
Test.c 文件
#include "BinaryTree.h" void TestBinaryTree1(){ BTNode* root = CreatBinaryTree(); printf("是否为完全二叉树 0/1:"); printf("%d\n", BinaryTreeComplete(root)); } int main(){ TestBinaryTree1(); system("pause"); return 0; }
运行结果:
BinaryTree.c 文件
#include "BinaryTree.h" // 二叉树的销毁 void BinaryTreeDestory(BTNode* root){ if (root == NULL){ return; } BinaryTreeDestory(root->left); BinaryTreeDestory(root->right); free(root); }
Test.c 文件
#include "BinaryTree.h" void TestBinaryTree1(){ BTNode* root = CreatBinaryTree(); BinaryTreeDestory(root); root = NULL; } int main(){ TestBinaryTree1(); system("pause"); return 0; }
BinaryTree.h 文件
#include
#include #include #include typedef char BTDataType; typedef struct BinaryTreeNode{ BTDataType data; // 节点 struct BinaryTreeNode* left; // 左子树 struct BinaryTreeNode* right; // 右子树 }BTNode; // 二叉树的初始化 BTNode* BuyNode(BTDataType x); // 创建二叉树 BTNode* CreatBinaryTree(); // 二叉树的前序遍历 void PreOrder(BTNode* root); // 二叉树的中序遍历 void InOrder(BTNode* root); // 二叉树的后序遍历 void PostOrder(BTNode* root); // 二叉树的节点个数 int BinaryTreeSize1(BTNode* root); void BinaryTreeSize2(BTNode* root, int* pCount); // 二叉树的叶子节点个数 int BinaryTreeLeafSize(BTNode* root); // 二叉树的第 k 层节点个数 int BinaryTreeLevelKSize(BTNode* root, int k); // 二叉树的深度/高度 int BinaryTreeDepth(BTNode* root); // 二叉树查找值为 x 的节点 BTNode* BinaryTreeFind(BTNode* root, BTDataType x); // 二叉树的层序遍历 void BinaryTreeLevelOrder(BTNode* root); // 判断一棵二叉树是否是完全二叉树 bool BinaryTreeComplete(BTNode* root); // 二叉树的销毁 void BinaryTreeDestory(BTNode* root); BinaryTree.c 文件
#include "BinaryTree.h" #include "Queue.h" // 二叉树的初始化 BTNode* BuyNode(BTDataType x){ BTNode* newnode = (BTNode*)malloc(sizeof(BTNode)); if (newnode == NULL){ printf("malloc fail\n"); exit(-1); } newnode->data = x; newnode->left = newnode->right = NULL; return newnode; } // 创建二叉树 BTNode* CreatBinaryTree(){ BTNode* nodeA = BuyNode('A'); BTNode* nodeB = BuyNode('B'); BTNode* nodeC = BuyNode('C'); BTNode* nodeD = BuyNode('D'); BTNode* nodeE = BuyNode('E'); nodeA->left = nodeB; nodeA->right = nodeC; nodeB->left = nodeD; nodeB->right = nodeE; return nodeA; } // 前序遍历 void PreOrder(BTNode* root){ if (root == NULL){ printf("NULL "); return; } printf("%c ", root->data); // 访问根节点 PreOrder(root->left); // 遍历左子树 PreOrder(root->right); // 遍历右子树 } // 中序遍历 void InOrder(BTNode* root){ if (root == NULL){ printf("NULL "); return; } InOrder(root->left); // 遍历左子树 printf("%c ", root->data); // 访问根节点 InOrder(root->right); // 遍历右子树 } // 后序遍历 void PostOrder(BTNode* root){ if (root == NULL){ printf("NULL "); return; } PostOrder(root->left); // 遍历左子树 PostOrder(root->right); // 遍历右子树 printf("%c ", root->data); // 访问根节点 } /*******************************************************/ // 二叉树的节点个数 // 方法一(最优) int BinaryTreeSize1(BTNode* root){ return root == NULL ? 0 : BinaryTreeSize1(root->left) + BinaryTreeSize1(root->right) + 1; } // 方法二 void BinaryTreeSize2(BTNode* root, int* pCount){ if (root == NULL){ return; } ++(*pCount); BinaryTreeSize2(root->left, pCount); BinaryTreeSize2(root->right, pCount); } /*******************************************************/ // 二叉树的叶子节点个数 int BinaryTreeLeafSize(BTNode* root){ // 树为空,没有叶子节点 if (root == NULL){ return 0; } // 只有一个节点,说明只有一个叶子节点 if (root->left == NULL && root->right == NULL){ return 1; } // 上述两种情况都存在,就去遍历左子树和右子树 return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right); } // 二叉树的第 k 层节点个数 int BinaryTreeLevelKSize(BTNode* root, int k){ //检查 K 的合法性 assert(k >= 1); if (root == NULL){ return 0; } if (k == 1){ return 1; } // root 不等于空,k 也不等于 1,说明 root 这棵树的第 k 节点在字树里面 // 转换成求左右子树的第 k-1 层的节点数量; return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1); } // 二叉树的深度/高度 int BinaryTreeDepth(BTNode* root){ if (root == NULL){ return 0; } int leftDepth = BinaryTreeDepth(root->left); int rightDepth = BinaryTreeDepth(root->right); return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1; } // 二叉树查找值为 x 的节点 BTNode* BinaryTreeFind(BTNode* root, BTDataType x){ // 如果树为空,则找不到 if (root == NULL){ return NULL; } // 根节点与找的值相等 if (root->data == x){ return root; } // 遍历左子树查找 BTNode* leftRet = BinaryTreeFind(root->left, x); if (leftRet){ return leftRet; } // 遍历右子树查找 BTNode* rightRet = BinaryTreeFind(root->right, x); if (rightRet){ return rightRet; } // 遍历完未找到 return NULL; } // 层序遍历 void BinaryTreeLevelOrder(BTNode* root){ if (root == NULL){ return; } Queue q; QueueInit(&q); QueuePush(&q, root); while (!QueueEmpty(&q)){ BTNode* front = QueueFront(&q); QueuePop(&q); printf("%c ", front->data); // 孩子带进队列 if (front->left){ QueuePush(&q, front->left); } if (front->right){ QueuePush(&q, front->right); } } printf("\n"); QueueDestroy(&q); } // 判断一棵二叉树是否是完全二叉树 // 是则返回 1,不是则返回 0 bool BinaryTreeComplete(BTNode* root){ Queue q; QueueInit(&q); QueuePush(&q, root); while (!QueueEmpty(&q)){ BTNode* front = QueueFront(&q); QueuePop(&q); // 孩子带进队列 if (front == NULL){ break; } else{ QueuePush(&q, front->left); QueuePush(&q, front->right); } } // 遇到空以后,检查队列中剩下的节点 // 1.剩下的全是空,则是完全二叉树 // 2.剩下的是非空,则不是完全二叉树 while (!QueueEmpty(&q)){ BTNode* front = QueueFront(&q); QueuePop(&q); if (front != NULL){ QueueDestroy(&q); return false; } } QueueDestroy(&q); return true; } // 二叉树的销毁 void BinaryTreeDestory(BTNode* root){ if (root == NULL){ return; } BinaryTreeDestory(root->left); BinaryTreeDestory(root->right); free(root); }
Test.c 文件
#include "BinaryTree.h" void TestBinaryTree1(){ BTNode* root = CreatBinaryTree(); printf("前序遍历:"); PreOrder(root); printf("\n\n"); printf("中序遍历:"); InOrder(root); printf("\n\n"); printf("后序遍历:"); PostOrder(root); printf("\n\n"); printf("二叉树节点个数,方法一:"); printf("%d\n\n", BinaryTreeSize1(root)); printf("二叉树节点个数,方法二:"); int count = 0; BinaryTreeSize2(root, &count); printf("%d\n\n", count); printf("二叉树的叶子节点个数:"); printf("%d\n\n", BinaryTreeLeafSize(root)); printf("二叉树第 3 层节点个数:"); int k = 3; printf("%d\n\n", BinaryTreeLevelKSize(root, k)); printf("查找二叉树中值为 E 的节点:\n"); char node = 'E'; printf("E 的地址:%p\n\n", BinaryTreeFind(root, node)); printf("二叉树深度:"); printf("%d\n\n", BinaryTreeDepth(root)); printf("层序遍历:"); BinaryTreeLevelOrder(root); printf("\n"); printf("是否为完全二叉树 0/1:"); printf("%d\n", BinaryTreeComplete(root)); BinaryTreeDestory(root); root = NULL; } int main(){ TestBinaryTree1(); system("pause"); return 0; }
Queue.h 文件
#pragma once #include
#include #include #include // 前置声明 extern struct BinaryTreeNode; typedef struct BinaryTreeNode* QDataType; // 链表结构实现队列 typedef struct QueueNode{ QDataType data; // 储存数据 struct QueueNode* next; // 储存下一个节点地址 }QNode; // 记录队列头、尾节点的地址 typedef struct Queue{ // 两个指针,一个控制队尾,一个控制队头,方便数据入队和出队 QNode* head; // 储存头节点地址 QNode* tail; // 储存尾节点地址 }Queue; // 队列的初始化 void QueueInit(Queue* pq); // 队列的销毁 void QueueDestroy(Queue* pq); // 队尾入队列 void QueuePush(Queue* pq, QDataType x); // 队头出队列 void QueuePop(Queue* pq); // 获取队头元素 QDataType QueueFront(Queue* pq); // 获取队尾元素 QDataType QueueBack(Queue* pq); // 获取队列的元素个数 int QueueSize(Queue* pq); // 判断队列是否为空 bool QueueEmpty(Queue* pq); Queue.c 文件
#include "Queue.h" // 队列的初始化 void QueueInit(Queue* pq){ assert(pq); pq->head = NULL; pq->tail = NULL; } // 队列的销毁 void QueueDestroy(Queue* pq){ assert(pq); QNode* cur = pq->head; // 从队头开始遍历销毁节点 while (cur){ // 销毁前,保存下一个节点的地址 QNode* next = cur->next; free(cur); cur = next; } pq->head = pq->tail = NULL; } // 队尾入队列(尾插) void QueuePush(Queue* pq, QDataType x){ assert(pq); // 创建一个新节点 QNode* newnode = (QNode*)malloc(sizeof(QNode)); // 将要入队的元素赋值给新创建的节点 newnode->data = x; newnode->next = NULL; // 队列为空时 if (pq->tail == NULL){ pq->head = pq->tail = newnode; } else{ pq->tail->next = newnode; // 记录新的尾节点 pq->tail = newnode; } } // 队头出队列(头删) void QueuePop(Queue* pq){ assert(pq); // 出列必须保证队列不为空 assert(!QueueEmpty(pq)); QNode* next = pq->head->next; free(pq->head); pq->head = next; // 此时 head 和 tail 同时指向最后一个空间,释放 head 后,注意也要将 tail 释放 if (pq->head == NULL){ pq->tail = NULL; } } // 获取队头元素 QDataType QueueFront(Queue* pq){ assert(pq); // 判断队列是否为空 assert(!QueueEmpty(pq)); return pq->head->data; } // 获取队尾元素 QDataType QueueBack(Queue* pq){ assert(pq); // 判断队列是否为空 assert(!QueueEmpty(pq)); return pq->tail->data; } // 获取队列的元素个数 int QueueSize(Queue* pq){ assert(pq); int n = 0; QNode* cur = pq->head; while (cur){ ++n; cur = cur->next; } return n; } // 判断队列是否为空 bool QueueEmpty(Queue* pq){ assert(pq); return pq->head == NULL; }
运行结果: