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

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

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

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

///////////////////////单链表///////////////////////////////
/*
SingleLinkedList.h文件:用于定义单链表的节点及方法
*/

using namespace std;

///////表示单链表中节点的结构体///////////////////////////////////////////////////////////////////////////////////
template //用函数模板的原因是:链表节点中存储的数据类型不确定
class Node{
public:
    /*节点存储的数据*/
    T element;

    /*指向下一个节点的指针*/
    Node *next;

public:
    /*空构造器*/
    Node(){}

    /*构造器*/
    Node(T e){
        element = e;
    }
};

////////////////////////////单链表类的定义////////////////////
template
class SingleLinkedList{
private:
    /*链表长度,存储的结点个数*/
    int size;

    /*表头节点,节点中存储的数据的类型为T*/
    Node *head;

    /*获取链表中指定索引上的节点,仅供内部调用*/
    Node* 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 
#include 
#include "SingleLinkedList.h"
using namespace std;


/*
构造器
*/
template<typename T>
SingleLinkedList::SingleLinkedList(){
    this->head = new Node();//调用默认构造器
    this->size = 0;//初始化长度为0
    this->head->next = NULL;
}

template<typename T>
SingleLinkedList::~SingleLinkedList(){

}



/*
获取链表长度,即当前链表中结点的个数
@return 链表的大小
*/
template<typename T>
int SingleLinkedList::length(){
    return this->size;
}

/*
检查索引范围
@param index 索引
@return 索引合法,则返回true;否则,返回false
*/
template<typename T>
bool SingleLinkedList::checkIndex(int index){
    return index >= 0 && index <= size;
}

/*
获取指定索引上的节点
@param index 给定的索引
@return 节点对象
*/
template<typename T>
Node* SingleLinkedList::node(int index){
    checkIndex(index);
    Node* 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::insert(T element){
    Node* newNode = new Node(element);//构造节点对象

    //如果链表是空
    if (this->size == 0){
        this->head = newNode;
    }

    //链表非空
    Node* 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::insert(int index, T element){
    checkIndex(index);

    Node* newNode = new Node(element);

    if (index == 0){//插入新节点作为链表头节点
        newNode->next = this->head;
        this->head = newNode;
    }
    else if (index == size){//插入新节点作为尾部节点
        insert(element);
    }
    else{//插入位置新节点到index索引之上
        //获取index索引上的节点
        Node* nIndex_pre = node(index - 1);//获取index-1位置上的节点
        Node* nIndex = node(index);//获取index索引上的节点
        nIndex_pre->next = newNode;
        newNode->next = nIndex;
    }
    size++;
    return true;
}

/*
打印整个链表
*/
template<typename T>
void SingleLinkedList::print(){
    //如果链表为空
    if (NULL == this->head){
        cout << "This list is empty.";
        return;//结果方法运行,下面的代码不再执行
    }
    //链表不为空
    Node* 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::get(int index){
    return node(index)->element;
}

/*
获取指定数据的索引,不存在时返回0
@param element 给定的需要查找索引的数据
@return 给定数据在链表中的索引(第一次出现)
*/
template<typename T>
int SingleLinkedList::getIndex(T element){
    bool flag = true;
    Node* 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::remove(int index){
    checkIndex(index);

    if (index == 0){//删除是头节点
        Node* nHead = this->head;
        Node* nHead_next = nHead->next;

        this->head = nHead_next;
    }
    else if (index == size){//删除的是链表最后一个节点
        Node* nIndex_pre = node(index - 1);
        nIndex_pre->next = NULL;
    }
    else{//删除的是中间节点
        Node* nPre = node(index - 1);
        Node* nNext = node(index + 1);
        nPre->next = nNext;
    }
    size--;
    return true;
}

/*
将指定位置的数据修改为给定的数据element
@param index 指定的索引
@param element 给定的数据
*/
template<typename T>
void SingleLinkedList::set(int index, T element){
    checkIndex(index);
    Node* n = node(index);
    n->element = element;
}

/*
释放整个链表:将链表所有节点在内存中占据的存储空间释放
*/
template<typename T>
void SingleLinkedList::freeList(){
    /*for (Node* n = this->head; n->next != NULL; n = n->next){
        delete n;
        }*/

    //上面那种释放方式行不通的原因在于:释放一个head后,就断链了,再也找不到之后的节点了
    Node* 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;
}

你可能感兴趣的:(C/C++,数据结构与算法)