bst double Linked List

struct BSTreeNode //二分查找树中的一个节点
    {
        int          m_nValue; // 节点的值
        BSTreeNode  *m_pLeft;  // 左指针域
        BSTreeNode  *m_pRight; // 右指针域
    };

然后,我们就可以根据以上递归的思想一步一步写出c++源码了

BSTreeNode* ConvertNode(BSTreeNode* pNode, bool asRight)
   //如果是空数,那么返回空指针
      if(!pNode)
            return NULL;
     //定义两个指针,存放当前节点的左双向链表的根河和右双向链表的根
      BSTreeNode *pLeft = NULL;
      BSTreeNode *pRight = NULL;

      //先将左子数转换为双向链表,注意这里的第二个参数是false,表示左子数节点转换为左双向链表
      if(pNode->m_pLeft)
            pLeft = ConvertNode(pNode->m_pLeft, false);

      //如果左双向链表不为空,那么就正确地链接到当前节点pNode上
      if(pLeft)
      {
            pLeft->m_pRight = pNode;
            pNode->m_pLeft = pLeft;
      }

      //再将右子数转换为双向链表,注意这里的第二个参数是true,表示右子数节点转换为右双向链表
      if(pNode->m_pRight)
            pRight = ConvertNode(pNode->m_pRight, true);

      //如果右双向链表不为空,那么就正确地链接到当前节点pNode上
      if(pRight)
      {
            pNode->m_pRight = pRight;
            pRight->m_pLeft = pNode;
      }
    
 //到了这里,当前节点pNode以及它的子数已经被转换为双向链表了,最后一步,就是怎样将转换好的双向链表的头指针返回呢?显然,我们应该根据当前节点在原子数中的位置判断,如果当前节点pNode在原来的树种是以右节点的形式存在的,那么以当前节点为头指针的双向链表应该返回整个以pNode为根节点的子数中最小的节点,也即最左的节点,反之,则返回最右的节点,以下代码便是这段文字的代码描述
      BSTreeNode *pTemp = pNode;
      if(asRight)
      {
            while(pTemp->m_pLeft)
                  pTemp = pTemp->m_pLeft;
      }
      else
      {
            while(pTemp->m_pRight)
                  pTemp = pTemp->m_pRight;
      }
      return pTemp;
}

最后,我们就可以用一个主函数来对以上一段程序进行包装,以形成一个独立功能的函数

BSTreeNode* Convert(BSTreeNode* pHeadOfTree)
{
      //这里,第二个参数为true,即把整个树当做是右子数看待,这样,最终就能返回整个树中的最小的节点了.
      return ConvertNode(pHeadOfTree, true);
}


思路之二是中序遍历二元查找树,由于中序遍历是从小到大遍历的,所以可以假设在遍历某一个子树的根节点的时候其左子树已经是一个排序双向链表了,并且如果再得到该双向链表的为指针,可以很轻易地将其与根节点相连,然后同样可以使得右子数成为一个排序双向链表,然后将根节点轻而易举的链接到右子数组成的排序双向链表.
//此函数的功能是将以pNode为根的树转换为排序双向链表,并且将她链接到以pLastNodeInList为已经调整好的双向链表的尾节点上
void ConvertNode(BSTreeNode* pNode, BSTreeNode*& pLastNodeInList)
{
      if(pNode == NULL)
            return;

      BSTreeNode *pCurrent = pNode;

      //装换左子树
      if (pCurrent->m_pLeft != NULL)
            ConvertNode(pCurrent->m_pLeft, pLastNodeInList);

      //将当前节点链接到已调整好的双向链表的尾节点,
pLastNodeInList为已经转换好的双向链表的尾指针
      pCurrent->m_pLeft = pLastNodeInList; 
      if(pLastNodeInList != NULL)
            pLastNodeInList->m_pRight = pCurrent;
    //然后当前节点就成了双向链表中的最后一个节点
      pLastNodeInList = pCurrent;
      //所以转换右子数的时候,可以很顺利地将双向链表中的最后一个节点与右子数装换好的双向链表相连
      if (pCurrent->m_pRight != NULL)
            ConvertNode(pCurrent->m_pRight, pLastNodeInList);
}


