小说网 找小说 无限小说 烟雨红尘 幻想小说 酷文学 深夜书屋

把二元查找树转变成排序的双向链表

题目: 输入一颗二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。

  

转换成双向链表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);
#endif
BSTree.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 运行效果

   




posted on 2014-09-09 17:18  牛栏山1  阅读(107)  评论(0编辑  收藏  举报

导航