二叉树与二叉排序树的创建于遍历

// TREE_IMPORTANT.cpp : 定义控制台应用程序的入口点。
//

#include "stdio.h"
#include "stdlib.h"
#include "iostream"
#include "stack"
#include "vector"

using namespace std;

typedef struct Node
{
	int data;
	struct Node * lc;
	struct Node * rc;
}Node, *TNode;

typedef struct Tree
{
	struct Node * root;
};

void PreOrder(Node * root);
void InOrder(Node * root);
void PostOrder(Node * root);
void InOrderTraverseNotRecursive(Node * root);

void InsertSort(int * arr, int length);


void CreateTree(Node * &root, int &index);

// 通过指向Node的指针的指针构建二叉树
// 只有通过指针的指针,才能创建
void CreateTree2(TNode * root, int &index);

// 先序建立二叉树
// 根据用户交互输入建立二叉树
// 通过引用传递
void CreateTreeByInput(Node * &root);

// 插入新的数据到已经存在的二叉排序树
// 通过指向指针的指针
void Insert2BST(TNode * root, int data);

// 通过引用创建二叉排序树
void CreateBST(Node * &root,int arr[], int left, int right);

// 通过指向节点的指针的指针添加节点
void InsertNode2BST(TNode *root, int data);
void InsertNode2BST2(TNode *root, int data);

// 通过指向指针的指针创建二叉排序树
void CreateBST2(TNode *root, int arr[], int left, int right);

// 插入到二叉排序树
// 通过对指向节点的指针的引用
void Insert2BST(Node * &root, int data);

//int elements[] = {1,2,4,8,-1,-1,9,-1,-1,5,-1,-1,3,6,-1,-1,7,-1,-1};
int elements[] = {1,2,4,8,-1,-1,9,-1,-1,5,10,-1,-1,-1,3,6,-1,-1,7,-1,-1};

int test[] = {5, 7, 1, 4, 3, 2, 9, 6, 8, 0};

int index = 0;

vector<int> all;
int main(int argc, char* argv[])
{
	// 使用对Node的NULL指针构建二叉树,传递对NULL指针的引用
	Tree T;
	T.root = NULL;
	// 通过对指针的引用为NULL指针申请内存
	CreateTree(T.root, index);
	PreOrder(T.root);
	//InOrder(T.root);
	cout<<endl;

	// 通过指向指针的指针创建二叉树
	index  = 0;
	Tree T2;
	T2.root = NULL;
	cout<<"通过指向指针的指针创建二叉树"<<endl;
	// 通过对指针的引用为NULL指针申请内存
	CreateTree2(&T2.root, index);
	PreOrder(T2.root);
	cout<<endl;

	// 遍历二叉树
	all.clear();
	// 先序遍历二叉树
	cout<<"先序遍历二叉树"<<endl;
	PreOrder(T.root);
	cout<<endl;
	int * arr = new int[all.size()];
	for(int i = 0; i < all.size(); i++)
		arr[i] = all[i];
	InsertSort(arr, all.size());
	Tree T3;
	T3.root = NULL;
	CreateBST(T3.root, arr, 0, all.size() - 1);
	cout<<"二叉排序的中序遍历"<<endl;
	//InOrderTraverseNotRecursive(T3.root);
	InOrder(T3.root);
	cout<<endl;


	cout<<"/"<<endl;
	// 测试通过指向指针的指针创建二叉排序树
	Tree T4;
	T4.root = NULL;
	CreateBST2(&T4.root, arr, 0, all.size() - 1);
	cout<<"通过指向指针的指针创建排序二叉树,中序遍历"<<endl;
	InOrder(T4.root);
	cout<<endl;


	// 通过对指针的引用创建二叉排序树
	cout<<"通过引用不停的插入新的节点,创建二叉排序树"<<endl;
	Tree T5;
	T5.root = NULL;
	for(int i = 0; i < 10; i++)
	{
		Insert2BST(T5.root, test[i]);
	}
	InOrder(T5.root);
	cout<<endl;

	system("pause");
	return 0;
}

// 通过指针的引用创建二叉树
// 如果不是引用,指向Node的指针为NULL, 指针为值传递,在调用函数中创建的Node不会和上一层的函数关联起来
// 所以最终的二叉树还是NULL
// 使用对Node的NULL指针构建二叉树,传递对NULL指针的引用
void CreateTree(Node * &root, int &index)
{
	int data = elements[index];
	if(data == -1)
		return; // 叶子节点

	root = new Node;
	root->data = data;
	root->lc = NULL;
	root->rc = NULL;

	CreateTree(root->lc, ++index);
	CreateTree(root->rc, ++index);
}

// 通过指向Node的指针的指针构建二叉树
// 只有通过指针的指针,才能创建
void CreateTree2(TNode * root, int &index)
{
	int data = elements[index];
	if(data == -1)
		return; // 叶子节点

	*root = new Node;
	(*root)->data = data;
	(*root)->lc = NULL;
	(*root)->rc = NULL;

	CreateTree2(&(*root)->lc, ++index);
	CreateTree2(&(*root)->rc, ++index);
}

