zoukankan      html  css  js  c++  java
  • 以链表为载体学习C++(4)

    这是一个系列的文章,主要目的是让初学者掌握链表的实现方法,并且从C过渡到C++。

    作者:重庆工程职业技术学院 万青

    第3篇文章中,add、insert方法的参数变成了指针,假设所有类的基类是Object,那么该指针是可以指向任何对象的。也就是说,链表节点可以容纳任意类型的数据(当然只是存了一个首地址)。

    不过更彻底的解决办法是用模板类:

      1 #include<iostream>
      2 using namespace std;
      3 template<class T> 
      4 class CNode //节点类
      5 {
      6     public:
      7         T data;
      8         CNode *next;
      9         CNode(T d) //构造函数
     10         {
     11             data=d;
     12             next=NULL;
     13         }
     14 };
     15 template<class T> 
     16 class CList //链表类
     17 {
     18     private:
     19         CNode<T> *head,*tail; //头、尾节点对象指针
     20         int length; //节点总数
     21     public:
     22         CList(); //构造函数(创建链表对象,并创建头节点,初始化头、尾指针等)
     23         void add(T data); //添加值为data的节点到链表末尾
     24         int insert(T data,int idx); //将数据data插入到链表的idx位置之后
     25         int del(int idx); //删除链表中的第idx个节点(idx从1开始计)
     26         CNode<T> * getPointerByIndex(int idx);//获取第idx个节点的对象指针(idx从1开始计)
     27         T* toArray(); //显示(遍历)链表的所有节点
     28         int getLength()
     29         {
     30             return length;
     31         }
     32         ~CList(); //析构函数(清除链表中的所有节点对象)
     33 };
     34 
     35 template<class T> 
     36 CList<T>::CList()
     37 {
     38     head=tail=new CNode<T>(0);
     39     length=0;
     40 }
     41 
     42 template<class T> 
     43 void CList<T>::add(T data)
     44 {
     45     CNode<T> *pNode=new CNode<T>(data);
     46     tail->next=pNode; 
     47     tail=pNode;//调整尾指针,指向新节点
     48     length++; //节点总数加1
     49 }
     50 
     51 template<class T> 
     52 CNode<T> * CList<T>::getPointerByIndex(int idx)
     53 {
     54     CNode<T> *p;
     55     int i=1;
     56     if(idx<1 || idx>length) return NULL;
     57     p=head;
     58 
     59     while(i<=idx)
     60         {
     61             p=p->next;
     62             i++;
     63         }
     64     return p;
     65 }
     66 
     67 template<class T> int CList<T>::insert(T data,int idx)
     68 {
     69     CNode<T> *p;
     70     p=getPointerByIndex(idx);
     71     if(p!=NULL)
     72     {
     73         CNode<T> *pNode=new CNode<T>(data);
     74         pNode->next=p->next;
     75         p->next=pNode;
     76         length++;
     77         return 1; //成功,返回1
     78     }
     79     return 0;
     80 }
     81 
     82 template<class T> int CList<T>::del(int idx)
     83 {
     84     CNode<T> *p,*q;
     85     if(idx<1 || idx>length)
     86         return 0; //失败,返回0
     87 
     88     //获得要删除节点的前一个节点指针
     89     if(idx==1) p=head;
     90     else p=getPointerByIndex(idx);
     91 
     92     //删除p节点的后一节点
     93     q=p->next; //记住后一节点的指针
     94     p->next=q->next;
     95     //delete(q->data);
     96     delete(q);
     97     length--;
     98     return 1;//成功,返回1
     99 }
    100 
    101 template<class T> T* CList<T>::toArray()
    102 {
    103     T *a=new T[length];
    104     CNode<T> *p;
    105     p=head;
    106     for(int i=0;i<length;i++)
    107     {
    108         p=p->next; //head节点没有数据,先移动再读取
    109         a[i]=p->data;
    110     }
    111     return a;
    112 }
    113 
    114 
    115 template<class T> CList<T>::~CList()
    116 {
    117     CNode<T> *curr,*tmp;
    118     curr=head;
    119     for(int i=0;i<=length;i++)
    120     {
    121         tmp=curr;
    122         curr=curr->next;
    123         //delete(tmp->data);
    124         delete(tmp);
    125     }
    126 }
    127 
    128 void showList(CList<int> *li)
    129 {
    130     int *a=li->toArray();
    131     for(int i=0;i<li->getLength();i++)
    132         cout<<a[i]<<" ";
    133     cout<<"\n-------------------\n";
    134 }
    135 
    136 void main()
    137 {
    138     CList<int> *li;
    139     li=new CList<int>();
    140     //int a=100,b=101,c=102;
    141     //li->add(&a);
    142     //li->add(&b);
    143     //li->add(&c);
    144     li->add(100);
    145     li->add(101);
    146     li->add(102);
    147     li->add(103);
    148     showList(li);
    149     li->insert(200,2);
    150     showList(li);
    151     li->insert(300,3);
    152     showList(li);
    153     li->del(1);
    154     showList(li);
    155     delete(li);
    156 }

    模板类不仅可以用于节点数据是对象指针的场合,也适用于节点数据是基本类型(如int)的场合。在此基础上,看到Java中的LinkedList<T>和C#中的List<T>,就不会有唐突的感觉了。稍微不同的是,Java和C#中去掉了“*”,把“->”变成“.”,对象指针也换了个名字叫“对象句柄”。

  • 相关阅读:
    【Android】ContentValues的用法
    【Android】Android处理Home键方法小结
    【Android】spannableStringBuilder
    【Android】Android 4.0 Launcher2源码分析——启动过程分析
    【Android】android文件的写入与读取---简单的文本读写context.openFileInput() context.openFileOutput()
    【Android】Android取消EditText自动获取焦点
    android在view.requestFocus(0)返回false的解决办法
    Android中创建倒影效果的工具类
    android布局layout中的一些属性
    android中巧妙更改spinner、AutoCompleteTextView分割线的颜色值(spinner AutoCompleteTextView divider color)
  • 原文地址:https://www.cnblogs.com/cyan1/p/2829307.html
Copyright © 2011-2022 走看看