鱼C论坛

 找回密码
 立即注册
查看: 5374|回复: 31

[技术交流] 贴下各种结构实例吧-->C++版本

[复制链接]
发表于 2012-3-14 13:21:20 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
因为C的复杂度和难以描述性 果断放弃C实现
C++的比较好理解 就是一个封装类  很少用到继承 多态更没见过
现贴出各种结构实现

评分

参与人数 2荣誉 +20 鱼币 +20 贡献 +3 收起 理由
故乡的风 + 10 + 10 + 3 赞一个!
小甲鱼 + 10 + 10 赞一个!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-3-14 13:24:31 | 显示全部楼层
1.
数组
myarray.h内容
  1. #include "student.h"
  2. #include "mystring.h"
  3. #include <iostream.h>

  4. template<typename T>
  5. class MyArray  
  6. {
  7. public:
  8.     MyArray()
  9.     {
  10.         Init();
  11.     }
  12.     virtual ~MyArray()
  13.     {
  14.         Clear();
  15.     }

  16. private:
  17.     //1.InitL ist(&L)           //构造空的线性表L
  18.     void Init()
  19.     {
  20.         m_isSorted = false;
  21.         m_lpData = NULL;
  22.         m_nLength = m_nAllocLength = 0;
  23.     }
  24. public:
  25.     //2.LengthList(L)          //求L的长度
  26.    
  27.     //3.GetElem(L,i,&e)        //取L中元素ai,由e返回ai
  28.     bool GetElem(int nIndex, T& OutStu)
  29.     {
  30.         if (nIndex < 0 || nIndex >= m_nLength)
  31.         {
  32.             return false;
  33.         }
  34.         OutStu = m_lpData[nIndex];
  35.         return true;
  36.     }
  37.    
  38.     //4.PriorElem(L,ce,&pre_e) //求ce的前驱,由pre_e返回
  39.     bool PriorElem(T& stu,T& OutPreStu)
  40.     {
  41.         for (int i = 0; i < m_nLength; i++)
  42.         {
  43.             if (m_lpData[i] == stu)
  44.             {
  45.                 break;
  46.             }
  47.         }
  48.         if (i == m_nLength)
  49.         {
  50.             return false;
  51.         }
  52.         GetElem(i - 1, OutPreStu);
  53.         return true;
  54.     }
  55.    
  56.     //InsertElemPrev  之前
  57.     bool InsertElemPrev(int index, const T& stu)
  58.     {
  59.         if (index < 0 || index > m_nLength)
  60.         {
  61.             return false;
  62.         }
  63.         m_isSorted = false;
  64.         if (m_nLength <= m_nAllocLength)
  65.         {
  66.             int nLengthtemp = m_nLength;
  67.             int nAllocLengthtemp = m_nAllocLength;
  68.             if (m_nAllocLength == 0)
  69.             {
  70.                 m_nAllocLength = 1;
  71.             }
  72.             T* newlpdata = new T[nAllocLengthtemp = m_nAllocLength * 2];
  73.             for (int i = 0; i < m_nLength; i++)
  74.             {
  75.                 newlpdata[i] = m_lpData[i];
  76.             }
  77.             
  78.             Clear();
  79.             m_lpData = newlpdata;
  80.             m_nAllocLength = nAllocLengthtemp;
  81.             m_nLength = nLengthtemp;
  82.         }
  83.         
  84.         for (int i = m_nLength; i > index; i--)
  85.         {
  86.             m_lpData[i] = m_lpData[i - 1];
  87.         }
  88.         m_lpData[index] = stu;
  89.         m_nLength++;
  90.         return true;
  91.     }
  92.     //InsertElemAfter 之后
  93.     bool InsertElemAfter(int index, const T& stu)
  94.     {
  95.         m_isSorted = false;
  96.         if (index < 0 || index > m_nLength)
  97.         {
  98.             return false;
  99.         }
  100.         if (m_nLength <= m_nAllocLength)
  101.         {
  102.             int nLengthtemp = m_nLength;
  103.             int nAllocLengthtemp = m_nAllocLength;
  104.             if (m_nAllocLength == 0)
  105.             {
  106.                 m_nAllocLength = 1;
  107.             }
  108.             T* newlpdata = new T[nAllocLengthtemp = m_nAllocLength * 2];
  109.             for (int i = 0; i < m_nLength; i++)
  110.             {
  111.                 newlpdata[i] = m_lpData[i];
  112.             }
  113.             
  114.             Clear();
  115.             m_lpData = newlpdata;
  116.             m_nAllocLength = nAllocLengthtemp;
  117.             m_nLength = nLengthtemp;
  118.         }
  119.         
  120.         for (int i = m_nLength; i > index + 1; i--)
  121.         {
  122.             m_lpData[i] = m_lpData[i - 1];
  123.         }
  124.         m_lpData[index + 1] = stu;
  125.         m_nLength++;
  126.         return true;
  127.     }

  128.     //尾部插入
  129.     void InsertTailElem(const T& InStu)
  130.     {
  131.         m_isSorted = false;
  132.         if (m_nLength <= m_nAllocLength)
  133.         {
  134.             int nLengthtemp = m_nLength;
  135.             int nAllocLengthtemp = m_nAllocLength;
  136.             if (m_nAllocLength == 0)
  137.             {
  138.                 m_nAllocLength = 1;
  139.             }
  140.             T* newlpdata = new T[nAllocLengthtemp = m_nAllocLength * 2];
  141.             for (int i = 0; i < m_nLength; i++)
  142.             {
  143.                 newlpdata[i] = m_lpData[i];
  144.             }
  145.             
  146.             Clear();
  147.             m_lpData = newlpdata;
  148.             m_nAllocLength = nAllocLengthtemp;
  149.             m_nLength = nLengthtemp;
  150.         }
  151.         m_lpData[m_nLength] = InStu;
  152.         m_nLength++;
  153.     }
  154.     //6.DeleteElem(&L,i)       //删除第i个数据元素
  155.     bool DeleteElem(int nIndex)
  156.     {
  157.         if (nIndex < 0 || nIndex >= m_nLength)
  158.         {
  159.             return false;
  160.         }
  161.         for (int i = nIndex; i < m_nLength; i++)
  162.         {
  163.             m_lpData[i] = m_lpData[i + 1];
  164.         }
  165.         m_nLength--;
  166.         return true;
  167.     }
  168.    
  169.     //7.EmptyList(L)           //判断L是否为空表
  170.     bool isEmpty() const
  171.     {
  172.         return m_nLength == 0;
  173.     }
  174.         
  175.         //8.ClearList(&L)          //置L为空表
  176.     void Clear()
  177.     {
  178.         if (m_lpData != NULL)
  179.         {
  180.             delete []m_lpData;
  181.             m_lpData = NULL;
  182.         }
  183.         m_nAllocLength = m_nLength = 0;
  184.     }
  185.     int GetLength() const
  186.     {
  187.         return  m_nLength;
  188.     }
  189.     void PrintAll()
  190.     {
  191.         T temp;
  192.         for (int i = 0; i < m_nLength; i++)
  193.         {
  194.             GetElem(i, temp);
  195.             cout << temp << endl;
  196.         }
  197.     }
  198. public:
  199.    
  200.     void Sort()
  201.     {
  202.         m_isSorted = true;
  203.         int i = 0;
  204.         int j = 0;
  205.         for (; i < m_nLength; i++)
  206.         {
  207.             for (j = i + 1; j < m_nLength; j++)
  208.             {
  209.                 if (m_lpData[i] > m_lpData[j])
  210.                 {
  211.                     int temp;
  212.                     temp = m_lpData[i];
  213.                     m_lpData[i] = m_lpData[j];
  214.                     m_lpData[j] = temp;
  215.                 }
  216.                
  217.             }
  218.         }
  219.     }

  220.     void QuickSort(int nMinIndex, int nMaxIndex)   //快速排序  O(n*log2^n)
  221.     {
  222.         m_isSorted = true;
  223.         int nTemp1 = nMinIndex;
  224.         int nTemp2 = nMaxIndex;
  225.         T nKey = m_lpData[nMinIndex];
  226.         if (nMinIndex >= nMaxIndex)
  227.         {
  228.             return;
  229.         }
  230.         for (;;)
  231.         {
  232.             while(nMinIndex < nMaxIndex && m_lpData[nMaxIndex] >= nKey)
  233.             {
  234.                 nMaxIndex--;
  235.             }
  236.             if (nMinIndex >= nMaxIndex)
  237.             {
  238.                 break;
  239.             }
  240.             m_lpData[nMinIndex++] = m_lpData[nMaxIndex];
  241.             
  242.             while (nMinIndex < nMaxIndex && m_lpData[nMinIndex] <= nKey)
  243.             {
  244.                 nMinIndex++;
  245.             }
  246.             if (nMinIndex >= nMaxIndex)
  247.             {
  248.                 break;
  249.             }
  250.             m_lpData[nMaxIndex--] = m_lpData[nMinIndex];
  251.         }
  252.         m_lpData[nMaxIndex] = nKey;
  253.         int nMiddle = nMaxIndex;
  254.         QuickSort(nTemp1, nMiddle - 1);
  255.         QuickSort(nMiddle + 1, nTemp2);
  256.     }
  257.     int FindItem(const T& obj)
  258.     {
  259.         
  260.         if (isSort())
  261.         {
  262.             return FindItemBy2Half(obj, 0, m_nLength - 1);
  263.         }
  264.         else
  265.         {
  266.             for (int i = 0; i < m_nLength; i++)
  267.             {
  268.                 if (m_lpData[i] == obj)
  269.                 {
  270.                     return 1;
  271.                 }
  272.             }
  273.             return -1;
  274.         }
  275.     }
  276.    
  277.     int FindItemBy2Half(const T& obj,int nMinIndex,int nMaxIndex)
  278.     {
  279.         int nMiddel = (nMinIndex + nMaxIndex) / 2;
  280.         
  281.         if (m_lpData[nMiddel] == obj)
  282.         {
  283.             return 1;
  284.         }
  285.         if (nMinIndex >= nMaxIndex)
  286.         {
  287.             return -1;
  288.         }
  289.         
  290.         if (m_lpData[nMiddel] > obj)
  291.         {
  292.             nMaxIndex = nMiddel - 1;
  293.         }
  294.         if (m_lpData[nMiddel] < obj)
  295.         {
  296.             nMinIndex = nMiddel + 1;
  297.         }
  298.         FindItemBy2Half(obj, nMinIndex, nMaxIndex);
  299.     }

  300.    
  301.     void Copy(const MyArray& theObj)
  302.     {
  303.         if (this == &theObj)
  304.         {
  305.             return;
  306.         }
  307.         Clear();
  308.         T* newlpdata = new T[theObj.m_nAllocLength];
  309.         m_lpData = newlpdata;
  310.         m_nLength = theObj.m_nLength;
  311.         m_nAllocLength = theObj.m_nAllocLength;
  312.         for (int i = 0; i < m_nLength; i++)
  313.         {
  314.             m_lpData[i] = theObj.m_lpData[i];
  315.         }
  316.     }
  317.    
  318.     void UnionArray(const MyArray& theObj)
  319.     {
  320.         m_isSorted = false;
  321.         if (m_nAllocLength < m_nLength + theObj.m_nLength)
  322.         {
  323.             int nAllocLengthTemp;
  324.             nAllocLengthTemp = m_nAllocLength;
  325.             T* newlpdata = new T[m_nLength + theObj.m_nLength];
  326.             Clear();
  327.             m_lpData = newlpdata;
  328.             m_nAllocLength = nAllocLengthTemp;
  329.         }
  330.         for (int i = 0; i < theObj.m_nLength; i++)
  331.         {
  332.             InsertTailElem(theObj.m_lpData[i]);
  333.         }
  334.     }
  335.     bool isSort() const
  336.     {
  337.         return m_isSorted;
  338.     }
  339.    
  340. private:
  341.     T*   m_lpData;
  342.     int        m_nLength;
  343.     int        m_nAllocLength;
  344. private:
  345.     bool       m_isSorted;
  346. };
