双向循环链表

  1. //双向循环链表  
  2. typedef int datatype;  
  3. //方便修改  
  4. //当然也可以写成模板来适应更多的数据类型  
  5. struct dclink{  
  6.     datatype data;//数据定义  
  7.     struct dclink *pre;  
  8.     struct dclink *next;//前驱和后继指针  
  9. };  
  10. class DCLink  
  11. {  
  12. public:  
  13.     DCLink();//default constructor  
  14.     DCLink(datatype data);//单参constructor  
  15.     void add(datatype data);//添加data到链表中去  
  16.     datatype getData(int pos)const;//获得指定位置的数据  
  17.     int deleteData(int pos);//删除指定位置的数据  
  18.     int modify(int pos, datatype data);//更改指定位置的数据  
  19.     int insert(int pos, datatype data);//在指定位置插入数据  
  20.     void sort()const;//循环链表排序  
  21.     int rePrint()const;//双向循环链表转置没啥意义,转置输出还有那么点意义  
  22.     int print()const;//打印链表  
  23.     ~DCLink();//destructor  
  24.     int getLength()const;//得到链表的长度  
  25. private:  
  26.     DCLink operator=(const DCLink &dcl){}//assignment constructor 禁止  
  27.     DCLink (const DCLink &dcl){}//copy constructor 禁止  
  28.     struct dclink *head;//头指针  
  29.     struct dclink *cur;//当前指针  
  30.     int size;//大小  
  31. };  
  32. #endif  

DCLink.cpp

