把二元查找树转变成排序的双向链表
题目: 输入一颗二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。
转换成双向链表4=6=8=10=12=14=16
首先,我们定义的二元查找树结点的数据结构如下:
struct BSTreeNode
{
int m_nValue;
BSTreeNode * m_pLeft;
BSTreeNode * m_pRIght;
};
解题思路:
1、构建一颗二叉查找树。
2、定义一个双向链表的全局变量pHead。
3、因为要保证链表的顺序,所以需要中序遍历。
4、因为不能创建任何新的结点,所以,需要重复利用树的结点。
5、因为,没有前驱和后继指针,所以,需要利用二叉树的左孩子指针和右孩子指针,将左孩子指针作为前驱指针,将右孩子指针作为后继指针。
6、每个结点的前驱由自己设置,每个结点的后继由下一个结点设置。
具体代码如下:
BSTree.h内容
#ifndef _BSTREE_H_ #define _BSTREE_H_ typedef struct _tagBSTreeNode { int m_nVal; _tagBSTreeNode * m_pLeft; _tagBSTreeNode * m_pRight; }BSTreeNode; extern BSTreeNode * pHead; //追加树结点 int AppendNode(BSTreeNode **, int nNum); //打印树结点 void PrintTree(BSTreeNode ** ppTree); //释放树 void Clear(BSTreeNode ** ppTree); //转换为有序双链表 void InOrderTree(BSTreeNode ** ppTree); //销毁链表 void ClearList(BSTreeNode * pHead); //打印链表 void PrintList(BSTreeNode * pHead); //打印路径 void PrintPath(BSTreeNode * pHead, int nSum); #endifBSTree.cpp内容
#include <stdlib.h> #include <stdio.h> #include "BSTree.h"
//追加树结点 int AppendNode(BSTreeNode ** ppTree, int nNum) { BSTreeNode * pNewNode = NULL; if (!ppTree) return 0; if (*ppTree == NULL) { pNewNode = (BSTreeNode *)malloc(sizeof(BSTreeNode)); if (!pNewNode) return 0; pNewNode->m_nVal = nNum; pNewNode->m_pLeft = NULL; pNewNode->m_pRight = NULL; *ppTree = pNewNode; return 1; } if ((*ppTree)->m_nVal > nNum) { AppendNode(&((*ppTree)->m_pLeft), nNum); } else if ((*ppTree)->m_nVal < nNum) { AppendNode(&((*ppTree)->m_pRight), nNum); } else { printf("树结点已经存在.\n"); return 0; } return 1; } //打印树结点 void PrintTree(BSTreeNode ** ppTree) { if (!ppTree) return; if (*ppTree == NULL) { return; } if ((*ppTree)->m_pLeft) PrintTree(&((*ppTree)->m_pLeft)); if (*ppTree) printf("%d", (*ppTree)->m_nVal); if ((*ppTree)->m_pRight) PrintTree(&((*ppTree)->m_pRight)); }
//释放树 void Clear(BSTreeNode ** ppTree) { BSTreeNode * pLeftTree = NULL; BSTreeNode * pRightTree = NULL; if (!ppTree) return; if (*ppTree == NULL) return; if ((*ppTree)->m_pLeft) { pLeftTree = (*ppTree)->m_pLeft; Clear(&pLeftTree); } if ((*ppTree)->m_pRight) { pRightTree = (*ppTree)->m_pRight; Clear(&pRightTree); } if (*ppTree) { free(*ppTree); *ppTree = NULL; } return; }
//以左孩子为前驱 //以右孩子为后继 BSTreeNode * pHead = NULL; int nListLen = 0;
void AppendNode2List(BSTreeNode * pInput) { int nTemp = 0; BSTreeNode * pCurNode = NULL; if (pInput == NULL) return; if (!pHead) { pHead = pInput; pInput->m_pLeft = NULL; nListLen++; return; } pCurNode = pHead; while (nTemp < nListLen-1) { pCurNode = pCurNode->m_pRight; nTemp++; } pCurNode->m_pRight = pInput; pInput->m_pLeft = pCurNode; nListLen++; return ; }
//打印树结点 void InOrderTree(BSTreeNode ** ppTree) { if (!ppTree) return; if (*ppTree == NULL) { return; } if ((*ppTree)->m_pLeft) InOrderTree(&((*ppTree)->m_pLeft)); if (*ppTree) AppendNode2List(*ppTree); if ((*ppTree)->m_pRight) InOrderTree(&((*ppTree)->m_pRight)); }
void PrintList(BSTreeNode * pHead) { BSTreeNode * pCurNode = NULL; if (!pHead) return; pCurNode = pHead; printf("\n链表数据:\n"); while (pCurNode) { printf("%d ", pCurNode->m_nVal); pCurNode = pCurNode->m_pRight; } return; }
void ClearList(BSTreeNode * pHead) { BSTreeNode * pCurNode = NULL; if (!pHead) return; while (pHead) { pCurNode = pHead->m_pRight; free(pHead); pHead = pCurNode; } return; }main.cpp内容:
//把二叉查找树转换为有序的双链表 //要求不可以创建新结点,只可以改变指针 //提示: //可以将左孩子用于指向前驱结点 //可以将右孩子用于指向后继结点 #define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <stdio.h> #include <crtdbg.h> #include "BSTree.h" void main() { BSTreeNode * pTree = NULL; if (AppendNode(&pTree, 5) == NULL) { printf("追加失败.\n"); return; } if (AppendNode(&pTree, 4) == NULL) { printf("追加失败.\n"); return; } if (AppendNode(&pTree, 3) == NULL) { printf("追加失败.\n"); return; } if (AppendNode(&pTree, 2) == NULL) { printf("追加失败.\n"); return; } if (AppendNode(&pTree, 1) == NULL) { printf("追加失败.\n"); return; } printf("二叉搜索树:\n"); PrintTree(&pTree); InOrderTree(&pTree); PrintList(pHead); printf("\n"); ClearList(pHead); _CrtDumpMemoryLeaks(); system("pause"); return; }运行效果如图1所示:
图1 运行效果
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步