复制代码
string.h:
  1. class mystring  
  2. {
  3. public:
  4.         mystring();
  5.     mystring(char *);
  6.         virtual ~mystring();
  7. public:
  8.     mystring(const mystring& obj)
  9.     {
  10.         m_lpstring = new char [strlen(obj.m_lpstring) + 1];
  11.         strcpy(m_lpstring, obj.m_lpstring);
  12.     }
  13.     mystring& operator=(const mystring& obj)
  14.     {
  15.         if (this == &obj)
  16.         {
  17.             return *this;
  18.         }
  19.         if (m_lpstring != NULL)
  20.         {
  21.             delete []m_lpstring;
  22.         }
  23.         
  24.         m_lpstring = new char[strlen(obj.m_lpstring) + 1];
  25.         strcpy(m_lpstring, obj.m_lpstring);
  26.         return *this;
  27.     }
  28.     operator char*() const
  29.     {
  30.         return m_lpstring;
  31.     }
  32.     bool operator >= (const mystring& obj)
  33.     {
  34.         return strcmp(m_lpstring, obj.m_lpstring) >= 0;
  35.     }
  36.     bool operator > (const mystring& obj)
  37.     {
  38.         return strcmp(m_lpstring, obj.m_lpstring) > 0;
  39.     }
  40.     bool operator < (const mystring& obj)
  41.     {
  42.         return strcmp(m_lpstring, obj.m_lpstring) < 0;
  43.     }
  44.     bool operator <= (const mystring& obj)
  45.     {
  46.         return strcmp(m_lpstring, obj.m_lpstring) <= 0;
  47.     }
  48.     bool operator == (const mystring& obj)
  49.     {
  50.         return strcmp(m_lpstring, obj.m_lpstring) == 0;
  51.     }
  52. private:
  53.     char* m_lpstring;
  54. };
  55. bool operator<(const mystring& obj1, const mystring& obj2);
  56. bool operator<=(const mystring& obj1, const mystring& obj2);
  57. bool operator>(const mystring& obj1, const mystring& obj2);
  58. bool operator>=(const mystring& obj1, const mystring& obj2);
  59. bool operator==(const mystring& obj1, const mystring& obj2);