[cpp] view plain copy
 
  1. #include "dclink.h"  
  2. #include <iostream>  
  3. //default constructor  
  4. DCLink::DCLink(){  
  5.     head = cur = NULL;//默认为空  
  6.     size = 0;  
  7. }  
  8. DCLink::DCLink(datatype data){//单参constructor  
  9.     head = new struct dclink[1];//申请空间  
  10.     cur = head;//指向当前节点  
  11.     head->data = data;  
  12.     head->next = head->pre = head;//指向自身  
  13.     size = 1;  
  14. }  
  15. void DCLink::add(datatype data){//添加data到链表中去  
  16.     //默认添加到表尾  
  17.     struct dclink *dcl = new struct dclink[1];  
  18.     dcl->data = data;  
  19.     if (NULL != head){//表非空  
  20.         //当前节点为第1号节点,它的后继节点为第2号节点  
  21.         struct dclink *temp = cur->next;//保持2号节点的位置  
  22.         cur->next = dcl;//1号节点的后继和新增节点相连  
  23.         dcl->pre = cur;//新增节点的前驱和1号节点相连  
  24.         dcl->next = temp;//新增节点的后继和2号节点相连  
  25.         temp->pre = dcl;//新增节点和2号节点的前驱相连  
  26.     }else {  
  27.         head = dcl;//新加节点成为头结点  
  28.         head->data = data;  
  29.         head->next = head->pre = head;//指向自身  
  30.     }//已经添加完毕,新增节点成为当前节点  
  31.     cur = dcl;  
  32.     size++;//长度+1  
  33. }  
  34. int DCLink::deleteData(int pos){//删除指定位置的数据  
  35.     if (size >= pos && pos > 0){//有数据并且没有越界才显示  
  36.         int count = 1;//计数  
  37.         struct dclink *temp = head;  
  38.         while (pos != count){  
  39.             temp = temp->next;//直到到达指定的位置  
  40.             count++;  
  41.         }//先到达指定位置  
  42.         //分情况是因为如果删除最后一个节点会改变cur的状态,挂空指针  
  43.         if (size == pos){  
  44.             if (1 == size){//只有一个节点的时候  
  45.                 delete []temp;  
  46.                 head = cur = NULL;//置空  
  47.                 size--;//-1  
  48.                 return 0;  
  49.             }else{//删除最后一个节点  
  50.                 cur = temp->pre;//向前移动一个位置  
  51.             }  
  52.         }else{//如果删除第一个节点head会改变  
  53.             if (1 == pos){  
  54.                 head = temp->next;//向后移动一个位置  
  55.             }  
  56.         }  
  57.         //当前节点为0号节点,后继节点为1号节点,前驱节点为-1号节点  
  58.         temp->pre->next = temp->next;//-1号节点的后继和1号节点相连  
  59.         temp->next = temp->pre;//1号节点的前驱和-1号节点相连  
  60.         size--;//长度-1  
  61.         return 0;//成功返回0  
  62.     }  
  63.     return -1;//无数据或者越界返回-1  
  64. }  
  65. int DCLink::modify(int pos, datatype data){//更改指定位置的数据  
  66.     if (size >= pos && pos > 0){//有数据并且没有越界才显示  
  67.         int count = 1;//计数  
  68.         struct dclink *temp = head;  
  69.         while (pos != count){  
  70.             temp = temp->next;  
  71.             count++;  
  72.         }  
  73.         temp->data = data;//更新  
  74.         return 0;  
  75.     }  
  76.     return -1;//无数据或者越界返回-1  
  77. }  
  78. int DCLink::insert(int pos, datatype data){//在指定位置插入数据  
  79.     if (0 == size && 1 == pos){  
  80.         this->add(data);//直接调用add函数  
  81.         return 0;  
  82.     }  
  83.     if (size >= pos && pos > 0){//有数据并且没有越界才显示  
  84.         int count = 1;//计数  
  85.         struct dclink *dcl = new struct dclink[1];  
  86.         dcl->data = data;  
  87.         struct dclink *temp = head;  
  88.         while (pos != count){  
  89.             temp = temp->next;//直到到达指定的位置  
  90.             count++;  
  91.         }//先到达指定位置  
  92.         //分情况是因为如果插入到第一个节点会改变head的状态  
  93.         if (size == pos){  
  94.             if (1 == size){//只有一个节点的时候  
  95.                 head = dcl;//当前结点成为头结点  
  96.                 head->next = temp;//新结点的后继和旧头结点相连  
  97.                 temp->pre = head;//旧头结点的前驱和新结点相连  
  98.                 head->pre = temp;//新结点的前驱和旧头结点相连  
  99.                 temp->next = head;//旧头结点的后继和新结点相连  
  100.             }else{//插入到尾结点的前面  
  101.                 temp->pre->next = dcl;  
  102.                 dcl->pre = temp->pre;  
  103.                 dcl->next = temp;  
  104.                 temp->pre = dcl;  
  105.             }  
  106.             size++;  
  107.             return 0;  
  108.         }else{  
  109.             if (1 == pos){//插入到第一个位置  
  110.                 head = dcl;//当前结点成为头结点  
  111.                 head->next = temp;//新结点的后继和旧头结点相连  
  112.                 temp->pre = head;//旧头结点的前驱和新结点相连  
  113.                 head->pre = temp->pre;//新结点的前驱和旧头结点相连  
  114.                 temp->pre->pre = head;//旧头结点的后继和新结点相连  
  115.             }else {//插入到中间的其它位置  
  116.                 temp->pre->next = dcl;  
  117.                 dcl->pre = temp->pre;  
  118.                 dcl->next = temp;  
  119.                 temp->pre = dcl;  
  120.             }  
  121.             size++;  
  122.             return 0;  
  123.         }  
  124.     }  
  125.     return -1;//越界返回-1  
  126. }  
  127. datatype DCLink::getData(int pos)const{//获得指定位置的数据  
  128.     if (size >= pos && pos > 0){//有数据并且没有越界才显示  
  129.         int count = 1;//计数  
  130.         struct dclink *temp = head;  
  131.         while (pos != count){  
  132.             temp = temp->next;//比插入和删除简单很多  
  133.             count++;//+1,第一次写的时候忘了+1,然后就固执地认为getData肯定没问题  
  134.             //可bug就在这里  
  135.         }  
  136.         return temp->data;  
  137.     }  
  138.     return -1;//无数据或者越界返回-1  
  139. }  
  140. void DCLink::sort()const{//排序  
  141.     if (1 < size){  
  142.         //快速排序  
  143.         int i = 1;  
  144.         int j = 0;  
  145.         struct dclink *ohead = head;  
  146.         while (size != i){//循环size - 1次  
  147.             j = 0;//重置  
  148.             struct dclink *temp = ohead;//辅助指针  
  149.             while (j != size - i){  
  150.                 if (ohead->data > temp->next->data){//交换排序  
  151.                     ohead->data += temp->next->data;  
  152.                     temp->next->data = ohead->data - temp->next->data;  
  153.                     ohead->data -= temp->next->data;  
  154.                 }  
  155.                 temp = temp->next;//移动  
  156.                 j++;  
  157.             }  
  158.             ohead = ohead->next;//前面j个数据已经排好  
  159.             i++;  
  160.         }  
  161.     }  
  162. }  
  163. int DCLink::rePrint()const{//打印链表  
  164.     if (NULL != head){//链表非空  
  165.         struct dclink *temp = head;  
  166.         int count = 0;//计数  
  167.         while (size != count){  
  168.             temp = temp->pre;  
  169.             std::cout<<temp->data<<std::endl;  
  170.             count++;  
  171.         }  
  172.         return 0;  
  173.     }  
  174.     return -1;//空表返回-1  
  175. }  
  176. int DCLink::print()const{//打印链表  
  177.     if (NULL != head){//链表非空  
  178.         struct dclink *temp = head;  
  179.         int count = 0;//计数  
  180.         while (size != count){  
  181.             std::cout<<temp->data<<"  ";  
  182.             temp = temp->next;  
  183.             count++;  
  184.         }  
  185.         return 0;  
  186.     }  
  187.     return -1;//空表返回-1  
  188. }  
  189. int DCLink::getLength()const{  
  190.     return size;  
  191. }//得到链表的长度  
  192. //destructor  
  193. DCLink::~DCLink()  
  194. {  
  195.     while (0 != size){//用size来控制析构的次数  
  196.         struct dclink *temp = head;//辅助指针  
  197.         head->pre->next = head->next;//让head的前一个节点指向它的后一个节点  
  198.         head = head->next;//head后移动一个节点  
  199.         head->pre = temp->pre;//head还是指向前一个节点  
  200.         delete []temp;  
  201.         size--;  
  202.     }  
  203. }  
  204.   
  205. int main(void){  
  206.     DCLink dcl;  
  207.     for (int i = 100; i > 0; i--)  
  208.         dcl.add(i);  
  209.     dcl.print();  
  210.     std::cout<<std::endl;  
  211.     dcl.sort();  
  212.     dcl.print();  
  213.     dcl.modify(1,10);  
  214.     dcl.modify(5,44);  
  215.     dcl.modify(3,33);  
  216.     dcl.deleteData(5);  
  217.     dcl.deleteData(1);  
  218.     dcl.deleteData(3);  
  219.     dcl.deleteData(6);  
  220.     dcl.add(5);  
  221.     for (i = 1; i < 7; i++)  
  222.         std::cout<<dcl.getData(i)<<std::endl;  
  223.       
  224.     std::cout<<"the sizeof DCLink is "<<dcl.getLength()<<std::endl;  
  225.     dcl.print();  
  226.   
  227.     return 0;  
  228. }  
posted @ 2016-03-19 22:03  starskyhu  阅读(159)  评论(0编辑  收藏  举报