C++实现单链表(用函数模板)

来源:互联网 发布:部落战争手游源码下载 编辑:程序博客网 时间:2024/06/07 03:11

之前一直都是用的Java学习的数据结构,这里把自己学习C++时用C++实现数据结构之单链表的代码直接贴出来,以供参考,还有很多可以改进之处,就不那么纠结了,作为学习数据结构的C++代码实现,应该是足够了。

编码的格式规范是Java的,个人觉得这种范式更加清晰明了。

调试环境是VS2013及VC++6.0,均全部通过。

///////////////////////单链表////////////////////////////////*SingleLinkedList.h文件:用于定义单链表的节点及方法*/using namespace std;///////表示单链表中节点的结构体///////////////////////////////////////////////////////////////////////////////////template<typename T> //用函数模板的原因是:链表节点中存储的数据类型不确定class Node{public:    /*节点存储的数据*/    T element;    /*指向下一个节点的指针*/    Node *next;public:    /*空构造器*/    Node(){}    /*构造器*/    Node(T e){        element = e;    }};////////////////////////////单链表类的定义////////////////////template<typename T>class SingleLinkedList{private:    /*链表长度,存储的结点个数*/    int size;    /*表头节点,节点中存储的数据的类型为T*/    Node<T> *head;    /*获取链表中指定索引上的节点,仅供内部调用*/    Node<T>* node(int index);public:    /*构造器*/    SingleLinkedList();    /*析构函数*/    ~SingleLinkedList();    /*获取链表长度,即当前链表中结点的个数*/    int length();    /*检查索引范围*/    bool checkIndex(int index);    /*添加指定的数据到链表尾部*/    bool insert(T element);    /*添加指定的数据到指定的索引位置*/    bool insert(int index, T element);    /*删除指定位置上的数据*/    bool remove(int index);    /*获取指定索引上的数据*/    T get(int index);    /*获取指定数据的索引,不存在时返回0*/    int getIndex(T element);    /*将指定位置的数据修改为给定的数据element*/    void set(int index, T element);    /*打印整个链表*/    void print();    /*释放整个链表*/    void freeList();};
///////////////////////SingleLinkedList.cpp/////////////////*包含测试代码的main()函数,放在了.cpp文件的最后。一般而言,单独写成一个test.cpp会更好点。*/#include <iostream>#include <string>#include "SingleLinkedList.h"using namespace std;/*构造器*/template<typename T>SingleLinkedList<T>::SingleLinkedList(){    this->head = new Node<T>();//调用默认构造器    this->size = 0;//初始化长度为0    this->head->next = NULL;}template<typename T>SingleLinkedList<T>::~SingleLinkedList(){}/*获取链表长度,即当前链表中结点的个数@return 链表的大小*/template<typename T>int SingleLinkedList<T>::length(){    return this->size;}/*检查索引范围@param index 索引@return 索引合法,则返回true;否则,返回false*/template<typename T>bool SingleLinkedList<T>::checkIndex(int index){    return index >= 0 && index <= size;}/*获取指定索引上的节点@param index 给定的索引@return 节点对象*/template<typename T>Node<T>* SingleLinkedList<T>::node(int index){    checkIndex(index);    Node<T>* n = this->head;    for (int i = 0; i < index; i++){        n = n->next;    }    return n;}/*添加指定的数据到链表尾部@param element 需要添加到链表尾位的数据@return 添加成功,返回true;否则,返回false*/template<typename T>bool SingleLinkedList<T>::insert(T element){    Node<T>* newNode = new Node<T>(element);//构造节点对象    //如果链表是空    if (this->size == 0){        this->head = newNode;    }    //链表非空    Node<T>* temp = this->head;    while (temp->next != NULL){//从头节点开始,找到最后一个节点,判断条件中必须是n->next,而不能是n        temp = temp->next;    }    temp->next = newNode;    newNode->next = NULL;//这句不可少    size++;    return true;}/*添加指定的数据到指定的索引位置@param index 指定的索引位置@param element 将要插入的数据@return 插入数据成功,返回true;否则,返回false*/template<typename T>bool SingleLinkedList<T>::insert(int index, T element){    checkIndex(index);    Node<T>* newNode = new Node<T>(element);    if (index == 0){//插入新节点作为链表头节点        newNode->next = this->head;        this->head = newNode;    }    else if (index == size){//插入新节点作为尾部节点        insert(element);    }    else{//插入位置新节点到index索引之上        //获取index索引上的节点        Node<T>* nIndex_pre = node(index - 1);//获取index-1位置上的节点        Node<T>* nIndex = node(index);//获取index索引上的节点        nIndex_pre->next = newNode;        newNode->next = nIndex;    }    size++;    return true;}/*打印整个链表*/template<typename T>void SingleLinkedList<T>::print(){    //如果链表为空    if (NULL == this->head){        cout << "This list is empty.";        return;//结果方法运行,下面的代码不再执行    }    //链表不为空    Node<T>* n = this->head;    while (NULL != n){//此处的判断条件中,只能是n,而不能用n->next        cout << n->element << ",";        n = n->next;    }    cout << '\n';//换行}/*获取指定索引上的数据@param index 给定的索引@return 指定索引上的数据*/template<typename T>T SingleLinkedList<T>::get(int index){    return node(index)->element;}/*获取指定数据的索引,不存在时返回0@param element 给定的需要查找索引的数据@return 给定数据在链表中的索引(第一次出现)*/template<typename T>int SingleLinkedList<T>::getIndex(T element){    bool flag = true;    Node<T>* n = this->head;    int index = 0;    while (flag && (NULL != n)){        if (n->element == element){            flag = false;        }        n = n->next;        index++;    }    if (index > size){        return -1;//没找到    }    return index - 1;//减1,是因为"index++;",在找到相等数据后,仍然被执行了一次,就是多走了一次}/*删除指定位置上的数据@param index 给定的索引@return 删除成功,返回true;否则,返回false*/template<typename T>bool SingleLinkedList<T>::remove(int index){    checkIndex(index);    if (index == 0){//删除是头节点        Node<T>* nHead = this->head;        Node<T>* nHead_next = nHead->next;        this->head = nHead_next;    }    else if (index == size){//删除的是链表最后一个节点        Node<T>* nIndex_pre = node(index - 1);        nIndex_pre->next = NULL;    }    else{//删除的是中间节点        Node<T>* nPre = node(index - 1);        Node<T>* nNext = node(index + 1);        nPre->next = nNext;    }    size--;    return true;}/*将指定位置的数据修改为给定的数据element@param index 指定的索引@param element 给定的数据*/template<typename T>void SingleLinkedList<T>::set(int index, T element){    checkIndex(index);    Node<T>* n = node(index);    n->element = element;}/*释放整个链表:将链表所有节点在内存中占据的存储空间释放*/template<typename T>void SingleLinkedList<T>::freeList(){    /*for (Node<T>* n = this->head; n->next != NULL; n = n->next){        delete n;        }*/    //上面那种释放方式行不通的原因在于:释放一个head后,就断链了,再也找不到之后的节点了    Node<T>* n1 = this->head, *n2;    while (NULL != n1){        n2 = n1->next;        delete n1;        n1 = n2;    }}int main(){    SingleLinkedList<int> list;    cout << list.checkIndex(-1) << endl;    list.insert(1);    list.insert(12);    list.insert(22);    list.insert(1, 10);    list.print();    cout << list.length() << endl;    cout << list.get(1) << endl;    cout << list.getIndex(10) << endl;    list.remove(1);    cout << list.length() << endl;    list.print();    list.set(1, 111);    cout << list.length() << endl;    list.print();    list.freeList();    return 0;}
原创粉丝点击