链表实现的线性表

来源:互联网 发布:美国零售销售数据公布 编辑:程序博客网 时间:2024/06/10 15:40

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

//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
原创粉丝点击