• 线性表-链式存储结构(单链表)


    需要注意的问题:类模板无法分开链接问题。

    类模板在编译的时候没有错误,但是在链接过程中会报错

    error LNK2019: unresolved external symbol "public: __thiscall LinkList<int>::~LinkList<int>(void)" (??1?$LinkList@H@@QAE@XZ) referenced in function _main

    这是由于类模板的声明和实现不能放在不同的文件中,即类模板的声明和实现是不能分离的。因为类模板和函数模板都不是真正的定义,真正的定义是在模板实体化的时候由编译器完成的。如果将模板的定义部分和实现部分分离开来,编译器真正要去完成模板实体化的时候就会因为找不到相应的代码而发生链接错误。

      1: //linklist.cpp
    
      2: #ifndef LINKLIST_CPP_CPP //为了解决类模板无法分开链接问题,需要include该实现文件,并注意重复包含问题。
    
      3: #define LINKLIST_CPP_CPP
    
      4: 
    
      5: #include "linklist.h"
    
      6: #include <iostream>
    
      7: 
    
      8: template<class T>
    
      9: LinkList<T>::LinkList()
    
     10: {
    
     11:   head = new Node(T);
    
     12:   head->next = NULL;
    
     13: }
    
     14: 
    
     15: template<class T>
    
     16: LinkList<T>::LinkList(T dataArray[], int n)
    
     17: {
    
     18:   Node<T> * currentNode, * newNode;
    
     19:   head = new Node<T>;
    
     20:   currentNode = head;
    
     21:   for(int i = 0; i < n; ++i)
    
     22:   {
    
     23:     newNode = new Node<T>;
    
     24:     newNode->data = dataArray[i];
    
     25:     currentNode->next = newNode;
    
     26:     currentNode = newNode;
    
     27:   }
    
     28:   currentNode->next = NULL;
    
     29: }
    
     30: 
    
     31: template<class T>
    
     32: LinkList<T>::~LinkList()
    
     33: {
    
     34:   Node<T> * ptr, * pTemp;
    
     35:   ptr = head;
    
     36:   while(ptr)
    
     37:   {
    
     38:     pTemp = ptr;
    
     39:     ptr = ptr->next;
    
     40:     delete pTemp;
    
     41:   }
    
     42:   head = NULL;
    
     43: }
    
     44: 
    
     45: template<class T>
    
     46: int LinkList<T>::ListLength()
    
     47: {
    
     48:   Node<T> * ptr;
    
     49:   int count = 0;
    
     50:   ptr = head->next;
    
     51:   while(ptr)
    
     52:   {
    
     53:     ptr = ptr->next;
    
     54:     ++count;
    
     55:   }
    
     56:   return count;
    
     57: }
    
     58: 
    
     59: template<class T>
    
     60: T LinkList<T>::GetItem(int pos)
    
     61: {
    
     62:   Node<T> * ptr;
    
     63:   ptr = head->next;
    
     64:   int position = 1;
    
     65:   while(ptr && (position < pos))
    
     66:   {
    
     67:     ptr = ptr->next;
    
     68:     ++position;
    
     69:   }
    
     70:   if(!ptr)
    
     71:   {
    
     72:     cerr<<"Cannot find the Item."<<endl;
    
     73:     exit(1);
    
     74:   }
    
     75:   else
    
     76:   {
    
     77:     return ptr->data;
    
     78:   }
    
     79: }
    
     80: 
    
     81: template<class T>
    
     82: int LinkList<T>::LocateItem(T item)
    
     83: {
    
     84:   Node<T> * ptr;
    
     85:   ptr = head->next;
    
     86:   int position = 1;
    
     87:   while(ptr && (ptr->data != item))
    
     88:   {
    
     89:     ptr = ptr->next;
    
     90:     ++position;
    
     91:   }
    
     92:   if(ptr)
    
     93:   {
    
     94:     return position;
    
     95:   }
    
     96:   else
    
     97:   {
    
     98:     return 0;
    
     99:   }
    
    100: }
    
    101: 
    
    102: template<class T>
    
    103: void LinkList<T>::PrintLinkList()
    
    104: {
    
    105:   Node<T> * ptr;
    
    106:   ptr = head->next;
    
    107:   while(ptr)
    
    108:   {
    
    109:     cout<<ptr->data<<endl;
    
    110:     ptr = ptr->next;
    
    111:   }
    
    112: }
    
    113: 
    
    114: template<class T>
    
    115: void LinkList<T>::InsertItem(int pos, T item)
    
    116: {
    
    117:   Node<T> * ptr, * pTemp;
    
    118:   ptr = head;
    
    119:   int position = 1;
    
    120:   while(ptr && (position < pos))
    
    121:   {
    
    122:     ptr = ptr->next;
    
    123:     ++position;
    
    124:   }
    
    125:   if(!ptr)
    
    126:   {
    
    127:     cerr<<"Cannot insert in this position."<<endl;
    
    128:     exit(1);
    
    129:   }
    
    130:   else
    
    131:   {
    
    132:     pTemp = new Node<T>;
    
    133:     pTemp->data = item;
    
    134:     pTemp->next = ptr->next;
    
    135:     ptr->next = pTemp;
    
    136:   }
    
    137: }
    
    138: 
    
    139: template<class T>
    
    140: T LinkList<T>::DeleteItem(int pos)
    
    141: {
    
    142:   Node<T> * ptr, * pTemp;
    
    143:   T item;
    
    144:   ptr = head;
    
    145:   int position = 1;
    
    146:   while(ptr && (position < pos))
    
    147:   {
    
    148:     ptr = ptr->next;
    
    149:     ++position;
    
    150:   }
    
    151:   if(!ptr || !ptr->next)
    
    152:   {
    
    153:     cerr<<"Cannot fine item need to delete in this position."<<endl;
    
    154:     exit(1);
    
    155:   }
    
    156:   else
    
    157:   {
    
    158:     pTemp = ptr->next;
    
    159:     item = pTemp->data;
    
    160:     ptr->next = pTemp->next;
    
    161:     delete pTemp;
    
    162:     return item;
    
    163:   }
    
    164: }
    
    165: 
    
    166: template<class T>
    
    167: void LinkList<T>::InvertItem()
    
    168: {
    
    169:   Node<T> *ptr, *pTemp;
    
    170:   ptr = head->next;
    
    171:   head->next = NULL;
    
    172:   while(ptr != NULL)
    
    173:   {
    
    174:     pTemp = ptr;
    
    175:     ptr = ptr->next;
    
    176:     pTemp->next = head->next;
    
    177:     head->next = pTemp;
    
    178:   }
    
    179: }
    
    180: 
    
    181: template<class T>
    
    182: void LinkList<T>::Merge(LinkList<T> &linklist)
    
    183: {
    
    184:   Node<T> *p1,*p2,*p3;
    
    185:   p1 = this->head->next;
    
    186:   p2 = linklist.head->next;
    
    187:   p3 = this->head;
    
    188: 
    
    189:   while((p1 != NULL) && (p2 != NULL))
    
    190:   {
    
    191:     if(p1->data < p2->data)
    
    192:     {
    
    193:       p3->next = p1;
    
    194:       p1 = p1->next;
    
    195:       p3 = p3->next;
    
    196:     }
    
    197:     else
    
    198:     {
    
    199:       p3->next = p2;
    
    200:       p2 = p2->next;
    
    201:       p3 = p3->next;
    
    202:     }
    
    203:   }
    
    204:   if(!p1)
    
    205:   {
    
    206:     p3->next = p1;
    
    207:   }
    
    208:   if(!p2)
    
    209:   {
    
    210:     p3->next = p2;
    
    211:   }
    
    212: 
    
    213:   delete linklist.head;
    
    214:   linklist.head = NULL;
    
    215: }
    
    216: 
    
    217: #endif
      1: //linkList.h
    
      2: 
    
      3: #ifndef LINKLIST_H_H
    
      4: #define LINKLIST_H_H
    
      5: 
    
      6: //#include <iostream>
    
      7: using namespace std;
    
      8: 
    
      9: template<class T>
    
     10: struct Node
    
     11: {
    
     12:   T data;
    
     13:   Node<T> * next;
    
     14: };
    
     15: 
    
     16: template<class T>
    
     17: class LinkList
    
     18: {
    
     19: private:
    
     20:   Node<T> * head;
    
     21: public:
    
     22:   LinkList();
    
     23:   LinkList(T dataArray[], int n);
    
     24:   ~LinkList();
    
     25:   int ListLength();
    
     26:   T GetItem(int pos);
    
     27:   int LocateItem(T item);
    
     28:   void PrintLinkList();
    
     29:   void InsertItem(int pos, T item);
    
     30:   T DeleteItem(int pos);
    
     31:   void InvertItem();//反转
    
     32:   void Merge(LinkList<T> &linklist);//合并
    
     33: };
    
     34: 
    
     35: 
    
     36: #endif
      1: //test.cpp
    
      2: 
    
      3: #include "linklist.h"
    
      4: #include "linklist.cpp" //类模板无法分开链接
    
      5: #include <iostream>
    
      6: using namespace std;
    
      7: 
    
      8: int main(int argc, char * argv[])
    
      9: {
    
     10:   int array1[] = {1,3,5,7,9};
    
     11:   int array2[] = {2,4,6,8,10};
    
     12: 
    
     13:   LinkList<int> linklist(array1,5);
    
     14:   LinkList<int> linklist2(array2,5);
    
     15: 
    
     16:   cout<<"Show all item:"<<endl;
    
     17:   linklist.PrintLinkList();
    
     18: 
    
     19:   cout<<"Length:"<<linklist.ListLength()<<endl;
    
     20: 
    
     21:   cout<<"The second item is:"<<linklist.GetItem(2)<<endl;
    
     22: 
    
     23:   cout<<"item 3 is in position:"<<linklist.LocateItem(3)<<endl;
    
     24: 
    
     25:   cout<<"Insert item 5 in position 4:"<<endl;
    
     26:   linklist.InsertItem(4,5);
    
     27:   cout<<"Show all item:"<<endl;
    
     28:   linklist.PrintLinkList();
    
     29: 
    
     30:   cout<<"Invert:"<<endl;
    
     31:   linklist.InvertItem();
    
     32:   cout<<"Show all item:"<<endl;
    
     33:   linklist.PrintLinkList();
    
     34: 
    
     35:   cout<<"Show linklist1:"<<endl;
    
     36:   linklist.PrintLinkList();
    
     37:   cout<<"Show linklist2:"<<endl;
    
     38:   linklist2.PrintLinkList();
    
     39:   cout<<"Merge them:"<<endl;
    
     40:   linklist.Merge(linklist2);
    
     41:   linklist.PrintLinkList();
    
     42:   
    
     43:   return 0;
    
     44: }
    作者:Lucas Hsueh
    文章部分是自己的学习体会、代码等,还有收集和整理其他技术牛人的文章。
  • 相关阅读:
    Android sdk 下载路径
    centos修改用户用户组
    centos7 通过shell切换root用户
    java 服务上传图片到linux没有读写权限
    Mybatis第二天
    Mybatis第一天
    反射
    注解
    多线程第二天
    java---过滤器、监听器
  • 原文地址:https://www.cnblogs.com/lucas-hsueh/p/3711331.html
Copyright © 2020-2023  润新知