BSTreeNode* Convert_Solution1(BSTreeNode* pHeadOfTree)
{
    //由于一开始已经调整好的双向链表为空,所以尾指针为空
      BSTreeNode *pLastNodeInList = NULL;
    //将整个树转换为双向链表的时候,
pLastNodeInList就成了链表中的最后一个节点
      ConvertNode(pHeadOfTree, pLastNodeInList);
      //然后链表指针不断向前移动,便得到了头节点的指针
      BSTreeNode *pHeadOfList = pLastNodeInList;
      while(pHeadOfList && pHeadOfList->m_pLeft)
            pHeadOfList = pHeadOfList->m_pLeft;
      return pHeadOfList;
}


将排序二叉树转化成双向链表,应该是一道很常见的面试题目,网上的实现比较多,有用递归也有用中序遍历法的。看到一位外国友人的实现,还是比较清晰的,思路如下:

1,如果左子树不为null,处理左子树
   1.a)递归转化左子树为双向链表;
   1.b)找出根结点的前驱节点(是左子树的最右的节点)
   1.c)将上一步找出的节点和根结点连接起来
2,如果右子树不为null,处理右子树(和上面的很类似)
   1.a)递归转化右子树为双向链表;
   1.b)找出根结点的后继节点(是右子树的最左的节点)
   1.c)将上一步找出的节点和根结点连接起来
3,找到最左边的节点并返回

附上国外友人的链接:http://www.geeksforgeeks.org/in-place-convert-a-given-binary-tree-to-doubly-linked-list/

下面是代码实现:
bintree2listUtil函数返回的node* 是root节点,bintree2list函数返回的是头节点
This is the core function to convert Tree to list. This function follows
  steps 1 and 2 of the above algorithm */
node* bintree2listUtil(node* root)
{
    // Base case
    if (root == NULL)
        return root;
 
    // Convert the left subtree and link to root
    if (root->left != NULL)
    {
        // Convert the left subtree
        node* left = bintree2listUtil(root->left);
 
        // Find inorder predecessor. After this loop, left
        // will point to the inorder predecessor
        for (; left->right!=NULL; left=left->right);
 
        // Make root as next of the predecessor
        left->right = root;
 
        // Make predecssor as previous of root
        root->left = left;
    }
 
    // Convert the right subtree and link to root
    if (root->right!=NULL)
    {
        // Convert the right subtree
        node* right = bintree2listUtil(root->right);
 
        // Find inorder successor. After this loop, right
        // will point to the inorder successor
        for (; right->left!=NULL; right = right->left);
 
        // Make root as previous of successor
        right->left = root;
 
        // Make successor as next of root
        root->right = right;
    }
 
    return root;
}
 
