C++實現通用雙向連結串列

gaopengtttt發表於2017-03-08
使用C++完成雙向通用連結串列
雙向連結串列不用多說,通用連結串列因為資料結構不確定的,使用一個VOID指標指向資料,
什麼資料都可以掛上去,這樣來封裝連結串列,可以作為基礎類也可以單獨使用,
這裡只是為了練習C++封裝的語法,實現了簡單的增加和刪除連結串列由於實際資料
型別不能確定,列印連結串列資料使用公有函式來完成,完成了正向列印反向列印,
演示了資料型別為簡單的int型別也演示了資料型別為class型別。
程式碼如下:


點選(此處)摺疊或開啟

  1. 連結串列實現:
  2. #include<iostream>
  3. #include<stdlib.h>
  4. using namespace std;
  5. /* data資料型別進行void封裝,為通用連結串列
  6.  * node為節點的基本資料結構
  7.  * addnode使用void資料進行連線到連結串列中,造成連結串列
  8.  * frist_node為第一個結點位置,開放訪問
  9.  * last_node為最後一個節點位置,開放訪問
  10.  * length為節點長度,開放訪問
  11.  * 只是完成增加節點和釋放節點功能,其他功能也相應簡單,用到再加,列印功能由於
  12.  * 資料型別不確定無法完成。
  13.  */
  14. #ifndef _CHAIN_
  15. #define _CHAIN_
  16. struct node
  17. {
  18.         void* data;
  19.         node* next;
  20.         node* priv;
  21.         unsigned int num;
  22.         node()
  23.         {
  24.                 data = NULL;
  25.                 next = NULL;
  26.                 priv = NULL;
  27.                 num = 0;
  28.         }
  29. };


  30. class my_chain
  31. {
  32.         public:
  33.                 my_chain()
  34.                 {

  35.                         this->frist_node = NULL;
  36.                         this->length = 0;
  37.                         this->last_node = NULL;
  38.                 }
  39. //-1 data is null;
  40. // 0 normal
  41. // 傳入一個void指標的資料型別,連結串列增加一個節點
  42.                 int addnode(void* data)
  43.                 {
  44.                         ret = 0 ;

  45.                         if(data == NULL)
  46.                         {
  47.                                 ret = -1;
  48.                                 return ret;
  49.                         }

  50.                         node* c_node = new node; //分配節點記憶體

  51.                         if(this->frist_node == NULL)
  52.                         {

  53.                                 this->frist_node = c_node;
  54.                         }
  55.                         if(this->last_node == NULL)
  56.                         {
  57.                                 c_node->next = NULL;
  58.                                 c_node->priv = NULL;
  59.                                 c_node->data = data;
  60.                         }
  61.                         else
  62.                         {
  63.                                 c_node->next = NULL;
  64.                                 c_node->priv = this->last_node;
  65.                                 this->last_node->next = c_node;
  66.                                 c_node->data = data;
  67.                         }
  68.                         this->last_node = c_node;
  69.                         this->length++;
  70.                         c_node->num = this->length;
  71.                         return ret;
  72.                 }
  73. //ret=1 null list;
  74. //ret=0 normal list;
  75. //釋放整個連結串列記憶體
  76.                 int freechain()
  77.                 {
  78.                         ret = 0;
  79.                         if(this->last_node == NULL)
  80.                         {
  81.                                 ret = 1;
  82.                                 cout<<"null list"<<endl;
  83.                                 return ret;
  84.                         }
  85.                         node* node_my = this->frist_node;
  86.                         while(node_my != NULL)
  87.                         {
  88. #ifdef DEBUG
  89.                                  cout<<"free node num:"<< node_my->num<<endl;
  90. #endif
  91.                                  node* temp = node_my;
  92.                                  node_my = node_my->next;
  93.                                  free(temp->data);//刪除節點資料記憶體?跨函式free
  94.                                  delete temp;//刪除節點node記憶體
  95.                         }
  96.                 }
  97. //....
  98.                 int delnode() //未實現
  99.                 {
  100.                         ret = 0;
  101.                         return ret;
  102.                 }

  103.                 int addmodnode(unsigned int loc)//未實現
  104.                 {
  105.                         ret = 0;
  106.                         return ret;
  107.                 }
  108. //.....

  109.         public:
  110.                  node* frist_node;//用於外部訪問
  111.                  unsigned int length;//用於外部訪問
  112.              node* last_node;//用於外部訪問
  113.         private:
  114.                  int ret;
  115. };
  116. #endif


