我的第一个单链表实现

#include <iostream>
using namespace std;
template<class T>
struct Node {
    T data;
    Node <T>* next;
};
template<class T>class LinkedList {
private:
    Node <T>* front;//头指针,指向头结点
public:
    LinkedList();//无参的构造函数,设置头结点,也留给空链表,;
    void FrontConstruct(T a[], int n);//用长度为n的T类型数组头插法初始化
    void RearConstruct(T a[], int n);//用长度为n的T类型数组尾插法初始化
    Node <T>* GetAddress(int i);//获得位置为i的节点地址(这个在其他函数里会被用到较多次数)
    void Insert(T x, int i);//在位置为i的地方插入类型为T的x
    int Locate(T x);//查找表中值为x的元素并返回其位置
    T Delete(int i);//删除位置为i的节点并返回其数据
    int GetLength();//获取链表长度
    void PrintList();//遍历,打印
    ~LinkedList();//析构函数

};
template<class T>
LinkedList<T>::LinkedList() {
    //设置头结点
    front = new Node <T>;
    front->next = NULL;
}
template<class T>
void LinkedList <T>::FrontConstruct(T a[], int n) {
    if (n <= 0) throw "无法使用长度为0的数组头插法初始化";//查了,长度小于等于0好像压根就不存在?。。。
    else {//普通情况,头插法
        for (int i = 0; i < n; i++)
        {
            Node <T>* p = new Node <T>;
            p->data = a[i];
            p->next = front->next;
            front->next = p;
        }
    }
}
template<class T>
void LinkedList <T>::RearConstruct(T a[], int n) {
    if (n <= 0) throw "无法使用长度为0的数组尾插法初始化";//查了,长度小于等于0好像压根就不存在?。。。
    else {//普通情况,尾插法
    //尾插法注意要设置尾指针
        Node <T>* rear = front;
        for (int i = 0; i < n; i++)
        {
            Node <T>* p = new Node <T>;
            p->data = a[i];
            rear->next = p;
            rear = p;
        }
    }
}
template <class T>
int LinkedList <T>::GetLength() {
    int length = 0;
    Node <T>* p = front;
    while (p->next)
    {
        p = p->next;
        length++;
        //注意,对于空链表而言,p->next=NULL,循环不会执行,长度length始终为0
        //而对于正常链表,length从0开始,恰好对应最后一个node的next为NULL
    }
    return length;
}





template <class T>
Node <T>* LinkedList <T>::GetAddress(int i) {
    //获取位置为i的结点地址
    if (i<1 || i>GetLength())
    {
        throw "您所选取的位置非法";
    }
    else {    
        int counter = 1;//空链表的情况包含在上面的if里了(length<1),所以计数器直接从1开始
        Node <T>* p = front->next;//front对counter无贡献,直接跳过
        while (p && counter!=i)
        {
            p = p->next;
            counter++;
        }
        return p;
    }
}

template <class T>
void LinkedList <T>::Insert(T x, int i) {
    //插入,先想特殊情况,假如他往0位置插入那不行
    if (i<1)
    {
        throw "插入位置非法";
    }
    else {
        //接下来是找前一个node的位置,就分情况了,头结点和普通节点
        Node <T>* p = NULL;
        if (i - 1 == 0) p = front;
        else p = GetAddress(i - 1);

        Node <T>* s = new Node <T>;
        s->data = x;
        s->next = p->next;
        p->next = s;
    }
}
template <class T>
int LinkedList <T>::Locate(T x) {
    //查找值为x的节点并返回节点位置
    int counter = 1;
    //空链表,其实和遍历之后找不到该值,这俩是同样的意思,相当于过早就到了表末。
    Node <T>* p = front->next;//你front又没有存数据
    while (p && p->data != x)//让p作为循环的一部分条件,就可以将空链表与找不到归为一类
    {
        p = p->next;
        counter++;
    }
    //情况1:没找到
    if (counter > GetLength())
    {
        cout << "未找到" << endl;
        return -1;//错误没找到
    }

    else {
        return counter;
    }
}
template <class T>
T LinkedList <T>::Delete(int i) {
    if (i<1 || i>GetLength())
        throw "删除位置非法";
    else {
        //空链表没啥可删的
        T a;
        Node <T>* p = front;
        if (i - 1 == 0) {
            Node <T>* s = front->next;
            a = s->data;
            front->next = s->next;
            delete s;
            return a;
        }
        else {
            p = GetAddress(i-1);
            Node <T>* s = p->next;
            a = s->data;
            p->next = s->next;
            //别忘了释放空间
            delete s;

            return a;
        }
    }
}
template <class T>
void LinkedList <T>::PrintList() {
    if (GetLength() == 0)
        cout << "此链表为空链表";
    else {
        Node <T>* p = front->next;
        int counter = 1;
        while (p)
        {
            cout << "这是第" << counter++ << "个节点,其数据为" << p->data << endl;
            p = p->next;
        }
    }
}


template <class T>
LinkedList <T>::~LinkedList() {
    Node <T>* p = front;
    while (p)
    {
        front = p;
        p = p->next;
        delete front;
    }
}
int main() {
    LinkedList <int> tlist;
    int arr[5] = { 2,8,2,9,31 };
    tlist.FrontConstruct(arr, 5);
    tlist.PrintList();
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值