二叉树T:一个又穷的结点集合
(这个集合可以为空,若不为空,则它是由根节点和称其左子树TL和右子树TR的两个不相交的二叉树组成)
使用结构体定义树的结点:
struct node
{
DataType data;
struct node *left, *right;
};
typedef struct node *BiTree;
开辟一个新结点 (返回这个结点的地址) (总是被Insert函数调用):
BiTree newNode(DataType d)
{
BiTree n = (BiTree)malloc(sizeof(struct node));
n->data = d;
n->left = n->right = NULL;
return n;
}
(规则:二叉搜索树,左子结点的值比根节点值小,右子结点的值比根节点值大)
BiTree Insert(BiTree node, DataType d)
{
if(!node)
node = newNode(d); // 结点的value
else
{
if(d >= node->data)
node->right = Insert(node->right, d);
else
node->left = Insert(node->left, d);
}
return node;
}
定义MBTree函数,递归建立二叉搜索树(输入0表示null,不为null的根结点还需要2个子树),返回根结点的地址:
BiTree MBTree()
{
// 输入二叉树data 输入0表示NULL
BiTree root = NULL;
DataType d;
scanf("%d", &d);
if(d != 0)
{
root = newNode(d);
root->left = MBTree();
root->right = MBTree();
}
return root;
}
/*----------------------------------到此为止,完成二叉搜索树定义-----------------------------------------*/二叉树的先序遍历(使用递归的思想):
void PreOrder(BiTree root)
{
if(root != NULL)
{
printf("%d ", root->data);
PreOrder(root->left);
PreOrder(root->right);
}
}
因为C语言库函数没有栈,因此需要自定义栈(在后序非递归遍历的时候使用) (尽量做到与C++库函数功能一样):
struct stack{
BiTNode *elem[maxSize];
int top;
};
// 栈初始化
void initStack(Stack *S)
{
S->top = -1;
}
// 判断栈空否,空栈时返回1,否则返回0
int IsStackEmpty(Stack *S)
{
if(S->top < 0)
return 1;
else
return 0;
}
// 读栈顶元素,用x返回栈顶元素的值(不退栈),若成功返回1
BiTree getTop(Stack *S)
{
if(IsStackEmpty(S))
return NULL;
else
return S->elem[S->top];
}
// 进栈,成功返回1,否则返回0
int Push(Stack *S, BiTNode *x)
{
if(S->top >= maxSize)
return 0;
else
S->elem[++S->top] = x;
return 1;
}
// 出栈,栈非空时,出栈成功返回1,否则返回0
int Pop(Stack *S, BiTNode **x)
{
if(S->top < 0)
return 0;
else
*x = S->elem[S->top--];
return 1;
}
二叉树的中序非递归遍历(需要使用栈):
void InOrder(BiTree root)
{
Stack *S = (Stack *)malloc(sizeof(struct stack)); // 建立栈
initStack(S); // 栈元素定义为
BiTNode *p = root; // p是遍历指针,从根节点开始
do
{
while(p != NULL) // 非空二叉树,沿左链进栈
{
Push(S, p);
p = p->left;
}
if(!IsStackEmpty(S)) // 栈不空时退栈
{
Pop(S, &p);
printf("%d ", p->data);
p = p->right; // 遍历指针进到右子女节点
}
}
while(p != NULL || !IsStackEmpty(S));
}
因为C语言库函数没有队列,因此需要自定义队列(在层次遍历的时候使用) (尽量做到与C++库函数功能一样):
struct queue{
BiTNode *elem[maxSize];
int front, rear; // 循环队列的队头、队尾指针
};
// 队列初始化:创建一个空的队列Q并初始化
void initQueue(Queue *Q)
{
Q->front = 0;
Q->rear = 0;
}
// 判断队列空否:当队列Q为空时函数返回1,否则返回0
int IsQueueEmpty(Queue *Q)
{
if(Q->front == Q->rear)
return 1;
else
return 0;
}
// 进队列:当队列Q未满时,将元素成为队尾,成功返回1,否则返回0
// 进队列:elem[rear]存入数据,rear再++
int enQueue(Queue *Q, BiTNode *x)
{
if((Q->rear+1) % maxSize == Q->front)
return 0;
else
{
Q->elem[Q->rear] = x;
Q->rear = (Q->rear+1) % maxSize;
return 1;
}
}
// 出队列:当队列Q非空时,将队头元素退出,成功返回1,否则返回0
int deQueue(Queue *Q, BiTNode **x)
{
if(IsQueueEmpty(Q))
return 0;
else
{
*x = Q->elem[Q->front];
Q->front = (Q->front+1) % maxSize;
return 1;
}
}
二叉树的层次遍历(需要使用队列):
void LevelOrder(BiTree root)
{
BiTNode *p;
Queue Q; // 建立一个队列
initQueue(&Q); // 初始化队列
enQueue(&Q, root); // 入栈队列
while(!IsQueueEmpty(&Q))
{
deQueue(&Q, &p);
printf("%d ", p->data);
if(p->left != NULL)
enQueue(&Q, p->left);
if(p->right != NULL)
enQueue(&Q, p->right);
}
}
二叉树的后序非递归遍历(需要使用栈):
void LastOrder(BiTree root)
{
BiTree temp = NULL;
Stack *S = (Stack *)malloc(sizeof(struct stack)); // 建立栈
initStack(S);
while(root != NULL || !IsStackEmpty(S))
{
while(root != NULL) // root和全部左子树 都压栈
{
Push(S, root);
root = root->left;
}
if(!IsStackEmpty(S))
if(getTop(S)->right != NULL) // 栈顶元素有右子树
root = getTop(S)->right;
else
{
do // 栈顶元素没有右子树
{
Pop(S, &temp);
printf("%d ", temp->data);
root = getTop(S); // root 可能为 null
}
while(!IsStackEmpty(S) && root->right == temp);
// 栈不空 并且 出栈元素是栈顶元素的右子树
}
if(root && root->left == temp) // 出栈元素是栈顶元素的左子树
root = root->right;
}
}
下面给出完整代码:
建立二叉搜索树、递归遍历、非递归中序和后序遍历、自定义栈、自定义队列
#include <stdio.h>
#include <stdlib.h> //#include <malloc.h>
// 建立二叉树,搜索二叉树
#define maxSize 100
typedef int DataType;
typedef struct node *BiTree;
typedef struct node BiTNode;
typedef struct stack Stack;
typedef struct queue Queue;
struct node
{
DataType data;
struct node *left, *right;
};
//-------------------------栈定义----------------------------
struct stack{
BiTNode *elem[maxSize];
int top;
};
// 栈初始化
void initStack(Stack *S)
{
S->top = -1;
}
// 判断栈空否,空栈时返回1,否则返回0
int IsStackEmpty(Stack *S)
{
if(S->top < 0)
return 1;
else
return 0;
}
// 读栈顶元素,用x返回栈顶元素的值(不退栈),若成功返回1
BiTree getTop(Stack *S)
{
if(IsStackEmpty(S))
return NULL;
else
return S->elem[S->top];
}
// 进栈,成功返回1,否则返回0
int Push(Stack *S, BiTNode *x)
{
if(S->top >= maxSize)
return 0;
else
S->elem[++S->top] = x;
return 1;
}
// 出栈,栈非空时,出栈成功返回1,否则返回0
int Pop(Stack *S, BiTNode **x)
{
if(S->top < 0)
return 0;
else
*x = S->elem[S->top--];
return 1;
}
//-------------------------栈定义end----------------------------
//-------------------------队列定义-----------------------------
struct queue{
BiTNode *elem[maxSize];
int front, rear; // 循环队列的队头、队尾指针
};
// 队列初始化:创建一个空的队列Q并初始化
void initQueue(Queue *Q)
{
Q->front = 0;
Q->rear = 0;
}
// 判断队列空否:当队列Q为空时函数返回1,否则返回0
int IsQueueEmpty(Queue *Q)
{
if(Q->front == Q->rear)
return 1;
else
return 0;
}
// 进队列:当队列Q未满时,将元素成为队尾,成功返回1,否则返回0
// 进队列:elem[rear]存入数据,rear再++
int enQueue(Queue *Q, BiTNode *x)
{
if((Q->rear+1) % maxSize == Q->front)
return 0;
else
{
Q->elem[Q->rear] = x;
Q->rear = (Q->rear+1) % maxSize;
return 1;
}
}
// 出队列:当队列Q非空时,将队头元素退出,成功返回1,否则返回0
int deQueue(Queue *Q, BiTNode **x)
{
if(IsQueueEmpty(Q))
return 0;
else
{
*x = Q->elem[Q->front];
Q->front = (Q->front+1) % maxSize;
return 1;
}
}
//-------------------------队列定义end--------------------------
BiTree newNode(DataType d) // 开辟新结点
{
BiTree n = (BiTree)malloc(sizeof(struct node));
n->data = d;
n->left = n->right = NULL;
return n;
}
BiTree Insert(BiTree node, DataType d)
{
if(!node)
node = newNode(d); // 结点的value
else
{
if(d >= node->data)
node->right = Insert(node->right, d);
else
node->left = Insert(node->left, d);
}
return node;
}
BiTree MBTree()
{
// 输入二叉树data 输入0表示NULL
BiTree root = NULL;
DataType d;
scanf("%d", &d);
if(d != 0)
{
root = newNode(d);
root->left = MBTree();
root->right = MBTree();
}
return root;
}
// 先序递归遍历
void PreOrder(BiTree root)
{
if(root != NULL)
{
printf("%d ", root->data);
PreOrder(root->left);
PreOrder(root->right);
}
}
// 中序非递归遍历
void InOrder(BiTree root)
{
Stack *S = (Stack *)malloc(sizeof(struct stack)); // 建立栈
initStack(S); // 栈元素定义为
BiTNode *p = root; // p是遍历指针,从根节点开始
do
{
while(p != NULL) // 非空二叉树,沿左链进栈
{
Push(S, p);
p = p->left;
}
if(!IsStackEmpty(S)) // 栈不空时退栈
{
Pop(S, &p);
printf("%d ", p->data);
p = p->right; // 遍历指针进到右子女节点
}
}
while(p != NULL || !IsStackEmpty(S));
}
// 层次遍历
void LevelOrder(BiTree root)
{
BiTNode *p;
Queue Q; // 建立一个队列
initQueue(&Q); // 初始化队列
enQueue(&Q, root); // 入栈队列
while(!IsQueueEmpty(&Q))
{
deQueue(&Q, &p);
printf("%d ", p->data);
if(p->left != NULL)
enQueue(&Q, p->left);
if(p->right != NULL)
enQueue(&Q, p->right);
}
}
// 后序遍历
void LastOrder(BiTree root)
{
BiTree temp = NULL;
Stack *S = (Stack *)malloc(sizeof(struct stack)); // 建立栈
initStack(S);
while(root != NULL || !IsStackEmpty(S))
{
while(root != NULL) // root和全部左子树 都压栈
{
Push(S, root);
root = root->left;
}
if(!IsStackEmpty(S))
if(getTop(S)->right != NULL) // 栈顶元素有右子树
root = getTop(S)->right;
else
{
do // 栈顶元素没有右子树
{
Pop(S, &temp);
printf("%d ", temp->data);
root = getTop(S); // root 可能为 null
}
while(!IsStackEmpty(S) && root->right == temp);
// 栈不空 并且 出栈元素是栈顶元素的右子树
}
if(root && root->left == temp) // 出栈元素是栈顶元素的左子树
root = root->right;
}
}
int main()
{
BiTree root;
root = MBTree(); // 建立二叉搜索树,输入0表示NULL
PreOrder(root); // 先序递归遍历
printf("\n");
InOrder(root); // 中序非递归遍历:栈
printf("\n");
LevelOrder(root); // 层次遍历:堆
printf("\n");
LastOrder(root); // 后序非递归遍历:栈
printf("\n");
return 0;
}
运行结果图: