泛型编程-抽象链表模板类
出现的问题:在增加、删除结点时,仅仅delete了指针,但是delete p;
并不意味着p=NULL;
例如以下代码:
int *pp=new int(5);
delete pp;
cout << pp <<","<<*pp<< endl;
运行结果为:`00D9EA38,-572662307
所以delete之后只是告诉编译器,这块堆空间上的内存可以回收,但是并没有让它等于NULL,以后再new的时候可能还会申请到这块地址。所以delete之后最好要加上p=NULL;
抽象链表模板类
#include <iostream>
#include <cstdlib>
using namespace std;
class EListEmpty{}; //链表为空异常
template<typename T> class ListNode; //表结点模板
template<typename T> class List; //链表模板
template<typename T> class ListNode
{
public:
friend class List<T>; //需要让List成为友元,否则List中的head无法访问data,next
ListNode(const T &x) :data(x), next(NULL){}
private:
T data;
ListNode<T> *next;
};
template<typename T> class List
{
public:
List() :head(NULL), tail(NULL){}
virtual ~List ();
void push_back(const T &x); //尾插入
void push_front(const T &x);//头插入
void pop_back(); //尾删除
void pop_front(); //头删除
int size(); //长度
void show(); //输出
void reverse(); //反向(通过建新链表,将旧链表依次加入头部)
bool IsEmpty()const { return head == 0; }
private:
ListNode<T> *head; //头指针
ListNode<T> *tail; //尾指针
};
template<typename T> List<T>::~List()
{
while (!IsEmpty())
{
pop_back();
}
}
template<typename T> void List<T>::push_back(const T &x)
{
ListNode<T> *p = new ListNode<T>(x);
if (IsEmpty()) head = tail = p;
else{
tail->next = p;
tail = p;
}
}
template<typename T> void List<T>::push_front(const T &x)
{
ListNode<T> *p = new ListNode<T>(x);
if (IsEmpty()) head = tail = p;
else{
p->next = head;
head = p;
}
}
template<typename T> void List<T>::pop_back()
{
if (IsEmpty()) throw EListEmpty();
ListNode<T> *p=head;
if (head == tail) {
delete head;
head = NULL;
return;
}
while (p->next!=tail)
{
p = p->next;
}
tail = p;
delete p->next;
p->next = NULL;
}
template<typename T> void List<T>::pop_front()
{
if (IsEmpty())
throw EListEmpty();
if (head == tail)
{
delete head;
head = NULL;
return;
}
ListNode<T> *p = head;
head = head->next;
delete p;
}
template<typename T> int List<T>::size()
{
int count=0;
if (IsEmpty()) return 0;
if (head == tail) return 1;
ListNode<T> *p = head;
while (p->next != tail)
{
p = p->next;
++count;
}
return count+1;
}
template<typename T> void List<T>::show()
{
ListNode<T> *p = head;
if (IsEmpty())
{
cout << "Empty List!" << endl; return;
}
else{}
if (head == tail) cout << head->data << endl;
else{
while (p!=tail)
{
cout << p->data << ",";
p = p->next;
}
cout << p->data << endl;
}
}
template<typename T> void List<T>::reverse()
{
if (head == 0 || head == tail) return;
List<T> *a=new List<T>;
ListNode<T> *p = head;
ListNode<T> *temp;
while (p != tail)
{
//a->push_front(p->data);
temp = new ListNode<T>(p->data);
if (a->head == NULL)
{
a->head = a->tail = temp;
}
else{
temp->next = a->head;
a->head = temp;
}
p = p->next;
}
a->push_front(tail->data);
head = a->head;
tail = a->tail;
}
int main()
{
List<int> *p = new List<int>;
cout<<p->size()<<endl;
p->reverse();
p->show();
for (int i = 0; i < 10; i++)
p->push_back(i);
p->show();
try{
for (int i = 0; i < 7; i++)
{
p->pop_front();
//cout << i << endl;
}
}
catch ( EListEmpty &a)
{
cout << "链表已空!" << endl;
}
p->push_front(10);
p->push_front(12);
p->show();
p->reverse();
p->show();
return 0;
}