zoukankan      html  css  js  c++  java
  • 2.3 单链表

     

     

     ①不带头结点的单链表的实现(类模板)

      1 #include <iostream>
      2 #include <cstdlib>
      3 #include <ctime>
      4 ///无头结点
      5 using namespace std;
      6 //typedef int T;
      7 
      8 template <class T>
      9 struct LinkNode //结点定义
     10 {
     11     T data;//数据域
     12     LinkNode<T>* next;//链域
     13     LinkNode(const T& item, LinkNode<T>* ptr=NULL)
     14     {
     15         data = item;
     16         next = ptr;
     17     }
     18     LinkNode(LinkNode<T>* ptr=NULL)
     19     {
     20         next = ptr;
     21     }
     22 };
     23 
     24 template <class T>
     25 class List
     26 {
     27 private:
     28     LinkNode<T>* first;
     29 public:
     30     List();//构造函数
     31     List(const T& x);
     32     List(const List<T>& L);//拷贝构造函数
     33     List<T>& operator=(const List<T>& L);//赋值运算符函数
     34     ~List();//析构函数
     35 
     36     void InputFront(const T& elem);//头插法
     37     void InputRear(const T& elem);//尾插法
     38 
     39     void MakeEmpty();//清空链表
     40     int Length() const;//返回链表中结点个数
     41 
     42     LinkNode<T>* Search(const T& x);//在链表中查找元素x,找到返回它所在结点的地址,否则返回空
     43     LinkNode<T>* Locate(int i);//返回链表中第i个结点的地址,i取值不合法则返回空
     44     LinkNode<T>* getHead()const;
     45 
     46     bool GetData(int i, T& x)const;//获取链表第i个元素,将它赋值给x
     47     void SetData(int i, const T& x);//设置链表第i个元素为x
     48 
     49     bool Insert(int i, const T& x);//在链表的第i个位置上插入元素x
     50     bool Remove(int i, T& x);//删除链表第i个位置的元素,并将它的值赋值给x
     51 
     52     bool IsEmpty() const;//返回链表是否为空
     53     bool IsFull() const;//返回链表是否为满
     54 
     55     void CopyList(const List<T>& L);//复制链表
     56 
     57     void Sort();//对链表中结点进行排序
     58 
     59     friend ostream& operator<<(ostream& out, const List<T>& L)//输出流运算符重载
     60     {
     61         LinkNode<T> *p=L.first;
     62        // p = p->next;
     63         while(p!=NULL)
     64         {
     65             cout << p->data << ' ';
     66             p = p->next;
     67         }
     68         cout << endl;
     69         return out;
     70     }
     71     //  friend istream& operator>>(istream& in, List& L);//输入流运算符重载
     72 };
     73 
     74 template <class T>
     75 List<T>::List()//构造函数
     76 {
     77     first = NULL;
     78 }
     79 
     80 template <class T>
     81 List<T>::List(const T& x)  //构造函数
     82 {
     83     first = new LinkNode<T>(x);
     84 }
     85 
     86 template <class T>
     87 List<T>::List(const List<T>& L)//拷贝构造函数
     88 {
     89     T temp;
     90     LinkNode<T>* strL = L.getHead();
     91     //cout <<L.getHead()<<endl;
     92     temp = strL->data;
     93     LinkNode<T>* strthis = first = new LinkNode<T>(temp);
     94     //cout <<first<<endl;
     95     while(strL->next)
     96     {
     97         temp = strL->next->data;
     98        // cout<<temp<<endl;
     99         strthis->next = new LinkNode<T>(temp);
    100         strthis = strthis->next;
    101         strL = strL->next;
    102     }
    103     strthis->next = NULL;
    104 }
    105 
    106 template <class T>
    107 LinkNode<T>* List<T>::getHead()const
    108 {
    109     return first;
    110 }
    111 
    112 
    113 template <class T>
    114 List<T>& List<T>::operator=(const List<T>& L)//赋值运算符函数
    115 {
    116     T temp;
    117     LinkNode<T>* strL = L.getHead();
    118     //cout <<L.getHead()<<endl;
    119     temp = strL->data;
    120     LinkNode<T>* strthis = first = new LinkNode<T>(temp);  ///注意在这里要附上初值,要不然会多一个
    121     //cout <<first<<endl;
    122     while(strL->next)
    123     {
    124         temp = strL->next->data;
    125        // cout<<temp<<endl;
    126         strthis->next = new LinkNode<T>(temp);
    127         strthis = strthis->next;
    128         strL = strL->next;
    129     }
    130     strthis->next = NULL;
    131     return *this;
    132 }
    133 
    134 template <class T>
    135 List<T>::~List()//析构函数
    136 {
    137     MakeEmpty();
    138 }
    139 
    140 template <class T>
    141 void List<T>::InputFront(const T& elem)//头插法
    142 {
    143     MakeEmpty();
    144     LinkNode<T> *temp = new LinkNode<T>(elem);
    145     if(temp == NULL)
    146         exit(1);
    147     temp->next = first;
    148     first = temp;
    149 }
    150 
    151 template <class T>
    152 void List<T>::InputRear(const T& elem)//尾插法
    153 {
    154     LinkNode<T> *temp;
    155     MakeEmpty();
    156     temp = new LinkNode<T>(elem);
    157     if(first == NULL) //要考虑没有元素的情况
    158         first = temp;
    159     else
    160     {
    161         LinkNode<T> *current = first;
    162         while(current->next)
    163         {
    164             current = current->next;
    165         }
    166         current->next = temp;
    167     }
    168     return;
    169 }
    170 
    171 template <class T>
    172 void List<T>::MakeEmpty()//清空链表
    173 {
    174     LinkNode<T> *q;
    175     while(first != NULL)
    176     {
    177         q = first;
    178         first = q->next;
    179         delete q;
    180     }
    181 }
    182 
    183 template <class T>
    184 int List<T>::Length() const//返回链表中结点个数
    185 {
    186     int len = 0;
    187     LinkNode<T> *p = first;
    188     while(p)
    189     {
    190         p=p->next;
    191         len++;
    192     }
    193     return len;
    194 }
    195 
    196 template <class T>
    197 LinkNode<T>* List<T>::Search(const T& x)//在链表中查找元素x,找到返回它所在结点的地址,否则返回空
    198 {
    199     LinkNode<T> *p = first;
    200     while(p)
    201     {
    202         if(p->data == x)
    203             return p;
    204         p = p->next;
    205     }
    206 }
    207 
    208 template <class T>
    209 LinkNode<T>* List<T>::Locate(int i)//返回链表中第i个结点的地址,i取值不合法则返回空
    210 {
    211     if(i<=0)
    212         return NULL;
    213     LinkNode<T> *p = first;
    214     int m = 1;
    215     while(p->next != NULL && m<i)
    216     {
    217         p = p->next;
    218         m++;
    219     }
    220     return p;
    221 }
    222 
    223 template <class T>
    224 bool List<T>::GetData(int i, T& x)const//获取链表第i个元素,将它赋值给x
    225 {
    226     if(i <= 0)
    227         return NULL;
    228     LinkNode<T> *p = Locate(i);
    229     if(p == NULL)
    230         return false;
    231     x = p->data;
    232     return true;
    233 }
    234 
    235 template <class T>
    236 void List<T>::SetData(int i, const T& x)//设置链表第i个元素为x
    237 {
    238     if(i <= 0)
    239         return;
    240     LinkNode<T> *p = Locate(i);
    241     if(p == NULL)
    242         return;
    243     p->data = x;
    244 }
    245 
    246 template <class T>
    247 bool List<T>::Insert(int i, const T& x)//在链表的第i个位置上插入元素x
    248 {
    249     if((first == NULL) || (i == 0))
    250     {
    251         LinkNode<T> *newNode = new LinkNode<T>(x);
    252         if(newNode == NULL)
    253         {
    254             cerr << "存储分配错误!";
    255             exit(1);
    256         }
    257         newNode->next = first;
    258         first = newNode;
    259     }
    260     else
    261     {
    262         LinkNode<T> *pre = first;
    263         for(int j = 1; j < i; j++)
    264         {
    265             if(pre->next == NULL)
    266                 break;
    267             else
    268                 pre = pre -> next;
    269         }
    270         if(pre == NULL)
    271         {
    272             cout << "无效的插入位置" << endl;
    273             return false;
    274         }
    275         else
    276         {
    277             LinkNode<T> *newNode = new LinkNode<T>(x);
    278             newNode -> next = pre -> next;
    279             pre -> next = newNode;
    280         }
    281     }
    282     return true;
    283 }
    284 
    285 template <class T>
    286 bool List<T>::Remove(int i, T& x)//删除链表第i个位置的元素,并将它的值赋值给x
    287 {
    288     LinkNode<T> *p = Locate(i-1);
    289     if(p == NULL)
    290         return false;
    291     LinkNode<T> *del = p->next;
    292     x = del->next->data;
    293     p->next = del->next;
    294 
    295     delete del;
    296     return true;
    297 }
    298 
    299 template <class T>
    300 bool List<T>::IsEmpty() const//返回链表是否为空
    301 {
    302     if(first = NULL)
    303         return true;
    304     else
    305         return false;
    306 }
    307 
    308 template <class T>
    309 bool List<T>::IsFull() const//返回链表是否为满
    310 {
    311     return false;
    312 }
    313 
    314 template <class T>
    315 void List<T>::CopyList(const List& L)                     //复制链表
    316 {
    317     LinkNode<T> *iter = new LinkNode<T>;
    318     LinkNode<T> *rear = new LinkNode<T>;
    319     if(L.first == NULL)
    320         return;
    321     LinkNode<T> *newNode = new LinkNode<T>(L.first -> data);
    322     first = newNode;
    323     iter = L.first -> next;
    324     rear = newNode;
    325     while(iter)
    326     {
    327         LinkNode<T> *newNode = new LinkNode<T>(iter -> data);
    328         rear -> next = newNode;
    329         iter = iter -> next;
    330         rear = rear -> next;
    331     }
    332 }
    333 
    334 
    335 template <class T>
    336 void List<T>::Sort()//对链表中结点进行排序
    337 {
    338     LinkNode<T> *current = this->first;
    339     int temp;
    340     while(current->next != NULL)
    341     {
    342         LinkNode<T>* second = current->next;
    343         while(second != NULL)
    344         {
    345             if((current->data) > (second->data))
    346             {
    347                 temp = current->data;
    348                 current->data = second->data;
    349                 second->data = temp;
    350             }
    351             second = second->next;
    352         }
    353         current = current->next;
    354     }
    355 }
    356 
    357 
    358 //template <class T>
    359 //friend istream& operator>>(istream& in, List& L)//输入流运算符重载
    360 //{
    361 
    362 //}
    363 
    364 int main()
    365 {
    366     List<int> lst;
    367     srand(time(NULL));
    368     for(int i=1; i<=5; i++)
    369         lst.Insert(i,rand()%50);
    370     cout << "past: " <<lst;
    371     cout <<endl;
    372 
    373     lst.SetData(3,999);
    374     cout<<"SetData,No.3=99: "<<lst;
    375     cout <<endl;
    376 
    377     lst.Sort();
    378     cout << "sort: " << lst;
    379     cout <<endl;
    380 
    381     int val;
    382     lst.Remove(2,val);
    383     cout << "remove:(second) " << lst;
    384    // cout<<"FIRST:   "<<lst.getHead()<<endl;
    385     cout <<endl;
    386 
    387     List<int> lst1 = lst;
    388    // cout<<"FIRST:   "<<lst1.getHead()<<endl;
    389     cout << lst1;
    390     lst.MakeEmpty();
    391     lst = lst1;
    392   //  cout<<"FIRST:   "<<lst.getHead()<<endl;
    393     cout << lst;
    394 
    395     return 0;
    396 }

    #调试结果#

    ②带头结点的单链表的实现(类模板)

      1 #include <iostream>
      2 #include <cstdlib>
      3 #include <ctime>
      4 ///带头结点
      5 using namespace std;
      6 //typedef int T;
      7 
      8 template <class T>
      9 struct LinkNode //结点定义
     10 {
     11     T data;//数据域
     12     LinkNode<T>* next;//链域
     13     LinkNode(const T& item, LinkNode<T>* ptr=NULL)
     14     {
     15         data = item;
     16         next = ptr;
     17     }
     18     LinkNode(LinkNode<T>* ptr=NULL)
     19     {
     20         next = ptr;
     21     }
     22 };
     23 
     24 template <class T>
     25 class List
     26 {
     27 private:
     28     LinkNode<T>* first;
     29 public:
     30     List();//构造函数
     31     List(const T& x);
     32     List(const List<T>& L);//拷贝构造函数
     33     List<T>& operator=(const List<T>& L);//赋值运算符函数
     34     ~List();//析构函数
     35 
     36     void InputFront(const T& elem);//头插法
     37     void InputRear(const T& elem);//尾插法
     38 
     39     void MakeEmpty();//清空链表
     40     int Length() const;//返回链表中结点个数
     41 
     42     LinkNode<T>* Search(const T& x);//在链表中查找元素x,找到返回它所在结点的地址,否则返回空
     43     LinkNode<T>* Locate(int i);//返回链表中第i个结点的地址,i取值不合法则返回空
     44     LinkNode<T>* getHead()const;
     45 
     46     bool GetData(int i, T& x)const;//获取链表第i个元素,将它赋值给x
     47     void SetData(int i, const T& x);//设置链表第i个元素为x
     48 
     49     bool Insert(int i, const T& x);//在链表的第i个位置上插入元素x
     50     bool Remove(int i, T& x);//删除链表第i个位置的元素,并将它的值赋值给x
     51 
     52     bool IsEmpty() const;//返回链表是否为空
     53     bool IsFull() const;//返回链表是否为满
     54 
     55     void CopyList(const List<T>& L);//复制链表
     56 
     57     void Sort();//对链表中结点进行排序
     58 
     59     friend ostream& operator<<(ostream& out, const List<T>& L)//输出流运算符重载
     60     {
     61         LinkNode<T> *p=L.first;
     62         p = p->next;
     63         while(p!=NULL)
     64         {
     65             cout << p->data << ' ';
     66             p = p->next;
     67         }
     68         cout << endl;
     69         return out;
     70     }
     71     //  friend istream& operator>>(istream& in, List& L);//输入流运算符重载
     72 };
     73 
     74 template <class T>
     75 List<T>::List()//构造函数
     76 {
     77     first = new LinkNode<T>;  //first不指向NULL了,指向一个头结点
     78 }
     79 
     80 template <class T>
     81 List<T>::List(const T& x)  //构造函数
     82 {
     83     first = new LinkNode<T>(x);
     84 }
     85 
     86 template <class T>
     87 List<T>::List(const List<T>& L)//拷贝构造函数
     88 {
     89     T temp;
     90     LinkNode<T>* strL = L.getHead();
     91     //cout <<L.getHead()<<endl;
     92     // temp = strL->data;
     93     LinkNode<T>* strthis = first = new LinkNode<T>;  //这里也进行了更改
     94     //cout <<first<<endl;
     95     while(strL->next)
     96     {
     97         temp = strL->next->data;  //change
     98         // cout<<temp<<endl;
     99         strthis->next = new LinkNode<T>(temp);
    100         strthis = strthis->next;
    101         strL = strL->next;
    102     }
    103     strthis->next = NULL;
    104 }
    105 
    106 template <class T>
    107 LinkNode<T>* List<T>::getHead()const
    108 {
    109     return first;
    110 }
    111 
    112 
    113 template <class T>
    114 List<T>& List<T>::operator=(const List<T>& L)//赋值运算符函数
    115 {
    116     T temp;
    117     LinkNode<T>* strL = L.getHead();
    118     //cout <<L.getHead()<<endl;
    119     //temp = strL->data;
    120     LinkNode<T>* strthis = first = new LinkNode<T>;
    121     //cout <<first<<endl;
    122     while(strL->next)
    123     {
    124         temp = strL->next->data;
    125         // cout<<temp<<endl;
    126         strthis->next = new LinkNode<T>(temp);
    127         strthis = strthis->next;
    128         strL = strL->next;
    129     }
    130     strthis->next = NULL;
    131     return *this;
    132 }
    133 
    134 template <class T>
    135 List<T>::~List()//析构函数
    136 {
    137     MakeEmpty();
    138 }
    139 
    140 template <class T>
    141 void List<T>::InputFront(const T& elem)//头插法
    142 {
    143     MakeEmpty();
    144     LinkNode<T> *temp = new LinkNode<T>(elem);
    145     if(temp == NULL)
    146         exit(1);
    147     temp->next = first;
    148     first = temp;
    149 }
    150 
    151 template <class T>
    152 void List<T>::InputRear(const T& elem)//尾插法
    153 {
    154     LinkNode<T> *temp;
    155     MakeEmpty();
    156     temp = new LinkNode<T>(elem);
    157     if(first == NULL) //要考虑没有元素的情况
    158         first = temp;
    159     else
    160     {
    161         LinkNode<T> *current = first;
    162         while(current->next)
    163         {
    164             current = current->next;
    165         }
    166         current->next = temp;
    167     }
    168     return;
    169 }
    170 
    171 template <class T>
    172 void List<T>::MakeEmpty()//清空链表
    173 {
    174     LinkNode<T> *q;
    175     while(first->next != NULL) ///这里所有的first都要修改->next
    176     {
    177         q = first->next;
    178         first->next = q->next;
    179         delete q;
    180     }
    181 }
    182 
    183 template <class T>
    184 int List<T>::Length() const//返回链表中结点个数
    185 {
    186     int len = 0;
    187     LinkNode<T> *p = first->next;  ///++++++
    188     while(p)
    189     {
    190         p=p->next;
    191         len++;
    192     }
    193     return len;
    194 }
    195 
    196 template <class T>
    197 LinkNode<T>* List<T>::Search(const T& x)//在链表中查找元素x,找到返回它所在结点的地址,否则返回空
    198 {
    199     LinkNode<T> *p = first->next;   ///++++++
    200     while(p)
    201     {
    202         if(p->data == x)
    203             return p;
    204         p = p->next;
    205     }
    206 }
    207 
    208 template <class T>
    209 LinkNode<T>* List<T>::Locate(int i)//返回链表中第i个结点的地址,i取值不合法则返回空
    210 {
    211     if(i<0)
    212         return NULL;
    213     LinkNode<T> *p = first;
    214     int m = 1;
    215     while(p != NULL && m<i)  ///直接操作就行
    216     {
    217         p = p->next;
    218         m++;
    219     }
    220     return p;
    221 }
    222 
    223 template <class T>
    224 bool List<T>::GetData(int i, T& x)const//获取链表第i个元素,将它赋值给x
    225 {
    226     if(i <= 0)
    227         return NULL;
    228     LinkNode<T> *p = Locate(i);
    229     if(p == NULL)
    230         return false;
    231     x = p->data;
    232     return true;
    233 }
    234 
    235 template <class T>
    236 void List<T>::SetData(int i, const T& x)//设置链表第i个元素为x
    237 {
    238     if(i <= 0)
    239         return;
    240     LinkNode<T> *p = Locate(i+1);
    241     if(p == NULL)
    242         return;
    243     p->data = x;
    244 }
    245 
    246 template <class T>
    247 bool List<T>::Insert(int i, const T& x)//在链表的第i个位置上插入元素x
    248 {
    249 
    250     LinkNode<T> *pre = Locate(i);  ///有的时候不要自己写那么麻烦,直接使用函数,再比如copyList
    251 
    252     if(pre == NULL)
    253         return false;
    254 
    255     LinkNode<T> *newNode = new LinkNode<T>(x);
    256     newNode -> next = pre -> next;
    257     pre -> next = newNode;
    258 
    259     return true;
    260 }
    261 
    262 template <class T>
    263 bool List<T>::Remove(int i, T& x)//删除链表第i个位置的元素,并将它的值赋值给x
    264 {
    265     LinkNode<T> *p = Locate(i);
    266     if(p == NULL || p->next == NULL)
    267         return false;
    268     LinkNode<T> *del = p->next;
    269     x = del->data;
    270     p->next = del->next;
    271 
    272     delete del;
    273     return true;
    274 }
    275 
    276 template <class T>
    277 bool List<T>::IsEmpty() const//返回链表是否为空
    278 {
    279     if(first->next = NULL)
    280         return true;
    281     else
    282         return false;
    283 }
    284 
    285 template <class T>
    286 bool List<T>::IsFull() const//返回链表是否为满
    287 {
    288     return false;
    289 }
    290 
    291 template <class T>
    292 void List<T>::CopyList(const List& L)                     //复制链表
    293 {
    294     LinkNode<T> *iter = new LinkNode<T>;
    295     LinkNode<T> *rear = new LinkNode<T>;
    296     if(L.first == NULL)
    297         return;
    298     LinkNode<T> *newNode = new LinkNode<T>(L.first -> data);
    299     first = newNode;
    300     iter = L.first -> next;
    301     rear = newNode;
    302     while(iter)
    303     {
    304         LinkNode<T> *newNode = new LinkNode<T>(iter -> data);
    305         rear -> next = newNode;
    306         iter = iter -> next;
    307         rear = rear -> next;
    308     }
    309 }
    310 
    311 
    312 template <class T>
    313 void List<T>::Sort()//对链表中结点进行排序
    314 {
    315     LinkNode<T> *current = this->first->next;
    316     int temp;
    317     while(current->next != NULL)
    318     {
    319         LinkNode<T>* second = current->next;
    320         while(second != NULL)
    321         {
    322             if((current->data) > (second->data))
    323             {
    324                 temp = current->data;
    325                 current->data = second->data;
    326                 second->data = temp;
    327             }
    328             second = second->next;
    329         }
    330         current = current->next;
    331     }
    332 }
    333 
    334 
    335 //template <class T>
    336 //friend istream& operator>>(istream& in, List& L)//输入流运算符重载
    337 //{
    338 
    339 //}
    340 
    341 int main()
    342 {
    343     List<int> lst;
    344     srand(time(NULL));
    345     for(int i=1; i<=5; i++)
    346         lst.Insert(i,rand()%50);
    347     cout << "past: " <<lst;
    348     cout <<endl;
    349 
    350     lst.SetData(3,999);
    351     cout<<"SetData,No.3=999: "<<lst;
    352     cout <<endl;
    353 
    354     lst.Sort();
    355     cout << "sort: " << lst;
    356     cout <<endl;
    357 
    358     int val;
    359     lst.Remove(2,val);
    360     cout << "remove:(second) " << lst;
    361     // cout<<"FIRST:   "<<lst.getHead()<<endl;
    362     cout <<endl;
    363 
    364     List<int> lst1 = lst;
    365     // cout<<"FIRST:   "<<lst1.getHead()<<endl;
    366     cout << lst1;
    367     lst.MakeEmpty();
    368     lst = lst1;
    369     //  cout<<"FIRST:   "<<lst.getHead()<<endl;
    370     cout << lst;
    371 
    372     return 0;
    373 }

    #调试结果#

  • 相关阅读:
    ylbtech-dbs-m-YinTai(银泰网)
    ylbtech-memorandum(备忘录)-数据库设计
    设计工作-Axure
    RegexHelper
    convert image to base64
    MVC Movie App
    ASP.NET MVC file download sample
    MVC架构、WebForm与MVC对比
    第2章 数字之魅——子数组之和的最大值(二维)
    第2章 数字之魅——求数组的子数组之和的最大值
  • 原文地址:https://www.cnblogs.com/syzyaa/p/13747937.html
Copyright © 2011-2022 走看看