// 先序建立二叉树
// 根据用户交互输入建立二叉树
// 通过引用传递
void CreateTreeByInput(Node * &root)
{
	int data;
	scanf("%d", &data);
	if(data == -1)
		return; // 叶子节点

	root = new Node;

	root->data = data;
	root->lc = NULL;
	root->rc = NULL;

	CreateTreeByInput(root->lc);
	CreateTreeByInput(root->rc);
}


// 先序遍历
void PreOrder(Node * root)
{
	if(root)
	{
		printf("%3d", root->data);
		all.push_back(root->data);
		PreOrder(root->lc);
		PreOrder(root->rc);
	}
}

// 中序遍历
void InOrder(Node * root)
{
	if(root)
	{
		InOrder(root->lc);
		printf("%3d", root->data);
		InOrder(root->rc);
	}
}

// 后序遍历
void PostOrder(Node * root)
{
	if(root)
	{
		PostOrder(root->lc);
		PostOrder(root->rc);
		printf("%3d", root->data);
	}
}

// 中序非递归遍历
void InOrderTraverseNotRecursive(Node * root)
{
	stack<Node *> s;
	s.push(root);

	while(!s.empty())
	{
		Node * p = s.top();
		while( p != NULL )
		{
			s.push(p->lc);
			p = s.top();
		}

		s.pop();

		if(!s.empty())
		{
			Node * t = s.top();
			s.pop();
			printf("%3d", t->data);
			s.push(t->rc);
		}
	}
}

void InsertSort(int * arr, int length)  
{  
    for (int i=1; i < length; i++)  
    {  
        if (arr[i] < arr[i-1])  
        {  
            int temp = arr[i];  
            int j = i - 1;  
            do   
            {  
                arr[j+1] = arr[j];  
                j = j - 1;  
            } while (j >= 0 && arr[j] > temp);  
            arr[j+1] = temp;  
        }
    }
}

// 插入新的数据到已经存在的二叉排序树
// 通过指向指针的指针
void Insert2BST(TNode * root, int data)
{
	while(*root)
	{
		if((*root)->data < data)
		{
			(*root) = (*root)->lc;
		}
		else
		{
			(*root) = (*root)->rc;
		}
	}

	(*root) = new Node;
	(*root)->data = data;
	(*root)->lc = NULL;
	(*root)->rc = NULL;
}


// 插入到二叉排序树
// 通过对指向节点的指针的引用
void Insert2BST(Node * &root, int data)
{
	if(root == NULL)
	{
		root = new Node;
		root->data = data;
		root->lc = NULL;
		root->rc = NULL;
		return;
	}
	else
	{
		if(data < root->data)
		{
			Insert2BST(root->lc, data);
		}
		else
		{
			Insert2BST(root->rc, data);
		}
	}
}


// 通过引用创建二叉排序树
void CreateBST(Node * &root,int arr[], int left, int right)
{
	if(left <= right)
	{
		int mid = (left + right)/2;

		root = new Node;
		root->data = arr[mid];
		root->lc = NULL;
		root->rc = NULL;

		CreateBST(root->lc, arr, left, mid - 1);
		CreateBST(root->rc, arr, mid + 1, right);
	}
}

// 通过指向指针的指针创建二叉排序树
// 暂时的代码和引用没有区别
void CreateBST2(TNode *root, int arr[], int left, int right)
{
	if(left <= right)
	{
		int mid = (left + right)/2;

		int temp = arr[mid];
		InsertNode2BST2(root, temp);

		CreateBST2(root, arr, left, mid - 1);
		CreateBST2(root, arr, mid + 1, right);
	}
}

// 通过指向节点的指针的指针添加节点
// 每次插入都需要从根节点找到带插入的节点位置
// 这段代码,虽然每次TNode * root都是值传递,但是每次代码运行,二叉树的根节点的指针都移动了
// 每次插入节点,根节点指针都移动到最后一个元素,然后指向根节点的指针的指针又总是指向根节点
// 所以这段代码是有问题的***** @@@@@ %%%%%%%%%
void InsertNode2BST(TNode *root, int data)
{
	while(*root)
	{
		if((*root)->data < data)
		{
			(*root) = (*root)->lc;
		}
		else
		{
			(*root) = (*root)->rc;
		}
	}
	(*root) = new Node;
	(*root)->data = data;
	(*root)->lc = NULL;
	(*root)->rc = NULL;
}

// 通过移动指向根节点的指针的指针,找到待插入的位置
// 这样也不会移动原来的根节点
void InsertNode2BST2(TNode *root, int data)
{
	while(*root)
	{
		if((*root)->data > data)
		{
			root = &(*root)->lc;
		}
		else
		{
			root = &(*root)->rc;
		}
	}
	(*root) = new Node;
	(*root)->data = data;
	(*root)->lc = NULL;
	(*root)->rc = NULL;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值