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