复制代码
string.cpp:
  1. #include "stdafx.h"
  2. #include "mystring.h"

  3. //////////////////////////////////////////////////////////////////////
  4. // Construction/Destruction
  5. //////////////////////////////////////////////////////////////////////

  6. mystring::mystring()
  7. {
  8.     m_lpstring = NULL;
  9. }
  10. mystring::mystring(char* lpstring)
  11. {
  12.     m_lpstring = new char[strlen(lpstring) + 1];
  13.     strcpy(m_lpstring, lpstring);
  14. }

  15. mystring::~mystring()
  16. {

  17. }

  18. bool operator<(const mystring& obj1, const mystring& obj2)
  19. {
  20.     return obj1 < obj2;
  21. }
  22. bool operator<=(const mystring& obj1, const mystring& obj2)
  23. {
  24.     return obj1 <= obj2;
  25. }
  26. bool operator>(const mystring& obj1, const mystring& obj2)
  27. {
  28.     return obj1 > obj2;
  29. }
  30. bool operator>=(const mystring& obj1, const mystring& obj2)
  31. {
  32.     return obj1 >= obj2;
  33. }
  34. bool operator==(const mystring& obj1, const mystring& obj2)
  35. {
  36.     return obj1 == obj2;
  37. }
复制代码
student.h:
  1. class student
  2. {
  3. public:
  4.     student(int ndata = 0)
  5.     {
  6.         m_ndata = ndata;
  7.     }
  8.     student(int ndata);
  9.     ~student();
  10. public:
  11.     student& operator=(const student& obj)
  12.     {
  13.         if (this == &obj)
  14.         {
  15.             return *this;
  16.         }
  17.         m_ndata = obj.m_ndata;
  18.         return *this;
  19.     }
  20.     operator int() const
  21.     {
  22.         return m_ndata;
  23.     }
  24. private:
  25.     int m_ndata;
  26. };
复制代码

评分

参与人数 1鱼币 +5 贡献 +1 收起 理由
番茄 + 5 + 1 很给力!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-3-14 13:24:55 | 显示全部楼层
数组的优缺点:
数组

优点:
1  随机访问快 O(1)
   访问第i个元素 &a[i] = base+(i-1)*sizeof(item)

缺点:

2  增加 删除 速度慢 O(n/2)

3  查询元素
   有序数组 速度快 log2^n
   无序数组 慢     O(n)

4. 当空间不够时候,
   (申请空间,复制原内容,释放原元素)  O(2n)

适用场合:
   1.数据操作(增加 删除) 频率少
   2.有序 ,频率高 查找快
   3.可以预先判断估计元素个数情况下  [汉字表 8000]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-3-14 13:28:10 | 显示全部楼层
算了传文件算了  贴代码太长了
2.链表:
优点:

1  当在指定的元素后增加 或删除 速度快 O(1)

2. 空间无限制


缺点:

1  随机访问慢 O(n)

   访问第i个元素 一个个找

2  查询元素慢  O(n)
   无序 慢     O(n)
   有序 慢     因为随机访问慢  
   
适用场合:

   1.无法事先估计元素个数

   2.尾部增加 尾部删除 频繁的时候

文件双链表2.rar