點選(此處)摺疊或開啟

  1. 測試用例:
  2. #include<iostream>
  3. #define DEBUG
  4. #include"chain.h"
  5. using namespace std;
  6. //測試類
  7. class cube
  8. {
  9.         public:
  10.                 cube(int a,int b,int c):a(a),b(b),c(c)
  11.         {
  12.                 ;
  13.         }
  14.                 int get_size() const
  15.                 {
  16.                         return a*b*c;
  17.                 }
  18.         private:
  19.                 int a;
  20.                 int b;
  21.                 int c;
  22. };
  23. //完成列印操作
  24. int printchain(my_chain* c_header)
  25. {
  26.         if(c_header->frist_node == NULL)
  27.         {
  28.                 cout<<"NULL chain" <<endl;
  29.                 return -1;
  30.         }
  31.         node* node_my = c_header->frist_node;
  32.    cout<<"chain total number:"<<c_header->length<<endl;

  33. //正向訪問
  34. cout<<"正向訪問"<<endl;
  35.         while(node_my != NULL)
  36.         {
  37.                 cout<<"node num:"<<node_my->num<<" data is:"<<*((int*)(node_my->data))<<endl;
  38.                 node_my = node_my->next;
  39.         }


  40.         node_my = c_header->last_node;
  41. //反向訪問
  42. cout<<"反向訪問"<<endl;
  43.         while(node_my != NULL)
  44.         {
  45.                 cout<<"node num:"<<node_my->num<<" data is:"<<*((int*)(node_my->data))<<endl;
  46.                 node_my = node_my->priv;
  47.         }
  48.         return 0;

  49. }

  50. int printchain_cube(my_chain* c_header)
  51. {
  52.         if(c_header->frist_node == NULL)
  53.         {
  54.                 cout<<"NULL chain" <<endl;
  55.                 return -1;
  56.         }
  57.         node* node_my = c_header->frist_node;
  58.         cout<<"chain total number:"<<c_header->length<<endl;
  59. //正向訪問
  60. cout<<"正向訪問"<<endl;
  61.         while(node_my != NULL)
  62.         {
  63.                 cout<<"node num:"<<node_my->num<<" data is:"<<((cube*)(node_my->data))->get_size()<<endl;
  64.                 node_my = node_my->next;
  65.         }

  66.         node_my = c_header->last_node;
  67. //反向訪問
  68. cout<<"反向訪問"<<endl;
  69.         while(node_my != NULL)
  70.         {
  71.                 cout<<"node num:"<<node_my->num<<" data is:"<<((cube*)(node_my->data))->get_size()<<endl;
  72.                 node_my = node_my->priv;
  73.         }

  74.         return 0;

  75. }

  76. int main()
  77. {
  78.         cout<<"---int data chain:"<<endl;
  79.         { //3個測試int資料
  80.                 my_chain* chain_int = new my_chain;//建立my_chain雙向連結串列頭
  81.                 int i = 0;
  82.                 for(i = 0;i<3;i++)
  83.                 {
  84.                         //最好使用malloc族函式使用free來釋放void型別記憶體
  85.                         int* data = (int*)calloc(1,sizeof(int));
  86.                         //int* data = new int(i);
  87.                         (*chain_int).addnode((void*)data);
  88.                 }
  89.                 printchain(chain_int);
  90. #ifdef DEBUG
  91.                 cout<<"釋放記憶體"<<endl;
  92. #endif
  93.                 (*chain_int).freechain();
  94.                 delete chain_int;
  95.         }
  96.    cout<<"---class data chain:"<<endl;
  97.         {//5個測試類資料
  98.                 my_chain* chain_cube = new my_chain;//建立my_chain雙向的連結串列頭
  99.                 int i = 0;
  100.                 for(i = 0;i<5;i++)
  101.                 {
  102.                         //cube* data = new cube(i,i,i);
  103.                         cube* data = (cube*)calloc(1,sizeof(cube));
  104.                         (*data)=cube(i,i,i);//預設淺複製,這裡無礙
  105.                         (*chain_cube).addnode((void*)data);
  106.                 }
  107.                 printchain_cube(chain_cube);
  108. #ifdef DEBUG
  109.                 cout<<"釋放記憶體"<<endl;
  110. #endif
  111.                 (*chain_cube).freechain();
  112.                 delete chain_cube;
  113.         }

  114. }


點選(此處)摺疊或開啟

  1. 測試結果:
  2. ---int data chain:
  3. chain total number:3
  4. 正向訪問
  5. node num:1 data is:0
  6. node num:2 data is:0
  7. node num:3 data is:0
  8. 反向訪問
  9. node num:3 data is:0
  10. node num:2 data is:0
  11. node num:1 data is:0
  12. 釋放記憶體
  13. free node num:1
  14. free node num:2
  15. free node num:3
  16. ---class data chain:
  17. chain total number:5
  18. 正向訪問
  19. node num:1 data is:0
  20. node num:2 data is:1
  21. node num:3 data is:8
  22. node num:4 data is:27
  23. node num:5 data is:64
  24. 反向訪問
  25. node num:5 data is:64
  26. node num:4 data is:27
  27. node num:3 data is:8
  28. node num:2 data is:1
  29. node num:1 data is:0
  30. 釋放記憶體
  31. free node num:1
  32. free node num:2
  33. free node num:3
  34. free node num:4
  35. free node num:5
記憶體洩露檢測:
==4624== 
==4624== HEAP SUMMARY:
==4624==     in use at exit: 0 bytes in 0 blocks
==4624==   total heap usage: 18 allocs, 18 frees, 392 bytes allocated
==4624== 
==4624== All heap blocks were freed -- no leaks are possible
==4624== 
==4624== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==4624== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2134969/,如需轉載,請註明出處,否則將追究法律責任。

相關文章