// 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;
}
二叉树与二叉排序树的创建于遍历
最新推荐文章于 2022-08-04 17:15:46 发布