24.65 KB, 下载次数: 16

文件双链表.rar

27.04 KB, 下载次数: 16

双链表.rar

266.13 KB, 下载次数: 17

单链表.rar

12.16 KB, 下载次数: 12

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-3-14 13:30:37 | 显示全部楼层
3.栈和队列
因为栈和队列也是线性结构所以可以继承数组类或链表类
这里用双链表实现
栈有蛮多应用 二叉树的遍历非递归时要用到
二叉树的层次遍历要用到队列

栈和队列结构.rar

16.98 KB, 下载次数: 14

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-3-14 13:33:44 | 显示全部楼层
数据结构中有个迭代器的概念
线性表->(数组,链表)

不同的线性表的实现中,用户可以使用统一的遍历方法.

1. iterator 迭代器(位置指示器)
   
   MyArray<T>::iterator it = list1.begin();

   for(; it != list1.end(); it++)
   {
     T& obj = *it;
   }


2.
(位置)
POSITION pos = list1.begin();

while( pos != list1.end() )
{
   //T& obj = list1.GetNext(pos);

   T& obj = list1.GetData(pos);

   pos++;
}

这里自己做得时候有个小BUG 没有解决 最后多输出个0..

迭代器.rar

22.79 KB, 下载次数: 23

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-3-14 13:34:38 | 显示全部楼层
哈希表:
也是线性结构 散列

哈希表.rar

