1.非递归建立
先看一下一个结点是如何插入
如图:
p指针用来查找要插入的位置,q指针记录插入位置的父节点,之后用于连接孩子结点
第一次比较后调整p,q
第二次比较
第三次
第四次,插入对应的关键字
对应排序树的结构体:
typedef int ElemType;
typedef struct BSTNode {
ElemType key;
struct BSTNode *lchild, *rchild;
}*BSTree,BSTNode;
非递归建立一个二叉排序树:
BSTree createBSTree(BSTree& T,ElemType arr[],int length) {
int i=0;
while (i < length) {
nonRecusInsertNode(T, arr[i]);
i++;
}
return T;
}
//非递归建立二叉排序树
BSTNode* nonRecusInsertNode(BSTree &T,ElemType key) {
BSTNode* p = T; //用来查找
BSTNode* q=NULL; //用来指明当前插入位置的父节点
//此处用来寻找插入的位置和当前插入位置的父节点
//q记录插入位置的父节点用来连接插入的孩子
while (p != NULL) {
if (p->key == key) {
return NULL; //已经存在,插入失败
}
else if (p->key > key) {
q = p;
p = p->lchild; //找到对应插入为NULL的位置
}
else {
q = p;
p = p->rchild;
}
}
//初始化一个插入结点
p = (BSTNode*)malloc(sizeof(BSTNode));
p->key = key;
p->lchild = NULL;
p->rchild = NULL;
//将插入结点与之父节点相连
if (!q) { //要插入根节点,直接用T指针相连
T = p;
}
else if (q->key > key) { //插入父节点的左边,将父节点的左孩子指向插入的结点
q->lchild = p;
}
else q->rchild = p; //插入父节点的右边,将父节点的右孩子指向插入的结点
return p;
}
测试:
中序遍历二叉排序树是一个有序的序列,所以正确
2.递归实现建立一个二叉树
BSTree createBSTree(BSTree& T,ElemType arr[],int length) {
int i=0;
while (i < length) {
recusInsertNode(T, arr[i]);
//nonRecusInsertNode(T, arr[i]);
i++;
}
return T;
}
//递归建立二叉排序树
BSTNode* recusInsertNode(BSTree& T, ElemType key) {
if (T == NULL) {
T = (BSTNode*)malloc(sizeof(BSTNode));
T->key = key;
T->lchild = NULL;
T->rchild = NULL;
return T;
}
else if (T->key==key) { //如果已经存在要插入的关键字,返回NULL
return NULL;
}
else if (key>T->key) {
return recusInsertNode(T->rchild,key); //递归查看比较右子树
}
else {
return recusInsertNode(T->lchild,key); //递归查看比较左子树
}
}
测试: