// 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; }