二叉搜索树

来源:互联网 发布:php二次开发有前途没 编辑:程序博客网 时间:2024/05/16 16:22

二叉树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;}

定义Insert函数,在树中加入一个结点
(规则:二叉搜索树,左子结点的值比根节点值小,右子结点的值比根节点值大)
BiTree Insert(BiTree node, DataType d){if(!node)node = newNode(d);// 结点的value else{if(d >= node->data)node->right = Insert(node->right, d);elsenode->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;elsereturn 0;}// 读栈顶元素,用x返回栈顶元素的值(不退栈),若成功返回1 BiTree getTop(Stack *S){if(IsStackEmpty(S))return NULL;elsereturn S->elem[S->top];}// 进栈,成功返回1,否则返回0 int Push(Stack *S, BiTNode *x){if(S->top >= maxSize)return 0;elseS->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;elsereturn 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 100typedef 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;elsereturn 0;}// 读栈顶元素,用x返回栈顶元素的值(不退栈),若成功返回1 BiTree getTop(Stack *S){if(IsStackEmpty(S))return NULL;elsereturn S->elem[S->top];}// 进栈,成功返回1,否则返回0 int Push(Stack *S, BiTNode *x){if(S->top >= maxSize)return 0;elseS->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;elsereturn 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);elsenode->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;}




运行结果图:




0 0