目录
1.以二叉链表作存储结构,编写一个算法将二叉树左、右子树进行交换的算法。
2.一棵具有n个结点的完全二叉树存放在二叉树的顺序存储结构中,试编写非递归算法对该树进行中序遍历。
5.编写一个将二叉树的所有叶子结点从左向右链接成单链表的算法。
6.设具有n个结点的完全二叉树采用顺序存储结构,试写一个算法将该顺序存储结构转换为二叉链式存储结构。
7.7.设具有n个结点的二叉树采用二叉链式存储结构,试写出一个算法将该二叉链式存储结构转换为顺序存储结构。
经典练习题
1.以二叉链表作存储结构,编写一个算法将二叉树左、右子树进行交换的算法。
void SwapSubTree(ListNode *root)
{
ListNode *temp;
if (root)
{
temp = root->lchild;
root->lchild = root->rchild;
root->rchild = temp;
SwapSubTree(&((*T)->lchild));
SwapSubTree(&((*T)->rchild));
}
}
2.一棵具有n个结点的完全二叉树存放在二叉树的顺序存储结构中,试编写非递归算法对该树进行中序遍历。
void Inorder(int root, int n ,T trees[])//n个节点的完全二叉树,存储在数组trees中
{
if(root == 0 ) return;
stack<int> s;
while( root <=n || !s.empty() )
{
if(root <=n) {
s.push(root);
root = root*2; //左子树入栈
}
else
{
root = s.top(); //取出左子树栈顶访问
visit (trees[root]);
s.pop();
root = root*2+1; //转向右子树
}
}
}
3.判别两棵二叉树是否等价。
如果T1和T2都是空二叉树,或T1和T2的根结点的值相同,并且T1的左子树与T2的左子树是等价的;T1的右子树与T2的右子树是等价的。
bool judgetree(treenode *s1,treenode *s2){
if(s1==NULL&&s2==NULL)
{
return true;
}
if(s1==NULL||s2==NULL)
{
return false;
}
if(s1->val!=s2->val)
return false;
return judgetree(s1->left,s2->left)&&judgetree(s1->right,s2->right);
}
4.设计一个实现一棵二叉树复制的算法。
void copytree(treenode *from, treenode * & to )//拷贝from到to树,注意to参数为引用
{
if (from == NULL) {to = NULL; return;}
to = new treenode ;to->data = from->data ; //1/拷贝根节点
copytree(from->lchild,to->lchild);//2/拷贝左子树
copytree(from->rchild,to->rchild)//3/拷贝右子树
}
5.编写一个将二叉树的所有叶子结点从左向右链接成单链表的算法。
void Creatlist(BinaryTreeNode*T,listNode*&L)//利用先序遍历递归,用链表L把结点串起来
{
if (T != NULL) {
if (T->left == NULL&&T->right == NULL) //如果左右子树为空,则为叶子结点
{
listNode *temp = new listNode; //串起来
temp->data = T->value;
L->next = temp;
L = L->next;
}
Creatlist(T->left,L); //递归左子树
Creatlist(T->right,L); //递归右子树
}
L->next = NULL;
}
原博客:
用递归法把二叉树的叶子结点按从左到右的顺序连成一个单链表_小树学信奥-CSDN博客_设计一个算法将二叉树的叶结点按从左到右
6.设具有n个结点的完全二叉树采用顺序存储结构,试写一个算法将该顺序存储结构转换为二叉链式存储结构。
void transfer(int from, int n ,T trees[], treenode * & to )//拷贝from到to树,注意to参数为引用
{
if (form == 0 || from > n ) {to = NULL; return;}
to = new treenode ;to->data =trees[ from] ; //1/拷贝根节点
transfer(from*2,to->lchild);//2/拷贝左子树
transfer(from*2+1,to->rchild)//3/拷贝右子树
}
7.7.设具有n个结点的二叉树采用二叉链式存储结构,试写出一个算法将该二叉链式存储结构转换为顺序存储结构。
//注意顺序结构需要的空间为n?当然不是,因为不会完全二叉树
void transfer(T trees[],int to, treenode * from )//值为0代表空树 调用时trees值全部为0;to为1;
{
if (form ==NULL ) return;
trees[ to]= from->data ; //1/拷贝根节点
transfer(trees,to*2,from->lchild);//2/拷贝左子树
transfer(trees,to*2+1,from->rchild)//3/拷贝右子树
}
8.获取节点值为x的层次
void binTree::getLevel3(TreeNode * proot,int x, int &leveloutput)
{
int static level = 1 ;
if (proot != NULL)
{
if (proot ->data == x ) leveloutput = level; //只赋值一次
++level;//进入下一层,层次增1
getLevel3(proot->lchild ,x,leveloutput);
//--level;++level; //所以这里可以不要这2个语句,刚好抵消
getLevel3(proot->rchild ,x,leveloutput);
--level;//退回到上一层,层数减1,这是回溯步
}
}
9.获取节点的路径
类似第八题的思路
void binTree::getPath(TreeNode * proot,int x,stack <int> &sx, bool &over )
{
if (!over && proot != NULL)
{
sx.push (proot ->data);//进入下一层,该节点进栈
if (proot ->data == x ) over = true;
if (!over)
getPath(proot->lchild ,x,sx,over); //如果找到,直接退出,否则遍历左子树
if (!over)
getPath(proot->rchild ,x,sx,over); //如果左子树找到,直接退出,否则遍历右子树
if (!over)
sx.pop ();
//退回到上一层,节点出栈,这是回溯步,如果已经发现,不退栈,保持找到的路径值,否则直接退出
}
}
10.先序遍历倒数第k个节点
//先序倒数第k个节点,即正数第n-k+1 个节点,这个实现略
//可以采用另外一个做法来实现:先序遍历的逆序列刚好就是使用右、左、根遍历的序列,
//所以倒数第k个先序序列,刚好就是使用先右再左最后根的遍历次序的 第k个节点
TreeNode * getLastNumKpreorder(TreeNode * proot,int k)//遍历全部节点
{
static int count = 0 ;
static TreeNode * pnumK = NULL;//这个变量不是静态,可以吗?为什么
if (proot != NULL)
{
getLastNumKpreorder(proot->rchild ,k);//先遍历右子树
getLastNumKpreorder(proot->lchild ,k);//再遍历左子树
//最后访问操作根
++count;
if (count == k ) pnumK = proot;
}
return pnumK;
}//可以使用外部变量或者引用参数代替内部静态变量来实现