// The main function that first calls bintree2listUtil(), then follows step 3
//  of the above algorithm
node* bintree2list(node *root)
{
    // Base case
    if (root == NULL)
        return root;
 
    // Convert to DLL using bintree2listUtil()
    root = bintree2listUtil(root);
 
    // bintree2listUtil() returns root node of the converted
    // DLL.  We need pointer to the leftmost node which is
    // head of the constructed DLL, so move to the leftmost node
    while (root->left != NULL)
        root = root->left;
 
    return (root);

跟网型逆变器小干扰稳定性分析与控制策略优化研究(Simulink仿真实现)内容概要:本文围绕跟网型逆变器的小干扰稳定性展开分析,重点研究其在电力系统中的动态响应特性及控制策略优化问题。通过构建基于Simulink的仿真模型,对逆变器在不同工况下的小信号稳定性进行建模与分析,识别系统可能存在的振荡风险,并提出相应的控制优化方法以提升系统稳定性和动态性能。研究内容涵盖数学建模、稳定性判据分析、控制器设计与参数优化,并结合仿真验证所提策略的有效性,为新能源并网系统的稳定运行提供理论支持和技术参考。; 适合人群:具备电力电子、自动控制或电力系统相关背景,熟悉Matlab/Simulink仿真工具,从事新能源并网、微电网或电力系统稳定性研究的研究生、科研人员及工程技术人员。; 使用场景及目标:① 分析跟网型逆变器在弱电网条件下的小干扰稳定性问题;② 设计并优化逆变器外环与内环控制器以提升系统阻尼特性;③ 利用Simulink搭建仿真模型验证理论分析与控制策略的有效性;④ 支持科研论文撰写、课题研究或工程项目中的稳定性评估与改进。; 阅读建议:建议读者结合文中提供的Simulink仿真模型,深入理解状态空间建模、特征值分析及控制器设计过程,重点关注控制参数变化对系统极点分布的影响,并通过动手仿真加深对小干扰稳定性机理的认识。
好的,我可以帮你解决这个问题,以下是代码示例: ```python # 定义二叉查找树节点类 class BSTNode: def __init__(self, val): self.val = val self.left = None self.right = None # 定义二叉查找树类 class BST: def __init__(self): self.root = None def insert(self, val): node = BSTNode(val) if not self.root: self.root = node else: cur = self.root while cur: if val < cur.val: if not cur.left: cur.left = node break cur = cur.left else: if not cur.right: cur.right = node break cur = cur.right def print_tree(self): self._print_tree(self.root) def _print_tree(self, node): if not node: return self._print_tree(node.left) print(node.val, end=' ') self._print_tree(node.right) def inorder_traversal(self): res = [] self._inorder_traversal(self.root, res) return res def _inorder_traversal(self, node, res): if not node: return self._inorder_traversal(node.left, res) res.append(node.val) self._inorder_traversal(node.right, res) def convert_to_double_linked_list(self): head, tail = self._convert_to_double_linked_list(self.root) return head def _convert_to_double_linked_list(self, node): if not node: return None, None left_head, left_tail = self._convert_to_double_linked_list(node.left) right_head, right_tail = self._convert_to_double_linked_list(node.right) cur_head = cur_tail = node if left_tail: left_tail.right = node node.left = left_tail cur_head = left_head if right_head: node.right = right_head right_head.left = node cur_tail = right_tail return cur_head, cur_tail # 定义双链表节点类 class ListNode: def __init__(self, val): self.val = val self.prev = None self.next = None # 定义双链表类 class DoubleLinkedList: def __init__(self): self.head = None self.tail = None def add(self, val): node = ListNode(val) if not self.head: self.head = node self.tail = node else: self.tail.next = node node.prev = self.tail self.tail = node def forward_traversal(self): node = self.head while node: print(node.val, end=' ') node = node.next def backward_traversal(self): node = self.tail while node: print(node.val, end=' ') node = node.prev # 测试代码 if __name__ == '__main__': bst = BST() bst.insert(4) bst.insert(2) bst.insert(5) bst.insert(1) bst.insert(3) print('打印二叉查找树:') bst.print_tree() print('\n中序遍历二叉查找树:') print(bst.inorder_traversal()) print('打印转换后的双链表:') linked_list = DoubleLinkedList() linked_list.head = bst.convert_to_double_linked_list() linked_list.forward_traversal() print('\n按正序输出双链表中所有元素:') linked_list.forward_traversal() print('\n按反序输出双链表中所有元素:') linked_list.backward_traversal() ``` 输出结果为: ``` 打印二叉查找树: 1 2 3 4 5 中序遍历二叉查找树: [1, 2, 3, 4, 5] 打印转换后的双链表: 1 2 3 4 5 按正序输出双链表中所有元素: 1 2 3 4 5 按反序输出双链表中所有元素: 5 4 3 2 1 ``` 希望这个示例代码能够解决你的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值