单链表

#include <iostream> 
using namespace std;

template <typename T>
struct Node
{
    T data;
    Node *next;
    Node() { data = 0; next = NULL; }
    Node(T x, Node *n = NULL) : data(x), next(n) {}
};

template <typename T>
class List
{
private:
    Node<T> *Head;
    int last;

public:
    List() { Head = new Node<T>, last = 0; } //ok

    List(const T &x) //ok
    {
        last = 0;
        Head = new Node<T>;
        Head->next = new Node<T>(x);
        last++;
    }

    List(List<T> &L) //ok
    {
        makeEmpty(Head);
        last = 0;
        this->Head = new Node<T>();
        for (Node<T> *p = L.Head->next; p; p = p->next)
            Insert(0, p->data);
    }

    ~List() { makeEmpty(Head); } //ok

    void makeEmpty(Node<T> * p) //ok
    {
        if (p) makeEmpty(p->next);
        delete p;
    }

    int Length() const { return last; } //ok

    Node<T>* getHead() const { return Head; } //ok

    Node<T>* Search(T x) //ok
    {
        for (Node<T> *p = Head->next; p; p = p->next)
            if (p->data == x) return p;
        return NULL;
    }

    Node<T>* Locate(int i) const //ok
    {
        int r = 0;
        for (Node<T> *p = Head; p; p = p->next, r++)
            if (r == i) return p;
        return NULL;
    }

    bool getData(int i, T &x) //ok
    {
        Node<T> *p = this->Locate(i);
        if (p)
        {
            x = p->data;
            return true;
        }
        return false;
    }

    bool setData(int i, T &x) //ok
    {
        if (Node<T> *p = Locate(i))
        {
            p->data = x;
            return true;
        }
        return false;
    }

    void Insert(int i, T &x) //ok
    {
        last++;
        int r = 1;
        for (Node<T> *p = Head; ; p = p->next, r++)
            if (r == i || p->next == NULL) { p->next = new Node<T>(x, p->next); break; }
    }

    bool Remove(int i, T &x) //ok
    {
        if (i > 0 && i <= last)
        {
            Node<T> *p = Locate(i - 1);
            Node<T> *d = p->next;
            p->next = d->next;
            last--;
            x = d->data;
            delete d;
            return true;
        }
        else return false;
    }

    bool IsEmpty() const { return Head->next == NULL ? true : false; } //ok

    bool IsFull() const { return false; } //ok

    void sortInsert(Node<T> *p, T &x) //ok
    {     
        for (; p->next; p = p->next)
        {
            if (p->next->data > x)
            {
                p->next = new Node<T>(x, p->next);
                return;
            }
        }
        
        p->next = new Node<T>(x);
        
    }

    void Sort() //ok
    {
        Node<T> *temp = new Node<T> ();
        for (Node<T> *p = Head->next; p; p = p->next)
            sortInsert(temp, p->data);
        makeEmpty(Head);
        Head = temp;
    }

    void input() //ok
    {
        int n;
        cin >> n;
        for (int i = 0; i < n; i++)
        {
            int x;
            cin >> x;
            this->Insert(i + 1, x);
        }
    }

    void output() //ok
    {
        cout << "{";
        for (Node<T> *p = Head->next; p; p = p->next)
            cout << p->data << " ";
        cout << "}" << endl;
    }

    List<T>& operator = (List<T> &L) //ok
    {
        makeEmpty(Head);
        Head = new Node<T>();
        for (Node<T> *p = L.Head->next, *P = Head; p; p = p->next, P = P->next)
            P->next = new Node<T>(p->data);
        return *this;
    }
};

Mind: 

  a.析构函数调用makeEmpty()受某些刺激用了递归...但会把头结点也delete掉,所以用来清空链表的话需要重新new一下头结点

    也可以改写成在makeEmpty()中重新new一下, 析构函数在调用它后再delete一下(好烦..)

  b.头结点为空结点,为方便删除插入操作

  c.现在才发现之前写的桶排序中的插入有多烂, 有一句完全不需要写。

  d.isFull(),好令人蛋疼的功能.. 返回定值false, 有啥用嘞?

  e.自己的代码容错性还是太差, 以后努力改进

原文地址:https://www.cnblogs.com/QQ-1615160629/p/5918523.html