数据结构-2

匿名 (未验证) 提交于 2019-12-02 23:51:01

  线性表结束了,接下来是其实线性结构就是树的一种特殊情况,

而我们的正常学习顺序也是从特殊到一般,所以也是理所应当的开始了解树的概念。

  树:


  基本概念

  1. 结点的度:子树个数
  2. 树的度:树的所有结点中最大的度数
  3. 叶结点:度为0的结点(没有子树)
  4. 父结点:子节点的上一级结点
  5. 子结点:父节点的子节点
  6. 兄弟结点:拥有同一个父节点
  7. 路径和路径长度:两个节点之间边的数量
  8. 子孙结点:一个结点往下所有结点都是子孙结点
  9. 祖先结点:拥有子孙结点的就是所有子孙结点的祖先结点
  10. 结点的层次:根节点在1层,其他任一结点的层数是其父节点+1
  11. 树的深度:该树中所有节点中,最大的层次就是这棵树的深度

我看对于树,这个考核大纲中,树的下面,只有二叉树...:

  • 树的定义和术语。
  • 二叉树(完全二叉树、满二叉树)的定义和性质、二叉树的存储结构(顺序表示法和二叉链表表示法)。
  • 二叉树遍历的递归算法。
  • 树和森林转换为二叉树的方法。

所以我也只去实现这里面的内容了。


  二叉树

什么是二叉树,二叉树的定义是?

二叉树的性质?

二叉树的存放方式?数组(顺序存储结构),链表

二叉树的主要操作集?是否为空IsEmpty,遍历Traversal(*重要),创建Create

  PS:遍历Traversal类型先序中序后序层次

数组实现:

#include <iostream> using namespace std;  struct Tree {     int* arr;     int lastIndex;     void Init()     {         arr=(int*)malloc(sizeof(int)*64);//为了方便写成固定         lastIndex = 0;         for (int i = 0; i < 64; i++)         {             arr[i] = 0x7fffffff;         }     }     void Add(int num)     {         arr[++lastIndex] = num;     }     void Remove(int i)     {         if(i<=lastIndex)         arr[i] = 0x7fffffff;     }     int GetLChild(int i)     {         return i * 2;     }     int GetRChild(int i)     {         return i * 2 + 1;     }     void PreTraversal(int root)     {         if ( arr[root]==0x7fffffff)return;         cout <<" ["<< arr[root]<<"] ";         PreTraversal(GetLChild(root));         PreTraversal(GetRChild(root));     }     void MidTraversal(int root)     {         if (arr[root] == 0x7fffffff)return;         MidTraversal(GetLChild(root));         cout << " [" << arr[root] << "] ";         MidTraversal(GetRChild(root));     }     void LastTraversal(int root)     {         if (arr[root] == 0x7fffffff)return;         LastTraversal(GetLChild(root));          LastTraversal(GetRChild(root));         cout << " [" << arr[root] << "] ";     }     void LayelTraversal(int root)     {         for (int i = 1; i < lastIndex+1; i++)         {             cout << " [" << arr[i] << "] ";         }      } };  int main() {     Tree a;     a.Init();     for (int i = 1; i < 10; i++)     {         a.Add(i);     }     cout << "前序";     a.PreTraversal(1);     cout <<endl;     cout << "中序";     a.MidTraversal(1);     cout << endl;     cout << "后序";     a.LastTraversal(1);     cout << endl;     cout << "层序";     a.LayelTraversal(1);     return 0; }
View Code

链表实现:

