LISH.h
#ifndef _LISH_H_
#define _LISH_H_
template<class T>
class List
{
public:
virtual void clear()=0;
virtual bool empty()const=0;
virtual int size()const=0;
virtual void insert(int i,const T &value)=0;
virtual void remove(int i)=0;
virtual int search(const T&value)const=0;
virtual T visit(int i)const=0;
virtual void traverse()const=0;
virtual void inverse()=0;
virtual ~List(){};
};
class outOfRange;
class badSize;
class outOfRange:public exception {
public:
const char* what()const throw() {
return "ERROR! OUT OF RANGE.\n";
}
};
class badSize:public exception {
public:
const char* what()const throw() {
return "ERROR! BAD SIZE.\n";
}
};
#endif
linkList.h
#ifndef _LINKLIST_H_
#define _LINKLIST_H_
template<class elemType>
class linkList:public List<elemType> {
private:
struct Node {
public:
elemType data;
Node *next;
Node(const elemType value,Node *p = NULL) {
data = value;
next = p;
}
Node(Node *p = NULL) {
next = p;
}
};
Node *head;
Node *tail;
int curLength;
Node *getPosition(int i)const;
void traverseRecursive(Node *p);
void traverseNonRecursive();
public:
linkList();
~linkList();
void clear();
bool empty()const {
return head->next==NULL;
}
int size()const{
return curLength;
}
void insert(int i,const elemType &value);
void remove(int i);
int search(const elemType &value)const;
elemType visit(int i)const;
void traverse()const;
void headCreate();
void tailCreate();
void inverse();
int prior(const elemType &value)const;
linkList *Union(linkList<elemType> *lb);
void outPut();
};
template<class elemType>
linkList<elemType>::linkList() {
head = tail = new Node();
curLength=0;
}
template<class elemType>
linkList<elemType>::~linkList() {
clear();
delete head;
}
template<class elemType>
void linkList<elemType>::clear() {
Node *p,*tmp;
p = head->next;
while(p!=NULL) {
tmp = p;
p = p->next;
delete tmp;
}
head->next = NULL;
tail = head;
curLength = 0;
}
template<class elemType>
typename linkList<elemType>::Node* linkList <elemType>::getPosition(int i)const { //因为是 private 所以不能直接调用
Node *p = head;
int count = 0;
if (i<-1 || i>curLength - 1) //查找的合法位置为 [-1...n-1]
return NULL;
while (count <= i) {
p = p->next;
count++;
}
return p; //返回指向第 i结点的指针 指针类型 typename:Node*
}
template<class elemType>
void linkList<elemType>::insert(int i, const elemType &value) {
Node *p,*q;
if (i<0 || i>curLength) //合法的插入位置为 [0...n]
throw outOfRange();
p = getPosition(i - 1); //p时位序为 i的结点的前驱
q = new Node(value, p->next);
p->next = q;
if (p == tail)tail = q; //插入点在表为,插入结点成为新的尾结点
curLength++;
}
template<class elemType>
void linkList<elemType>::remove(int i) {
Node *pre,*p;
if (i<0 || i>curLength - 1) //合法的删除位置为 [0...n-1]
throw outOfRange();
pre = getPosition(i - 1);
p = pre->next; //p时真正待删除结点
if (p == tail) { //待删除结点为尾结点,则修改尾指针
tail = pre;
pre->next = NULL;
delete p;
}
else { //删除结点 p并修改指针
pre->next = p->next;
delete p;
}
curLength--;
}
template<class elemType>
void linkList<elemType>::traverse()const {
Node *p = head->next;
cout << "traverse:";
while (p != NULL) {
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
template<class elemType>
int linkList<elemType>::search(const elemType &value)const {
Node *p = head->next;
int count = 0; //首元结点的位序为 0
while (p != NULL && p->data != value) {
p = p->next;
count++;
}
if (p == NULL)return -1; //查找失败返回 -1,这里-1并非头结点
else return count;
}
template<class elemType>
elemType linkList<elemType>::visit(int i)const {
Node *p = head->next;
int count = 0; //首元结点位序为 0
if (i<0 || i>curLength - 1) //合法的访问位置为 [0...n-1]
throw outOfRange(); //当结点不存在时,抛出异常
while (count < i) {
p = p->next;
count++;
}
return p->data;
}
template<class elemType>
void linkList<elemType>::headCreate() {
Node *p;
elemType value, flag;
cout <<"input elements,ended with:";
cin >> flag; //输入结束标志
while (cin >> value, value != flag)
{
p = new Node(value, head->next);
head->next = p; //结点 p插入到头结点的后面
if (head == tail)tail = p; //原链表为空,则节点 p是尾结点
curLength++;
}
}
template<class elemType>
void linkList<elemType>::tailCreate() {
Node *p;
elemType value, flag;
cout << "input elements,enden whit:";
cin >> flag; //输入结束标志
while (cin >> value, value != flag)
{
p = new Node(value, NULL);
tail->next = p; //结点 p插入到尾结点的后面
tail = p; //结点 p成为新的表尾
curLength++;
}
}
template<class elemType>
void linkList<elemType>::inverse() {
Node *p,*tmp;
p = head->next; // p为工作指针指向首元结点
head->next = NULL; //构成只有一个头结点的空链表
if (p) tail = p; //原首元结点将变成表为
while (p)
{
tmp = p->next; //保存当前处理结点 p的后继
p->next = head->next;
head->next = p; //结点 p插入到头结点的后面
p = tmp;
}
}
template<class elemType>
int linkList<elemType>::prior(const elemType &value)const {
Node *p = head->next; // p是工作指针指向首元结点
Node *pre = NULL; // pre指向 p的前驱结点
int count = -1; //-1表示首元结点无前驱
while (p && p->data != value) {
pre = p; //前驱指针后移
p = p->next; //指向下个待处理结点
count++;
}
if (p == NULL)return-1; //查找失败返回 -1,这里 -1并非头结点
else return count; //查找成功,count为元素的位序
}
template<class elemType>
linkList<elemType> *linkList<elemType>::Union(linkList<elemType> *lb) {
Node *pa,*pb,*pc; //分别是链表 la,lb,lc的工作指针
linkList<elemType> *lc =
this; // lc利用 la空间,将 lb合并进来
pa = head->next; head->next = NULL; // la表头结点的指针域置为Null,构成空链表
pb = (lb->head)->next; (lb->head)->next = NULL; // lb表头结点的指针域置为 NULL,构成空链表
pc = lc->head; //为节省空间 lc表直接利用 la表头结点
while (pa && pb) { // la和 lb均为非空
if (pa->data <= pb->data) { // pb所指结点尾插法插入 lc表
pc->next = pa; pc = pa; pa = pa->next;
}
else { // pb所指结点尾插法插入 lc表
pc->next = pb; pc = pb; pb = pb->next;
}
}
if (pa) { //若 pa未到尾,将 pc所指向 pa
pc->next = pa;
lc->tail = lb->tail; //修改尾指针
}
else {
pc->next = pb; //若 pb未到尾,将 pc指向 pb
lc->tail = lb->tail; //修改尾指针
}
lc->curLength = curLength + lb->curLength;
delete lb;
return lc;
}
template<class elemType>
void linkList<elemType>::outPut() {
cout << "递归:";
traverseRecursive(head->next); cout << endl;
cout << "非递归:";
traverseNonRecursive(); cout << endl;
}
template<class elemType>
void linkList<elemType>::traverseRecursive(Node *p) {
if (p) {
cout << p->data << " "; //输出结点的值
traverseRecursive(p->next); //尾递归调用
}
}
//顺序表输出单链表结点数据的非递归算法:
template<class elemType>
void linkList<elemType>::traverseNonRecursive() {
Node *tmp = head->next;
while (tmp != NULL) {
cout << tmp->data << " "; //输出结点的值
tmp = tmp->next; //向里一层修改变量值
}
cout << endl;
}
#endif
All.cpp
#include <bits/stdc++.h>
using namespace std;
#include "C:\Users\14805\Desktop\LIST.h"
#include "C:\Users\14805\Desktop\linkList.h"
template<class T>
void testList(linkList<T>* p)
{
if (p->empty())cout << "empty list\n";
cout << " test insert:\n";
int n, i;
T val;
cout << "input number of nodes;:\n";
cin >> n; //输入结点总数
cout << "input each node's insertion position and value:\n";
while (n > 0) //测试插入
{
cin >> i; //输入结点插入位置的下标
cin >> val; //输入结点的值
try
{
p->insert(i, val); //插入
}
catch (outOfRange)
{
cerr << "error,catch outOfRange\n";
}
n--;
}
p->traverse(); //测试遍历
cerr << "curLength:" << p->size() << endl; //输出表长
cout << "test inverse:\n";
p->inverse(); //测试逆置
p->traverse(); //测试遍历
cout << "test search:\n"; //测试查找
cout << "input the value:\n";
cin >> val; //输入要查找的元素值
cout << "the position of" << val << "is:" << p->search(val) << endl; //查找
cout << "test the delete:\n"; //测试删除
cout << "input the position:\n";
cin >> i; //输入删除位置
try
{
p->remove(i); //删除
}
catch (outOfRange)
{
cerr << "error, catch outOfRange.\n";
}
p->traverse(); //测试遍历
cout << "test visit:\n"; //测试访问
cout << "input the position[0...n-1]:\n";
cin >> i; //输入要访问的元素
try
{
cout << "position:" << i << ":" << p->visit(i) << endl; //访问
}
catch (outOfRange)
{
cerr << "error, catch outOfRange.\n";
}
}
template<class T>
void testLinkCreate(linkList<T>* lk)
{
cout << "test headCreate:\n";
lk->headCreate(); //测试头插法
lk->traverse();
lk->outPut();
cout << "test tailCreate:\n";
lk->tailCreate(); //测试尾插法
lk->traverse();
}
int main()
{
linkList<int>* lk; //创建一个单链表
lk = new linkList<int>();
testList(lk); //测试单链表
system("pause");
return 0;
}