二叉排序树在不借助新节点只修改指针转换为双链表
2011-03-14 11:41
429 查看
本题目来源于网络
题目:把二元查找树转变成排序的双向链表
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ /
6 14
/ / / /
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
头文件如下:
实现文件如下:
----------------------------------------------------------------------------------------------------
下面给出二叉排序树类,在其中实现了上述功能:
头文件如下:
实现文件如下:
题目:把二元查找树转变成排序的双向链表
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ /
6 14
/ / / /
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
头文件如下:
/******************************************************************** 1.把二元查找树转变成排序的双向链表 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 要求不能创建任何新的结点,只调整指针的指向。 10 / / 6 14 / / / / 4 8 12 16 转换成双向链表 4=6=8=10=12=14=16。 首先我们定义的二元查找树 节点的数据结构如下: struct BSTreeNode { int m_nValue; // value of node BSTreeNode *m_pLeft; // left child of node BSTreeNode *m_pRight; // right child of node }; *********************************************************************/ #ifndef _BINARYTREE_TO_DOUBLELINKLIST_H_ #define _BINARYTREE_TO_DOUBLELINKLIST_H_ ////////////////////////////////////////////////////////////////////////// #include <tchar.h> #include <stdio.h> ////////////////////////////////////////////////////////////////////////// struct BTTDL_Node { int nValue; // value of node BTTDL_Node *pLeft; // left child of node BTTDL_Node *pRight; // right child of node }; // 添加一个节点 bool BTTDL_AddBinaryTreeNode(BTTDL_Node* &pRootNode, int nNodeValue); // 打印二叉排序树 bool BTTDL_PrintBinaryTree(const BTTDL_Node *pRootNode); // 二叉排序树转换为排序的双链表 BTTDL_Node* BTTDL_BinaryTreeToDoubleLinkList(BTTDL_Node *pRootNode, BTTDL_Node* &pDListHead, BTTDL_Node* &pDlistIndex); // 添加树中遍历到的一个节点到双链表中 void BTTDL_AddBTreeNodeToDoubleLinkList(BTTDL_Node *pBTreeNode, BTTDL_Node* &pDListHead, BTTDL_Node* &pDlistIndex); // 打印双链表 void BTTDL_PrintDoubleLinkList(BTTDL_Node *pDoubleListHead); void BTTDL_PrintDoulbeLinkListFromEnd(BTTDL_Node *pDoubleListEnd); ////////////////////////////////////////////////////////////////////////// #endif
实现文件如下:
#include "BinaryTreeToDoubleLinkList.h" ////////////////////////////////////////////////////////////////////////// // 添加一个节点 bool BTTDL_AddBinaryTreeNode(BTTDL_Node* &pRootNode, int nNodeValue) { // 参数有效性 if (pRootNode == NULL) { // 创建节点 BTTDL_Node *pNewNode = new BTTDL_Node; if (pNewNode == NULL) { return false; } // 初始化节点 pNewNode->nValue = nNodeValue; pNewNode->pLeft = NULL; pNewNode->pRight = NULL; pRootNode = pNewNode; return true; } // 与根节点比较,小于根节点值则插入左子树,否则插入右子树 if (nNodeValue < pRootNode->nValue) { return BTTDL_AddBinaryTreeNode(pRootNode->pLeft, nNodeValue); } else { return BTTDL_AddBinaryTreeNode(pRootNode->pRight, nNodeValue); } return false; } // 打印二叉排序树 bool BTTDL_PrintBinaryTree(const BTTDL_Node *pRootNode) { // 参数有效性 if (pRootNode == NULL) { return false; } // 打印左子树 BTTDL_PrintBinaryTree(pRootNode->pLeft); // 打印根节点 printf("%d, ", pRootNode->nValue); // 打印右子树 BTTDL_PrintBinaryTree(pRootNode->pRight); return true; } // 二叉排序树转换为排序的双链表 BTTDL_Node* BTTDL_BinaryTreeToDoubleLinkList(BTTDL_Node *pRootNode, BTTDL_Node* &pDListHead, BTTDL_Node* &pDlistIndex) { // 参数有效性 if (pRootNode == NULL) { return NULL; } // 中序遍历左子树 if (pRootNode->pLeft != NULL) { BTTDL_BinaryTreeToDoubleLinkList(pRootNode->pLeft, pDListHead, pDlistIndex); } // 当前遍历到的节点添加到链表 BTTDL_AddBTreeNodeToDoubleLinkList(pRootNode, pDListHead, pDlistIndex); // 中序遍历右子树 if (pRootNode->pRight != NULL) { BTTDL_BinaryTreeToDoubleLinkList(pRootNode->pRight, pDListHead, pDlistIndex); } return NULL; } // 添加树中遍历到的一个节点到双链表中 void BTTDL_AddBTreeNodeToDoubleLinkList(BTTDL_Node *pBTreeNode, BTTDL_Node* &pDListHead, BTTDL_Node* &pDlistIndex) { // 参数有效性 if (pBTreeNode == NULL) { return; } // 节点pBTreeNode是当前遍历到的树的节点 if (pBTreeNode->pLeft == NULL) { // 得到链表头节点 if (pDListHead == NULL) { pDListHead = pBTreeNode; pDlistIndex = pBTreeNode; } // 连接到链表尾部 else { pDlistIndex->pRight = pBTreeNode; pBTreeNode->pLeft = pDlistIndex; pDlistIndex = pBTreeNode; } } // 连接到链表尾部 else { pDlistIndex->pRight = pBTreeNode; pBTreeNode->pLeft = pDlistIndex; pDlistIndex = pBTreeNode; } } // 打印双链表 void BTTDL_PrintDoubleLinkList(BTTDL_Node *pDoubleListHead) { // 参数有效性 if (pDoubleListHead == NULL) { return; } // 打印 printf("/n"); BTTDL_Node *pWork = pDoubleListHead; while (pWork != NULL) { printf("%d, ", pWork->nValue); pWork = pWork->pRight; } } void BTTDL_PrintDoulbeLinkListFromEnd(BTTDL_Node *pDoubleListEnd) { // 参数有效性 if (pDoubleListEnd == NULL) { return; } // 打印 printf("/n"); BTTDL_Node *pWork = pDoubleListEnd; while (pWork != NULL) { printf("%d, ", pWork->nValue); pWork = pWork->pLeft; } }
----------------------------------------------------------------------------------------------------
下面给出二叉排序树类,在其中实现了上述功能:
头文件如下:
/******************************************************************** 二叉排序树 *********************************************************************/ #ifndef _CBINARY_SEARCH_TREE_H_ #define _CBINARY_SEARCH_TREE_H_ ////////////////////////////////////////////////////////////////////////// #include <tchar.h> ////////////////////////////////////////////////////////////////////////// struct BSTree_Node { int nValue; // value of node BSTree_Node *pLeft; // left child of node BSTree_Node *pRight; // right child of node }; ////////////////////////////////////////////////////////////////////////// class CBinarySearchTree { public: CBinarySearchTree(); ~CBinarySearchTree(); public: // 添加一个结点 bool AddNode(const BSTree_Node *pNode); // 中序遍历 void InorderTraversal(void); // 清除 void Clear(void); public: // 二叉排序树转换为排序的双链表 void TransToDbList(BSTree_Node* &pDbListHead, BSTree_Node* &pDblistRear); // 清除双链表 void ClearDbList(BSTree_Node* &pDbListHead); public: // 向根结点为pRootNode的二叉排序树中添加一个结点 static bool AddNode(BSTree_Node* &pRootNode, const BSTree_Node *pNode); // 中序遍历根结点为pRootNode的二叉排序树 static void InorderTraversal(const BSTree_Node *pRootNode); // 清除 static void Clear(BSTree_Node* &pRootNode); // 添加树中遍历到的一个节点到双链表中 static void AddInorderBTreeNodeToDbList(BSTree_Node *pBTreeNode, BSTree_Node* &pDbListHead, BSTree_Node* &pDblistRear); // 二叉排序树转换为排序的双链表 static void TransToDbList(BSTree_Node *pRootNode, BSTree_Node* &pDbListHead, BSTree_Node* &pDblistRear); // 打印双链表 static void PrintDbListFromHead(BSTree_Node *pDbListHead); static void PrintDbListFromRear(BSTree_Node *pDbListRear); private: // 防止使用拷贝构造及赋值函数 CBinarySearchTree(const CBinarySearchTree &otherBSTree); CBinarySearchTree& operator =(const CBinarySearchTree &otherBSTree); private: BSTree_Node *m_pBSTreeRoot; // 二叉排序树根结点 bool m_bTransToDbList; // 记录是否转换为双链表 }; ////////////////////////////////////////////////////////////////////////// #endif
实现文件如下:
#include "CBinarySearchTree.h" #include <stdio.h> ////////////////////////////////////////////////////////////////////////// CBinarySearchTree::CBinarySearchTree() { m_pBSTreeRoot = NULL; m_bTransToDbList = false; } CBinarySearchTree::~CBinarySearchTree() { Clear(); } // 添加一个结点 bool CBinarySearchTree::AddNode(const BSTree_Node *pNode) { return AddNode(m_pBSTreeRoot, pNode); } // 中序遍历 void CBinarySearchTree::InorderTraversal(void) { InorderTraversal(m_pBSTreeRoot); } // 清除 void CBinarySearchTree::Clear(void) { if (m_bTransToDbList) { ClearDbList(m_pBSTreeRoot); } else { Clear(m_pBSTreeRoot); } } // 二叉排序树转换为排序的双链表 void CBinarySearchTree::TransToDbList(BSTree_Node* &pDbListHead, BSTree_Node* &pDblistRear) { TransToDbList(m_pBSTreeRoot, pDbListHead, pDblistRear); m_bTransToDbList = true; m_pBSTreeRoot = pDbListHead; } // 清除双链表 void CBinarySearchTree::ClearDbList(BSTree_Node* &pDbListHead) { // 参数有效性 if (pDbListHead == NULL) { return; } // 释放结点 BSTree_Node *pWork = pDbListHead; BSTree_Node *pDel = NULL; while (pWork != NULL) { pDel = pWork; pWork = pWork->pRight; delete pDel; pDel = NULL; } pDbListHead = NULL; } // 向根结点为pRootNode的二叉排序树中添加一个结点 bool CBinarySearchTree::AddNode(BSTree_Node* &pRootNode, const BSTree_Node *pNode) { // 参数有效性 if (pNode == NULL) { return false; } // 未创建树的根结点 if (pRootNode == NULL) { // 创建节点 BSTree_Node *pNewNode = new BSTree_Node(); if (pNewNode == NULL) { return false; } // 初始化节点 pNewNode->nValue = pNode->nValue; pNewNode->pLeft = NULL; pNewNode->pRight = NULL; pRootNode = pNewNode; return true; } // 与根节点比较,小于根节点值则插入左子树,否则插入右子树 return (pNode->nValue < pRootNode->nValue) ? AddNode(pRootNode->pLeft, pNode) : AddNode(pRootNode->pRight, pNode); } // 中序遍历根结点为pRootNode的二叉排序树 void CBinarySearchTree::InorderTraversal(const BSTree_Node *pRootNode) { // 参数有效性 if (pRootNode == NULL) { return; } // 打印左子树 InorderTraversal(pRootNode->pLeft); // 打印根节点 printf("%d, ", pRootNode->nValue); // 打印右子树 InorderTraversal(pRootNode->pRight); return; } // 清除 void CBinarySearchTree::Clear(BSTree_Node* &pRootNode) { // 参数有效性 if (pRootNode == NULL) { return; } // 释放根结点 BSTree_Node *pLeft = pRootNode->pLeft; BSTree_Node *pRight = pRootNode->pRight; delete pRootNode; pRootNode = NULL; // 释放左子树 Clear(pLeft); // 释放右子树 Clear(pRight); } // 添加树中遍历到的一个节点到双链表中 void CBinarySearchTree::AddInorderBTreeNodeToDbList(BSTree_Node *pBTreeNode, BSTree_Node* &pDbListHead, BSTree_Node* &pDblistRear) { // 参数有效性 if (pBTreeNode == NULL) { return; } // 节点pBTreeNode是当前遍历到的树的节点 if (pBTreeNode->pLeft == NULL) { // 得到链表头节点 if (pDbListHead == NULL) { pDbListHead = pBTreeNode; pDblistRear = pBTreeNode; } // 连接到链表尾部 else { pDblistRear->pRight = pBTreeNode; pBTreeNode->pLeft = pDblistRear; pDblistRear = pBTreeNode; } } // 连接到链表尾部 else { pDblistRear->pRight = pBTreeNode; pBTreeNode->pLeft = pDblistRear; pDblistRear = pBTreeNode; } } // 二叉排序树转换为排序的双链表 void CBinarySearchTree::TransToDbList(BSTree_Node *pRootNode, BSTree_Node* &pDbListHead, BSTree_Node* &pDblistRear) { // 参数有效性 if (pRootNode == NULL) { return; } // 中序遍历左子树 if (pRootNode->pLeft != NULL) { TransToDbList(pRootNode->pLeft, pDbListHead, pDblistRear); } // 当前遍历到的节点添加到链表 AddInorderBTreeNodeToDbList(pRootNode, pDbListHead, pDblistRear); // 中序遍历右子树 if (pRootNode->pRight != NULL) { TransToDbList(pRootNode->pRight, pDbListHead, pDblistRear); } } // 打印双链表 void CBinarySearchTree::PrintDbListFromHead(BSTree_Node *pDbListHead) { // 参数有效性 if (pDbListHead == NULL) { return; } // 打印 printf("/n"); BSTree_Node *pWork = pDbListHead; while (pWork != NULL) { printf("%d, ", pWork->nValue); pWork = pWork->pRight; } } // 打印双链表 void CBinarySearchTree::PrintDbListFromRear(BSTree_Node *pDbListRear) { // 参数有效性 if (pDbListRear == NULL) { return; } // 打印 printf("/n"); BSTree_Node *pWork = pDbListRear; while (pWork != NULL) { printf("%d, ", pWork->nValue); pWork = pWork->pLeft; } }
相关文章推荐
- PHP 将二叉查找树转换为双向链表,要求不能创建新节点,只能调节节点指针
- O(1)时间复杂度删除链表节点/复制带随机指针的链表
- 编码实现环状单向链表(尾指针直接指向头指针,中间没有空节点),去除连续的重复元素的操作
- 有一个特殊的链表,其中每个节点不但有指向下一个节点的指针pNext,还有一个指向链表中任意节点的指针pRand,如何拷贝这个特殊链表?
- Leetcode 237/83/203 两个指针与链表节点删除
- 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序
- c 链表之 快慢指针 查找循环节点
- 待整理。。。二叉排序树转换成为双向链表
- 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序
- 只给出链表某节点的的指针,如何删除它(不允许遍历)
- leetcode 328 --Odd Even Linked List 链表 双指针 移动节点
- C++链表插入,为什么头节点必须是二位指针
- 反转链表(不改变节点指针方向)
- 给定一个链表,一次颠倒链表k的节点并返回其修改列表。如果节点的数量不是k的倍数,那末最后的剩余节点应该保持原样。
- 链表节点面试100题系列之1将查找二叉树转换成有序的双向链表
- java实现输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head
- 等式转换(熟悉一下链表,指针引用)
- 链表的头指针在函数里修改怎么没有用?
- xStream完美转换XML、JSON xStream框架 xStream可以轻易的将Java对象和xml文档相互转换,而且可以修改某个特定的属性和节点名称,而且也支持json的转换; 前面有介
- 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)