9.76 KB, 下载次数: 13

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-3-14 13:42:48 | 显示全部楼层
非常不错,谢谢朋友分享!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-3-14 13:49:09 | 显示全部楼层
最大堆:
最大堆排序算法我认为是最实用的
比如有一题
n个无序元素 得到最小的m个元素
  /*   100000000              m[10000]
  [ 5 63 59 45 12 36 98 97 ...... ]
1亿个数据得到前10000最小的数据
这里用到最大堆来完成算法复杂度直接成了
(m/2)(lg2^m) + (n-m)(lg2^m)
具体思路就是前10000个构成个最大堆 从10001 到 100000000
如果小于根节点 循环与根节点交换 维护最大堆性质就行了
       = lg2^m- (m/2)(lg2^m)

最大堆.rar

10.59 KB, 下载次数: 11

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-3-14 13:53:41 | 显示全部楼层
还有个桶排序  感觉实用性并不到 是个线性阶 有点浪费空间
可以用哈希表实现解决空间浪费问题
具体思路
比如
10 2 3 4 5 7 0
这些数据
定义个数组 数组长度为要排序数据的最大长度 为10
数组元素为 0 0 2 3 4 5 0 7 0 0 10
0为标记 表示没有数据
当你写完数组 数据默认就自动排好序了
很少用
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-3-14 14:01:07 | 显示全部楼层
当然具体数据分布情况
选择不同的算法
代码中基本上有冒泡 快排
最大堆 二叉树排序
晚上我贴下二叉树
前中后遍及 以及层次遍及
还有二叉树排序 查找
这些代码都是上课时记的
有什么错误大家一起交流

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-3-14 15:31:27 | 显示全部楼层
  1. void MyTree::PreorderTraverse(TreeNode* lpNode) //前序递归
  2. {
  3.     if (lpNode != NULL)
  4.     {
  5.         cout << lpNode->m_Data << endl;
  6.         PreorderTraverse(lpNode->m_lpLeft);
  7.         PreorderTraverse(lpNode->m_lpRight);
  8.     }

  9. }

  10. void MyTree::MidorderTraverse(TreeNode* lpNode) //中序递归
  11. {
  12.     if (lpNode != NULL)
  13.     {
  14.         MidorderTraverse(lpNode->m_lpLeft);
  15.         cout << lpNode->m_Data << endl;
  16.         MidorderTraverse(lpNode->m_lpRight);
  17.     }
  18. }

  19. void MyTree::LastorderTraverse(TreeNode* lpNode) //后序递归
  20. {
  21.     if (lpNode != NULL)
  22.     {
  23.         LastorderTraverse(lpNode->m_lpLeft);
  24.         LastorderTraverse(lpNode->m_lpRight);
  25.         cout << lpNode->m_Data << endl;
  26.     }
  27. }
复制代码
二叉树的遍历:

递归真的蛮简单的
调整下输出位置就行了 符合人的思想
如果是反前序 反中序 反后续 调整下递归函数调用的左右节点顺序即可
非递归有点抽象

能用递归的就能用栈结构来表示 但是一个函数两个递归函数调用就有点难理解的

首先看递归 都是压入左节点递归
当左节点最后一个问题执行完成才又递归传右节点
  1. void MyTree::PreorderTraverseByStack(TreeNode* lpNode) //前序非递归
  2. {
  3.     MyStack<TreeNode*> theStack;

  4.    
  5.     while (lpNode != NULL || !theStack.isEmpty())
  6.     {

  7.         while (lpNode != NULL)
  8.         {
  9.             cout << lpNode->m_Data << endl;
  10.             theStack.push(lpNode);
  11.             lpNode = lpNode->m_lpLeft;
  12.         }

  13.         if (!theStack.isEmpty())
  14.         {
  15.             theStack.pop(lpNode);
  16.             lpNode = lpNode->m_lpRight;
  17.         }
  18.     }


  19.    
  20. }
复制代码
这需要多思考 多跟程序才能慢慢理解

中序的话 就是输出位置不同 把输出放到pop后就可以实现

而后序换输出位置已经不行
因为是最后输出根节点
先左后右最后根

所以肯定会有判断条件
先遍历到左子树叶子节点 弹出输出
然后跳到父节点 查找右节点 如果右节点非空 继续查找
然后输出右叶子
跳到父节点 输出父节点

这里父节点如果直接pop出来 则会出错 要么保存两次父节点 要么
写个取栈顶的函数 非改变栈大小 只是取元素

我写的第二种
  1. void MyTree::LastorderTraverseByStack(TreeNode* lpRoot)
  2. {
  3.     MyStack<TreeNode*> theStack;
  4.     TreeNode* preNode = NULL;
  5.     while ( lpRoot != NULL || !theStack.isEmpty())
  6.     {
  7.         if (lpRoot != NULL)
  8.         {
  9.             theStack.push(lpRoot);
  10.             lpRoot = lpRoot->m_lpLeft;
  11.         }
  12.         else
  13.         {
  14.             theStack.GetTail(lpRoot);
  15.             if ( lpRoot->m_lpRight != NULL && preNode != lpRoot->m_lpRight)
  16.             {
  17.                 lpRoot = lpRoot->m_lpRight;
  18.             }
  19.             else
  20.             {
  21.                 theStack.GetTail(preNode);
  22.                 lpRoot = preNode;
  23.                 cout << lpRoot->m_Data << endl;
  24.                 theStack.pop(lpRoot);
  25.                 lpRoot = NULL;
  26.             }
  27.         }
  28.     }




  29. }
复制代码
最后一个层次遍历

意思就是从根节点 第一层开始
从左到右或从右到左一层层的输出

这里用不了递归(因为递归输出位置3种情况已经用完 测试下都不是层次遍历) 所以栈也实现不了
只能用队列 不用队列也很难写
  1. void MyTree::LayerorderTraverse(TreeNode* lpNode) //层次遍历
  2. {
  3.     if(lpNode == NULL)
  4.     {
  5.         return;
  6.     }
  7.       
  8.     MyQueue<TreeNode*> theQueue;
  9.     theQueue.EnQueue(lpNode);
  10.     TreeNode* lpCurNode = NULL;
  11.     while (theQueue.DeQueue(lpCurNode))
  12.     {
  13.         cout << lpCurNode->m_Data << endl;
  14.         if (lpCurNode->m_lpLeft != NULL)
  15.         {
  16.             theQueue.EnQueue(lpCurNode->m_lpLeft);
  17.         }
  18.         if (lpCurNode->m_lpRight != NULL)
  19.         {
  20.             theQueue.EnQueue(lpCurNode->m_lpRight);
  21.         }
  22.         
  23.     }

  24. }
复制代码
说下应用
前序遍历是波兰表达式
后续遍历是逆波兰表达式
中序是我们最习惯的表达式

所以写个让用户输入表达式的程序 可以用二叉树来写
遍历用后续 加个栈结构就可以实现

还有个析构函数怎么写 把后序遍历输出部分换成delete就行了

至于什么赫夫曼树什么的 也跟这有关系 感觉有点晕。。

二叉树遍历.rar

265.97 KB, 下载次数: 17

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-3-15 19:18:58 | 显示全部楼层
没人来啊。。
也许C++语法有点难懂 不过貌似就是用到个类 构造和析构
连C++3个特性都没用到
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-3-15 22:24:56 | 显示全部楼层
二叉有序数的添加 删除
当删除的节点有左右子树时 一种方法时交换其数据值
一种方法时交换指针值 因为当数据特别大时交换时拷贝数据会浪费很大内存
这里我做的是交换指针

所以析构时 有序树不用后序遍历删除了
析构代码也改了

二叉有序树.rar

27.89 KB, 下载次数: 15

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-3-16 14:27:03 | 显示全部楼层
今天讲到avl树 平衡树
其中平衡因子 就是左子树-右子树高度差 是个公式算出来的
而有些书 直接给-1 0 1

还有些书根本不讲avl树的实现。。 貌似觉得退化到链表对当今计算机没什么影响。。
自己先做一遍 唉 已经昏了 以前感觉链表交换排序够复杂的  跟avl树根本不是一个层次的难
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-3-16 16:20:20 | 显示全部楼层
好文章,我也打算开始把数据结构上的知识重新学一遍{:1_1:}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-3-16 19:19:21 | 显示全部楼层

AVL树
    1.每个结点的左右子树abs(高度差值)<=1  

TreeNode
{
   int m_nSubHeight;  左右子树高度差值  左高度-右高度
}

旋转: K1 K2相邻
         K1                 K2
     K2      C    ===>   A       K1
   A    B                      B    C


好处: 合适的旋转 可以使得高度减少

右单旋转
                    20(K1)                  10(K2)
       10(K2)         30   ===>   7          20(K1)
    7       15                 5          15       30
  5

左单旋转

         K1                        K2
     A       K2       ===>     K1       C
           B    C           A     B


右双旋转
                 K1                    k3
        K2         D   ===>       k2        K1
      A     K3                 A     B    C    D
          B    C   
         
     1. K2,K3 左单旋          2. K1,K3 右单旋
            
                   K1                  K3
              K3      D           K2         K1
          K2     C             A     B    C     D
        A    B


左双旋转

                    K1
        D                k2
                k3            C   
       
          A           B

     1. k3, k2 右单旋
       
                k3
        A                k2
                B                C

    2.  k3, k1左单旋
       
                k3
        k1                k2
  D            A          B           C



--------------------------------------------------------------
时间复杂度:

查找 logn

增加 找logn + c1 + 高度差调整logn + 旋转时间

     2logn + c1 + c2

旋转时间 c2 + 高度差调整logn

删除 找logn + c1 + 高度差调整logn  + 旋转时间

     2logn + c1 + c2




AVL树.rar

20.83 KB, 下载次数: 15

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-3-17 17:21:27 | 显示全部楼层
今天学到图 彻底崩溃 看到实现有点恶心的感觉

图1.rar

38.63 KB, 下载次数: 14

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-3-30 22:27:52 | 显示全部楼层
牛啊,学习了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-4-4 11:33:02 | 显示全部楼层
刚学完数据结构   谢楼主这么好的东西   回去好好看看!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-27 13:15

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表