【本文谢绝转载原文来自http://990487026.blog.51cto.com】
数据结构与算 5:C++ 顺序/链式存储,栈 模板类实现 C++ 顺序存储模板类的实现[面试重要] C++ 链式存储模板类的实现[面试重要] C++ 链式存储模板类,载入指针 c++ 栈的链式存储实现(模板类嵌套模板类),编译问题教训[重要]
C++ 顺序存储模板类的实现[面试重要]
项目文件:
[email protected]://990487026.blog.51cto.com~/c++$ tree . ├── main.cpp ├── seqlist.cpp └── seqlist.h 0 directories, 4 files ================================
main.cpp文件
[email protected]://990487026.blog.51cto.com~/c++$ cat main.cpp //C++ 构建模板类 顺序存储 #include <iostream> #include <stdio.h> #include <string.h> #include "seqlist.cpp" using namespace std; struct Teacher { char name[64]; int age; }; void fun() { int i = 0; struct Teacher tmp; struct Teacher t1; t1.age = 31; struct Teacher t2; t2.age = 32; struct Teacher t3; t3.age = 33; seqlist<Teacher> list(10);//创建顺序表 list.insert(t1,0);//头插法 list.insert(t2,0);//头插法 list.insert(t3,0);//头插法 //遍历链表 for(i=0;i<list.getLen();i++) { list.get(i,tmp); cout <<tmp.age <<" get\n"; } list.clear();// 清空链表 list.insert(t1,0);//头插法 list.insert(t2,0);//头插法 list.insert(t3,0);//头插法 //循环删除 while(list.getLen() > 0) { list.del(0,tmp);////头删除 cout <<tmp.age <<" del\n"; } } int main() { fun(); return 0; } [email protected]://990487026.blog.51cto.com~/c++$
seqlist.cpp文件
[email protected]://990487026.blog.51cto.com~/c++$ cat seqlist.cpp #include <stdio.h> #include "seqlist.h" template <typename T> seqlist<T>::seqlist(int Capacity) { this->pArray = new T[Capacity]; this->capacity = Capacity; this->len = 0; } template <typename T> seqlist<T>::~seqlist(void) { delete [] this->pArray; this->pArray = NULL; this->capacity = 0; this->len = 0; } template <typename T> int seqlist<T>::getLen() { return this->len; } template <typename T> int seqlist<T>::getCapacity() { return this->capacity; } template <typename T> int seqlist<T>::insert(T &t,int pos) { int i = 0; if(pos <0) { return -1; } for(i=this->len;i>pos;i--) { pArray[i] = pArray[i-1]; } pArray[i] = t;//STL元素保存时,通过复制机制实现的,你的类要可以复制才行 this->len++; return 0; } template <typename T> int seqlist<T>::get(int pos,T &t) { if(pos <0) { return -1; } t = pArray[pos]; return 0; } template <typename T> int seqlist<T>::del(int pos,T &t) { int i = 0; t = pArray[pos]; for(i=pos+1;i<this->len;i++) { pArray[i-1] = pArray[i]; } this->len--; return 0; } template <typename T> int seqlist<T>::clear()//回到初始状态 { this->len = 0; return 0; } [email protected]://990487026.blog.51cto.com~/c++$
seqlist.h文件
[email protected]://990487026.blog.51cto.com~/c++$ cat seqlist.h #pragma once template <typename T> class seqlist { public: seqlist(int Capacity); ~seqlist(void); int getLen(); int getCapacity(); int insert(T &t,int pos); int get(int pos,T &t); int del(int pos,T &t); int clear();//清空链表 private: int len; int capacity; T *pArray; }; [email protected]://990487026.blog.51cto.com~/c++$
编译运行:
[email protected]://990487026.blog.51cto.com~/c++$ g++ main.cpp -Wall && ./a.out 33 get 32 get 31 get 33 del 32 del 31 del [email protected]://990487026.blog.51cto.com~/c++$
C++ 链式存储模板类的实现[面试重要]
项目文件:
[email protected]://990487026.blog.51cto.com~/c++/linklist_链式存储模板类$ tree . ├── linklist.cpp ├── linklist.h └── main.cpp 0 directories, 3 files
linklist.cpp 文件
[email protected]://990487026.blog.51cto.com~/c++/linklist_链式存储模板类$ cat linklist.cpp #include <stdio.h> #include "linklist.h" template <typename T> LinkList<T>::LinkList(void) { this->head = new Node<T>; this->head->next = NULL;//初始化 this->length =0;//初始化 } template <typename T> LinkList<T>::~LinkList(void) { Node<T> *tmp = NULL; while(this->head) { tmp = this->head->next; delete head; this->head = tmp; } this->length = 0; this->head =NULL; } template <typename T> int LinkList<T>::clear(void) { Node<T> *tmp = NULL; while(this->head) { tmp = this->head->next; delete head; this->head = tmp; } this->length = 0; this->head = new Node<T>; this->head->next = NULL;//初始化 this->length =0;//初始化 return 0; } template <typename T> int LinkList<T>::len(void) { return this->length; } template <typename T> int LinkList<T>::insert(T &t,int pos) { Node<T> *current = this->head; for(int i = 0;i<pos;i++) { current = current->next; } Node<T> *node = new Node<T>; if(node == NULL) { return -1; } node->t = t;//缓冲外部数据,调用拷贝构造函数 node->next = current->next;//让新节点连接后续表 current->next = node; this->length++; return 0; } template <typename T> int LinkList<T>::get(int pos,T &t) { Node<T> *current = NULL; current = this->head; for(int i = 0;i<pos;i++) { current = current->next; } t = current->next->t;//把缓存的节点给他 return 0; } template <typename T> int LinkList<T>::del(int pos,T &t) { Node<T> *current = this->head; for(int i = 0;i<pos;i++) { current = current->next; } Node<T> *ret = current->next;//被删除的元素 t = ret->t;////把缓存的节点给他 current->next = ret->next; this->length--; delete ret;//释放内存 return 0; } [email protected]://990487026.blog.51cto.com~/c++/linklist_链式存储模板类$
linklist.h文件
[email protected]://990487026.blog.51cto.com~/c++/linklist_链式存储模板类$ cat linklist.h #pragma once //模板类里面,在插入元素的时候,应该把每一个t保存起来 template <typename T> struct Node { T t; Node<T> *next;//搞成链表 }; template <typename T> class LinkList { public: LinkList(); ~LinkList(); int clear(); int len(); int insert(T &t,int pos ); int get (int pos,T &t); int del(int pos,T &t); private: Node<T> *head;//指向链表的头指针 int length; }; [email protected]://990487026.blog.51cto.com~/c++/linklist_链式存储模板类$
main.cpp文件
[email protected]://990487026.blog.51cto.com~/c++/linklist_链式存储模板类$ cat main.cpp #include <iostream> #include <stdio.h> #include <string.h> #include "linklist.cpp" using namespace std; struct Teacher { char name[64]; int age; }; int main() { int i = 0; struct Teacher tmp; struct Teacher t1; t1.age = 31; struct Teacher t2; t2.age = 32; struct Teacher t3; t3.age = 33; LinkList<Teacher> list;//实例化 链式储存类 list.insert(t1,0);//头插法 list.insert(t2,0);//头插法 list.insert(t3,0);//头插法 //遍历链表 for(i=0;i<list.len();i++) { list.get(i,tmp); cout <<tmp.age <<" get\n"; } list.clear();// 清空链表 list.insert(t1,0);//头插法 list.insert(t2,0);//头插法 list.insert(t3,0);//头插法 //循环删除 while(list.len() > 0) { list.del(0,tmp);////头删除 cout <<tmp.age <<" del\n"; } return 0; } [email protected]://990487026.blog.51cto.com~/c++/linklist_链式存储模板类$
编译运行:
[email protected]://990487026.blog.51cto.com~/c++/linklist_链式存储模板类 $ g++ main.cpp linklist.cpp -Wall && ./a.out 33 get 32 get 31 get 33 del 32 del 31 del [email protected]://990487026.blog.51cto.com~/c++/linklist_链式存储模板类$
C++ 链式存储模板类,载入指针
linklist.cpp,linklist.h文件不变的
以下是main程序:
[email protected]://990487026.blog.51cto.com~/c++/linklist_链式存储模板类$ cat main.cpp #include <iostream> #include <stdio.h> #include <string.h> #include "linklist.cpp" using namespace std; struct Teacher { char name[64]; int age; }; int main() { int i = 0; struct Teacher *tmp = NULL; struct Teacher t1; t1.age = 31; struct Teacher t2; t2.age = 32; struct Teacher t3; t3.age = 33; struct Teacher *p1 = &t1; struct Teacher *p2 = &t2; struct Teacher *p3 = &t3; LinkList<Teacher*> list;//实例化 链式储存类 list.insert(p1,0);//头插法 list.insert(p2,0);//头插法 list.insert(p3,0);//头插法 //遍历链表 for(i=0;i<list.len();i++) { list.get(i,tmp); cout <<tmp->age <<" get\n"; } list.clear();// 清空链表 list.insert(p1,0);//头插法 list.insert(p2,0);//头插法 list.insert(p3,0);//头插法 //循环删除 while(list.len() > 0) { list.del(0,tmp);////头删除 cout <<tmp->age <<" del\n"; } return 0; } [email protected]://990487026.blog.51cto.com~/c++/linklist_链式存储模板类$ g++ main.cpp linklist.cpp -Wall && ./a.out 33 get 32 get 31 get 33 del 32 del 31 del [email protected]://990487026.blog.51cto.com~/c++/linklist_链式存储模板类$
c++ 栈的链式存储实现(模板类嵌套模板类),编译问题教训[重要]
项目文件:
[email protected]://990487026.blog.51cto.com~/c++/link_stack$ tree . ├── linklist.cpp ├── linklist.h ├── LinkStack.cpp ├── LinkStack.h └── main.cpp 0 directories, 5 files
linklist.cpp 文件
[email protected]://990487026.blog.51cto.com~/c++/link_stack$ cat linklist.cpp #include <stdio.h> #include "linklist.h" template <typename T> LinkList<T>::LinkList(void) { this->head = new Node<T>; this->head->next = NULL;//初始化 this->length =0;//初始化 } template <typename T> LinkList<T>::~LinkList(void) { Node<T> *tmp = NULL; while(this->head) { tmp = this->head->next; delete head; this->head = tmp; } this->length = 0; this->head =NULL; } template <typename T> int LinkList<T>::clear(void) { Node<T> *tmp = NULL; while(this->head) { tmp = this->head->next; delete head; this->head = tmp; } this->length = 0; this->head = new Node<T>; this->head->next = NULL;//初始化 this->length =0;//初始化 return 0; } template <typename T> int LinkList<T>::len(void) { return this->length; } template <typename T> int LinkList<T>::insert(T &t,int pos) { Node<T> *current = this->head; for(int i = 0;i<pos;i++) { current = current->next; } Node<T> *node = new Node<T>; if(node == NULL) { return -1; } node->t = t;//缓冲外部数据 node->next = current->next;//让新节点连接后续表 current->next = node; this->length++; return 0; } template <typename T> int LinkList<T>::get(int pos,T &t) { Node<T> *current = NULL; current = this->head; for(int i = 0;i<pos;i++) { current = current->next; } t = current->next->t;//把缓存的节点给他 return 0; } template <typename T> int LinkList<T>::del(int pos,T &t) { Node<T> *current = this->head; for(int i = 0;i<pos;i++) { current = current->next; } Node<T> *ret = current->next;//被删除的元素 t = ret->t;////把缓存的节点给他 current->next = ret->next; this->length--; delete ret;//释放内存 return 0; } [email protected]://990487026.blog.51cto.com~/c++/link_stack$
linklist.h 文件
[email protected]://990487026.blog.51cto.com~/c++/link_stack$ cat linklist.h #pragma once //模板类里面,在插入元素的时候,应该把每一个t保存起来 template <typename T> struct Node { T t; Node<T> *next;//搞成链表 }; template <typename T> class LinkList { public: LinkList(void); ~LinkList(void); int clear(void); int len(void); int insert(T &t,int pos ); int get (int pos,T &t); int del(int pos,T &t); private: Node<T> *head;//指向链表的头指针 int length; }; [email protected]://990487026.blog.51cto.com~/c++/link_stack$
LinkStack.cpp 文件
[email protected]://990487026.blog.51cto.com~/c++/link_stack$ cat LinkStack.cpp #include <stdio.h> #include "LinkStack.h" #include "linklist.cpp"//不要包含linklist.h,编译模板类包含linklist.cpp,不然老是报错找不到函数 template <typename T> LinkStack<T>::LinkStack(void) { this->list = new LinkList<T>; //创建栈就相当于创建线性表 } template <typename T> LinkStack<T>::~LinkStack(void) { clear(); delete list; list = NULL; } template <typename T> void LinkStack<T>::clear() { list->clear(); } template <typename T> int LinkStack<T>::push(T &t) { return list->insert(t,0); //向栈中添加元素 } template <typename T> int LinkStack<T>::pop(T &t) { return this->list->del(0,t);//传出元素,删除头部元素 } template <typename T> int LinkStack<T>::top(T &t) { return this->list->get(0,t);//获取头部元素 } template <typename T> int LinkStack<T>::size() { return this->list->len(); } [email protected]://990487026.blog.51cto.com~/c++/link_stack$
LinkStack.h 文件
[email protected]://990487026.blog.51cto.com~/c++/link_stack$ cat LinkStack.h #pragma once #include "linklist.h" template <typename T> class LinkStack { public: LinkStack(void); ~LinkStack(void); void clear(); int push(T &t); int pop(T &t); int top(T &t); int size(); private: LinkList<T> *list;//实例化一个链表 }; [email protected]://990487026.blog.51cto.com~/c++/link_stack$
main.cpp 文件
[email protected]://990487026.blog.51cto.com~/c++/link_stack$ cat main.cpp /* g++ 编译模板类 ,老是报错,烦啊!!! [email protected]://990487026.blog.51cto.com~/c++/link_stack$ g++ main.cpp LinkStack.cpp linklist.cpp /tmp/ccd3WOZY.o: In function `LinkStack<Teacher>::LinkStack()‘: main.cpp:(.text._ZN9LinkStackI7TeacherEC2Ev[_ZN9LinkStackI7TeacherEC5Ev]+0x20): undefined reference to `LinkList<Teacher>::LinkList()‘ /tmp/ccd3WOZY.o: In function `LinkStack<Teacher>::~LinkStack()‘: main.cpp:(.text._ZN9LinkStackI7TeacherED2Ev[_ZN9LinkStackI7TeacherED5Ev]+0x29): undefined reference to `LinkList<Teacher>::~LinkList()‘ /tmp/ccd3WOZY.o: In function `LinkStack<Teacher>::push(Teacher&)‘: main.cpp:(.text._ZN9LinkStackI7TeacherE4pushERS0_[_ZN9LinkStackI7TeacherE4pushERS0_]+0x27): undefined reference to `LinkList<Teacher>::insert(Teacher&, int)‘ /tmp/ccd3WOZY.o: In function `LinkStack<Teacher>::top(Teacher&)‘: main.cpp:(.text._ZN9LinkStackI7TeacherE3topERS0_[_ZN9LinkStackI7TeacherE3topERS0_]+0x24): undefined reference to `LinkList<Teacher>::get(int, Teacher&)‘ /tmp/ccd3WOZY.o: In function `LinkStack<Teacher>::size()‘: main.cpp:(.text._ZN9LinkStackI7TeacherE4sizeEv[_ZN9LinkStackI7TeacherE4sizeEv]+0x17): undefined reference to `LinkList<Teacher>::len()‘ /tmp/ccd3WOZY.o: In function `LinkStack<Teacher>::pop(Teacher&)‘: main.cpp:(.text._ZN9LinkStackI7TeacherE3popERS0_[_ZN9LinkStackI7TeacherE3popERS0_]+0x24): undefined reference to `LinkList<Teacher>::del(int, Teacher&)‘ /tmp/ccd3WOZY.o: In function `LinkStack<Teacher>::clear()‘: main.cpp:(.text._ZN9LinkStackI7TeacherE5clearEv[_ZN9LinkStackI7TeacherE5clearEv]+0x17): undefined reference to `LinkList<Teacher>::clear()‘ collect2: error: ld returned 1 exit status [email protected]://990487026.blog.51cto.com~/c++/link_stack$ g++ 编译模板类的两种方式 关于模板类声明与实现分离(即声明放在.h文件,实现放在.cpp文件)的测试。 最近在写模板类的时候,分开编译模板声明和模板实现老实编译不过。看提示应该是链接不到实现的函数。 原来原因是模板的具体定义要在模板参数确定了之后才能实例化。 而在模板实例化的过程中(比如在main函数中,但只包含模板声明函数)。包含实例化的.cpp文件编译成.o文件,留了类函数的入口地址等待填充。 一般,包含普通函数的.cpp文件编译成.o文件时。函数是确定的,能编译成二进制代码。然后就有函数入口地址可以让链接程序填入调用了这个函数的.o文件中。然后函数调用就成功了。 但是,对于模板类的实现。编译成.o文件时,仍然没有实例化。就是说模板类的实现函数不知道具体的模板函数是什么,不能实例化成一个真正的类型. (比如Vector<int> a ; //参数实例化成int,vector<int>为一个类型( 和内置类型double一样了 ))。 但是没有实例化前,函数是不确定的。就是还没有编译成二进制文件。所以没有函数的入口地址提供。由于没有入口地址,链接程序在帮main函数找实例化成具体类型的模板找实现函数时找不到,就提示链接错误了。 既然知道哪里粗了问题,就可以解决问题了。解决的办法就是让实例化了模板的.cpp文件可以看到函数实现就行了。 1、直接把函数声明和函数实现全部放在同一个.h文件里面。这样引用.h文件的时候,声明和实现都直接展开在实例化的.cpp文件里面这样编译的时候就能找到函数的入口地址了。 2、函数声明和函数实现分开实现。在实例化模板的地方#include "xxx.cpp",即直接包含.cpp文件,这样也能找到函数入口。本程序引用这种方法. */ #include <iostream> #include "LinkStack.cpp" using namespace std; struct Teacher { char name[64]; int age; }; int main() { //创建栈 LinkStack<Teacher> stack;//实例化类 struct Teacher tmp; struct Teacher t1; t1.age = 31; struct Teacher t2; t2.age = 32; struct Teacher t3; t3.age = 33; //入栈 stack.push(t1); stack.push(t2); stack.push(t3); //谁是栈顶 stack.top(tmp); cout << tmp.age<<" top \n"; //清空栈 stack.clear(); //入栈 stack.push(t1); stack.push(t2); stack.push(t3); //栈的删除 while(stack.size()) { stack.pop(tmp); cout << tmp.age<<" pop \n"; } return 0; } [email protected]://990487026.blog.51cto.com~/c++/link_stack$
编译运行:
[email protected]://990487026.blog.51cto.com~/c++/link_stack$ g++ main.cpp LinkStack.cpp linklist.cpp -Wall && ./a.out 33 top 33 pop 32 pop 31 pop [email protected]://990487026.blog.51cto.com~/c++/link_stack$
【本文谢绝转载原文来自http://990487026.blog.51cto.com】
时间: 2024-10-12 17:32:21