链表实现的线性表

这是一个很简单的链表实现的线性表,提供了自表首插入元素、从表尾插入元素、删除指定元素、搜索表中是否有指定元素、 输出链表的操作,还有通过链表遍历器来实现链表反序输出和有序链表合并的方法。

//MyException.h

class OutofBounds
{
public:
    OutofBounds(){ }
};

//LinkedList.cpp

#include "MyException.h"
#include <iostream>
using std::ostream;
using std::operator<<;

template <class T>
class Node;

template<class T>
class Iterator;

template<class T>
class LinkedList //链表类
{
    friend Iterator<T>;
    friend ostream& operator<< <T>(ostream& out, const LinkedList<T>& l);
public:
    LinkedList() { first = 0; }
    ~LinkedList();
    LinkedList<T>& AddToFirst(const T& x); //自表首插入元素
    LinkedList<T>& Delete(int k, T& x); //删除第k个元素
    LinkedList<T>& Append(const T& x); //添加元素到链表最后
    int Search(const T& x) const; //查找链表中是否含有元素x,并返回位置,不存在返回0
    void Output(ostream& out) const;
private:
    Node<T> *first; //指向链表的第一个元素
};

template<class T>
LinkedList<T>::~LinkedList()
{
    Node<T> *p; //指向下一个节点的指针
    while (first) {
        p = first->next;
        delete first;
        first = p;
    }
}

template<class T>
LinkedList<T>& LinkedList<T>::AddToFirst(const T & x)
{//新建节点并添加到链表头部
    Node<T> *p = new Node<T>;
    p->data = x;
    p->next = first;
    first = p;
    return *this;
}

template<class T>
LinkedList<T>& LinkedList<T>::Append(const T & x)
{//添加元素到链表最后
    Node<T> *p = first;
    Node<T> *q = new Node<T>;
    q->data = x;
    if (!p) {//表为空时
        q->next = first;
        first = q;
    } else {
        while (p->next)
            p = p->next;
        p->next = q;
        q->next = 0;
    }
    return *this;
}

template<class T>
LinkedList<T>& LinkedList<T>::Delete(int k, T & x)
{
    if (k < 1 || !first) throw OutofBounds(); //序号小于1或表为空时,抛出OutofBounds
    Node<T> *p = first;
    if (k == 1) //如果要删除第一个元素,移动first指针
        first = first->next;
    else {
        Node<T> *q = first;
        for (int i = 1; i < k - 1 && q; i++) //找到k-1个元素
            q = q->next;
        if (!q || !q->next) throw OutofBounds(); //k-1个元素不存在或第k个元素不存在
        p = q->next; //把第k元素赋给p
        q->next = p->next; //改变第k-1个元素的下一个为第k+1个元素
    }
    x = p->data;
    delete p;
    return *this;
}

template<class T>
int LinkedList<T>::Search(const T & x) const//返回元素x第一次出现的位置,不存在则返回0
{
    int k = 1; //记录x的位置
    Node<T> *p = first; //创建一个从头开始的指针
    while (p && x != p->data) {
        k++;
        p = p->next;
    }
    if (p) return k; //如果找到了,返回元素的位置
    return 0;
}

template<class T>
void LinkedList<T>::Output(ostream & out) const
{
    Node<T> *p;
    for (p = first; p; p = p->next)
        out << p->data << ' ';
}

template<class T>
class Node //节点类
{
    friend LinkedList<T>;
    friend Iterator<T>;
private:
    T data;//存放的数据
    Node<T> *next;//指向下一个节点的指针
};

template<class T>
ostream& operator<<(ostream& out, const LinkedList<T>& l)
{
    l.Output(out);
    return out;
}

template<class T>
class Iterator //链表迭代器类
{
public:
    T* Initialize(const LinkedList<T>& list);
    T* Next();
private:
    Node<T> *location;
};

template<class T>
T * Iterator<T>::Initialize(const LinkedList<T>& list) 
{
    location = list.first; 
    if (location) return &location->data; //如果链表存在,就返回其第一个元素的地址
    return 0;
}

template<class T>
T * Iterator<T>::Next()
{
    if (!location) return 0; //如果链表到头,返回0
    location = location->next;
    if (location) return &location->data; //如果元素存在,返回它的地址
    return 0;
}

//main.cpp

#include "LinkedList.cpp"
#include <iostream>
using std::cout;
using std::cin;
using std::endl;

template<class T>
void ReverseOutputList(const LinkedList<T>& list)
{//通过链表遍历器按序获得list中的元素,并不断加到临时链表的头节点中
    Iterator<T> it;
    T* x = it.Initialize(list);
    LinkedList<T> tmpList;
    while (x) {
        tmpList.AddToFirst(*x);
        x = it.Next();
    }
    cout << "倒序输出" << endl;
    tmpList.Output(cout);
}

template<class T>
void Merge(const LinkedList<T>& A, const LinkedList<T>& B, LinkedList<T>& C)
{
    Iterator<T> ita, itb;
    T* x1 = ita.Initialize(A);
    T* x2 = itb.Initialize(B);
    while (x1&&x2) { //当两个表中都还有元素时,把比较小的先加入C表
        if (*x1 < *x2) {
            C.Append(*x1);
            x1 = ita.Next();
        } else {
            C.Append(*x2);
            x2 = itb.Next();
        }
    }

    //无论哪个表还有元素,都添加到最后
    while (x1) {
        C.Append(*x1);
        x1 = ita.Next();
    }
    while (x2) {
        C.Append(*x2);
        x2 = itb.Next();
    }
}

int main()
{
    LinkedList<int> list;
    int length = 0;
    cout << "输入要输入的元素数量:" << endl;
    cin >> length;
    int num = 0;
    cout << "输入元素:" << endl;
    for (int i = 0; i < length; i++) {
        cin >> num;
        list.AddToFirst(num);
    }
    cout << "新的链表为" << endl;
    list.Output(cout);
    cout << endl;
    cout << "输入要搜索的元素:" << endl;
    cin >> num;
    int index = list.Search(num);
    if (index)
        cout << num << "在链表中的位置为" << index << "。\n";
    else
        cout << num << "在链表中不存在。\n";
    cout << endl;


    cout << "输入要删除的元素的位置:" << endl;
    cin >> index;
    try { list.Delete(index, num); }
    catch (OutofBounds) { cout << "元素位置输入错误!" << endl; }
    cout << "新的链表为" << endl;
    list.Output(cout);
    cout << endl;

    ReverseOutputList(list);
    cout << endl;

    //合并两个有序表
    int a1[] = { 92,74,22,13,4 };
    int a2[] = { 88,33,2 };
    LinkedList<int> listA;
    LinkedList<int> listB;
    for (int i = 0; i < (sizeof a1) / (sizeof a1[0]); i++)
        listA.AddToFirst(a1[i]);
    for (int i = 0; i < (sizeof a2) / (sizeof a2[0]); i++)
        listB.AddToFirst(a2[i]);
    LinkedList<int> listC;
    Merge(listA, listB, listC);
    cout << "第一个链表为:" << listA << endl;
    cout << "第二个链表为:" << listB << endl;
    cout << "合并后的链表为:" << listC << endl;
    cout << endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值