单链表
单链表为链表的一种,链表和顺序表又同属于线性表,在正式写单链表之前,可以先定义一个线性表抽象类,用来规范所有线性表共同的操作
#includeusing namespace std; // 线性表:顺序表和链表共同的抽象类 template class list{ public: virtual void clear() = 0; // 删除线性表中的所有数据元素 virtual int length() const = 0; // 求线性表的长度 virtual void insert(int i, const elemType & x) = 0; // 在第i个位置插入一个元素 virtual void remove(int i) = 0; // 删除第i个位置的元素 virtual int search(const elemType & x) const = 0; // 搜索某个元素x在线性表中是否出现 virtual elemType visit(int i) const = 0; // 返回线性表中第i个数据元素的值 virtual void traverse() const = 0; // 按序访问线性表的每一数据元素 virtual ~list(){}; };
定义单链表,链表中用到的节点被定义为类内的结构体。
// 单链表 templateclass sLinkList:public list {
private: struct node{ // 单链表中的节点类 elemType data; node* next; node(const elemType & x, node* n = NULL) {data = x; next = n;} node():next(NULL){} ~node(){} }; node* head; // 头指针 int currentLength; // 表长 node* move(int i) const; // 返回指向第i个结点的指针 class NoSuchNodeError{}; // 按索引的结点不存在导致的错误 public: sLinkList(); ~sLinkList(){clear(); delete head;} void clear(); int length() const{return currentLength;} void insert(int i, const elemType & x); void remove(int i); int search(const elemType & x) const; elemType visit(int i) const; void traverse() const; };
函数的类外定义,注意在构造函数中应该新建一个哨兵节点,这样就保证所有储存信息的节点都有前一个节点,可以简化代码和加快运行速度
templatetypename sLinkList ::node* sLinkList ::move(int i) const{ node* p = head; while (i-- >= 0) p = p->next; return p; } template sLinkList ::sLinkList(){ head = new node; // 哨兵结点 currentLength = 0; } template void sLinkList ::clear(){ node* p = head->next; node* q; head->next = NULL; while(p != NULL){ q = p->next; delete p; p = q; } currentLength = 0; } template void sLinkList ::insert(int i, const elemType & x){ if(i > currentLength || i < 0) throw NoSuchNodeError(); node* pos = move(i - 1); pos->next = new node(x, pos->next); ++ currentLength; } template void sLinkList ::remove(int i){ if(i >= currentLength || i < 0) throw NoSuchNodeError(); node* pos = move(i - 1); node* delp = pos->next; pos->next = delp->next; delete delp; --currentLength; } template int sLinkList ::search(const elemType & x) const{ node* p = head->next; int i = 0; while(p!= NULL && p->data != x){p = p->next; ++i;} if(p == NULL) return -1; else return i; } template elemType sLinkList ::visit(int i) const{ if(i >= currentLength || i < 0) throw NoSuchNodeError(); return move(i)->data; } template void sLinkList ::traverse() const{ node* p = head->next; while(p != NULL){ cout << p->data << " "; p = p->next; } cout << endl; }