1. 程式人生 > 實用技巧 >1094 谷歌的招聘 (20分)

1094 谷歌的招聘 (20分)

單鏈表為連結串列的一種,連結串列和順序表又同屬於線性表,在正式寫單鏈表之前,可以先定義一個線性表抽象類,用來規範所有線性表共同的操作

#include <iostream>
using namespace std;

// 線性表:順序表和連結串列共同的抽象類
template<typename elemType>
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(){}; };

定義單鏈表,連結串列中用到的節點被定義為類內的結構體。

// 單鏈表
template<typename elemType>
class sLinkList:public list<elemType>{
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; };

函式的類外定義,注意在建構函式中應該新建一個哨兵節點,這樣就保證所有儲存資訊的節點都有前一個節點,可以簡化程式碼和加快執行速度

template<typename elemType>
typename sLinkList<elemType>::node* sLinkList<elemType>::move(int i) const{
    node* p = head;

    while (i-- >= 0) p = p->next;
    return p;
}


template<typename elemType>
sLinkList<elemType>::sLinkList(){
    head = new node;                                     // 哨兵結點
    currentLength = 0;
}


template<typename elemType>
void sLinkList<elemType>::clear(){
    node* p = head->next;
    node* q;

    head->next = NULL;
    while(p != NULL){
        q = p->next;
        delete p;
        p = q;
    }
    currentLength = 0;
}


template<typename elemType>
void sLinkList<elemType>::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<typename elemType>
void sLinkList<elemType>::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<typename elemType>
int sLinkList<elemType>::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<typename elemType>
elemType sLinkList<elemType>::visit(int i) const{
    if(i >= currentLength || i < 0) throw NoSuchNodeError();

    return move(i)->data;
}


template<typename elemType>
void sLinkList<elemType>::traverse() const{
    node* p = head->next;

    while(p != NULL){
        cout << p->data << " ";
        p = p->next;
    }
    cout << endl;
}