#include <iostream> using namespace std; /////////////////////////////////////////////////////////////////////////////队列 struct Queue {     int arr[1024];     int maxlen;     int left;//队列尾     int right;//队列头     int len;          void Init()     {         maxlen = 5;         left = 0;         right = -1;         len = 0;     }     bool IsNull()     {         if (len==0)return true;         return false;     }     bool IsFull()     {         if (len == maxlen)return true;         return false;     }     bool Enqueque(int num)     {         bool rt=false;         if (!IsFull())//一定不能满         {             right++;             arr[right%maxlen] = num;             len++;             rt = true;         }         return rt;     }      int Dequeque()     {         int rt = 0x7fffffff;         if (!IsNull())//一定不能是空的         {                          rt = arr[left % maxlen];             len--;             left++;         }         return rt;     }     void Show()     {         for (int i=0; i < len  ; i++)         {             cout<< arr[(left+i)%maxlen]<< " ";         }         cout << endl;     } }; //////////////////////////////////////////////////////////////////////////// struct Node {      Node* L;     Node* R;     int value; }; struct Tree {     Node* root;     int high;     int lastIndex;//用来插入的时候定位      void Init()     {         root = NULL;         high = 0;         lastIndex = 0;     }     void Add(int num)     {         if (root == NULL)//如此简单就将一个根节点插入了进来         {             root = (Node*)malloc(sizeof(Node));             root->value = num;             root->L = NULL;             root->R = NULL;             lastIndex = 1;         }         else         {//分两步,1计算结点插入的位置,2插入结点             //利用高度,得出批段,             //将lastindex- (2^high-1)可以算出该层的位置,             //然后根据2 , 4,8 来确定具体是谁的子树,?怎么实现呢?             //第一步生成一个数组,.....             bool* sx;             sx = (bool*)malloc(sizeof(bool)*high+1);             int tmp = pow(2, high);//最下一层,一共有多少个             int pos = lastIndex - (tmp - 1)+1; //最下一层从左往右数,的序号                          if (pos > tmp)              {//这种情况直接在左斜边插入一个                 high++;                 for (int i = 0; i < high; i++)sx[i] = false;             }             else             {                 int i = 0;                 while (tmp >= 1)                 {                     tmp /= 2;                     if (pos <= tmp)                     {                         sx[i++] = false;                         if(pos>tmp)                         pos -= tmp;                     }                     else                     {                         sx[i++] = true;                         if (pos > tmp)                          pos -= tmp;                     }                 }              }             //以上这个if else是结合pos和tmp定位到需要添加的地方(直接计算,免去遍历树的过程,提高效率)             cout << "添加路径:"; for (int i = 0; i < high; i++)cout << sx[i] << " "; cout << endl;//输出路径看看             Node* newNode = (Node*)malloc(sizeof(Node));             newNode->value = num;             newNode->L = NULL;             newNode->R = NULL;             lastIndex++;             Node* n = root;             //创建新结点              for (int i = 0; i < high; i++)             {                 if (sx[i])                 {//R                     if (i == high - 1 && n->R == NULL)                     {                         n->R = newNode;                     }                     else                     {                         n = n->R;                     }                 }                 else                 {//L                     if (i == high - 1 && n->L == NULL)                     {                         n->L = newNode;                     }                     else                     {                         n = n->L;                     }                 }             }             //知道位置了,就直接迭代插入         }     }       void PreTraversal(Node* _root)     {         if (_root == NULL)return;         cout << " ["<<_root->value << "] ";         if (_root->L != NULL)PreTraversal(_root->L);         if (_root->R != NULL)PreTraversal(_root->R);     }     void MidTraversal(Node* _root)     {         if (_root == NULL)return;          if (_root->L != NULL)MidTraversal(_root->L);         cout << " [" << _root->value << "] ";         if (_root->R != NULL)MidTraversal(_root->R);     }     void LastTraversal(Node* _root)     {         if (_root == NULL)return;          if (_root->L != NULL)LastTraversal(_root->L);          if (_root->R != NULL)LastTraversal(_root->R);         cout << " [" << _root->value << "] ";     }     void LayelTraversal()     {         Queue q;         q.Init();         q.Enqueque((int)root);         for (int i = 0; i < lastIndex; i++)         {             Node* tmp = (Node*)q.Dequeque();             cout << " ["<< tmp->value <<"] ";             if (tmp->L != NULL)q.Enqueque((int) tmp->L);             if (tmp->R != NULL)q.Enqueque((int) tmp->R);         }     } };  int main() {     Tree t;     t.Init();     for (int i = 1; i <= 9; i++)     {         t.Add(i);     }     cout << "前序";     t.PreTraversal(t.root); cout << endl;     cout << "中序";     t.MidTraversal(t.root); cout << endl;     cout << "后序";     t.LastTraversal(t.root); cout << endl;     cout << "层序";     t.LayelTraversal(); cout << endl;            return 0; }
View Code

树和森林转换为二叉树的方法。 以后再来补充吧,感觉要把我写二叉结构变成多叉结构。然后再转换为二叉树?然后再把很多二叉树合并成一个二叉树?。。。。有缘再补充吧

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!