用C++語言實現線性表

1.用數組實現

#include<iostream>
#include "utility.h"

using namespace std;

const int max_list = 5000;

template <class List_entry> //模板
class List {
public:
   List();  //構造函數
   int size() const; //返回線性表的大小
   bool full() const; //判滿
   bool empty() const; //判空
   void clear();  //清空
   void traverse(void (*visit)(List_entry &)); //遍歷
   Error_code retrieve(int position, List_entry &x) const; //讀取指定位置的數據
   Error_code replace(int position, const List_entry &x);  //換掉指定位置的數據
   Error_code remove(int position, List_entry &x); //刪除指定位置的數據
   Error_code insert(int position, const List_entry &x); //在指定位置插入數據

protected:
   int count;  //記數
   List_entry entry[max_list]; //數組,存放數據
};

template <class List_entry>
List<List_entry>::List() //構造函數
{
    count = 0;
}

template <class List_entry>
void List<List_entry>::clear() //清空
{
    count = 0;
}

template <class List_entry>
int List<List_entry>::size() const //返回線性表的大小
{
   return count;
}

template <class List_entry>
bool List<List_entry>::empty() const //判空
{
   return count <= 0;
}

template <class List_entry>
bool List<List_entry>::full() const //判滿
{
   return count >= max_list;
}

template <class List_entry>
Error_code List<List_entry>::insert(int position, const List_entry &x) //在指定位置插入數據
{
   if (full())
      return overflow; //判斷能否再插入數據

   if (position < 0 || position > count) //判斷指定位置是否合法
      return range_error;

   for (int i = count - 1; i >= position; i--)
      entry[i + 1] = entry[i];//從指定位置開始往後,每一個數據向後移一位

   entry[position] = x; //給指定位置賦值
   count++; //計數器加一
   return success;
}

template <class List_entry>
Error_code List<List_entry>::retrieve(int position,List_entry &x) const  //讀取指定位置的數據
{
    if((position < 0) || (position >= count)) return range_error; //判斷指定位置是否合法
    x = entry[position]; //將指定位置元素賦給x
    return success;
}

template <class List_entry>
Error_code List<List_entry>::replace(int position,const List_entry &x)  //換掉指定位置的數據
{
    if((position < 0) || (position >= count)) return range_error;  //判斷指定位置是否合法
    entry[position] = x;//將指定位置元素換成x
    return success;
}

template <class List_entry>
Error_code List<List_entry>::remove(int position,List_entry &x) //刪除指定位置的數據
{
    if(count == 0) return underflow;  //判斷是否有數據
    if((position < 0) || (position >= count)) return range_error; //判斷指定位置是否合法
    x = entry[position]; //將這個位置的值取出賦給x
    for(int i = position+1;i <= count - 1;i++)
    {
        entry[i - 1] = entry[i];  //從position+1往後每個數據都向前挪一個位置
    }
    count--; //計數器減一
    return success;
}

template <class List_entry>
void List<List_entry>::traverse(void (*visit)(List_entry &))  //遍歷。參數*visit指向任意一個無參函數,意思是將線性表中的每一項傳給函數供函數使用
{
   for (int i = 0; i < count; i++)
      (*visit)(entry[i]);
}

2.用鏈表實現

#include<iostream>
#include "utility.h"

using namespace std;

template <class Node_entry>
struct Node {
   Node_entry entry;
   Node<Node_entry> *next;
   Node(); //構造函數
   Node(Node_entry data, Node<Node_entry> *link = NULL);
};

template <class Node_entry>
Node<Node_entry>::Node()
{
    next = NULL;
}

template <class Node_entry>
Node<Node_entry>::Node(Node_entry data,Node<Node_entry> *link)
{
    entry = data;
    next = link;
}

template <class List_entry>
class List {
public:
    List();  //構造函數
    int size() const; //返回線性表的大小
    bool full() const; //判滿
    bool empty() const; //判空
    void clear();  //清空
    void traverse(void (*visit)(List_entry &)); //遍歷
    Error_code retrieve(int position, List_entry &x) const; //讀取指定位置的數據
    Error_code replace(int position, const List_entry &x);  //換掉指定位置的數據
    Error_code remove(int position, List_entry &x); //刪除指定位置的數據
    Error_code insert(int position, const List_entry &x); //在指定位置插入數據
    ~List(); //析構函數
    List(const List<List_entry> &copy);  //拷貝構造函數
    void operator =(const List<List_entry> &copy); //“=”運算符重載
protected:
    int count; //計數器
    Node<List_entry> *head; //頭指針
    Node<List_entry> *set_position(int position) const; //讓指針指向指定位置
};

template <class List_entry>
List<List_entry> ::List()  //構造函數
{
    count = 0; //計數器置0
    head = NULL;
}

template <class List_entry>
void List<List_entry>::clear() //清空
{
    Node<List_entry> *p,*q;
    for(p = head;p;p = q)
    {
        q = p->next;
        delete p;
    }  //遍歷,有數據的釋放空間
    count = 0;
    head = NULL; //置空
}

template <class List_entry>
int List<List_entry>::size() const  //返回線性表大小
{
    return count;
}

template <class List_entry>
bool List<List_entry>::empty() const //判空
{
    return count <= 0;
}

template <class List_entry>
bool List<List_entry>::full() const //判滿
{
    return false;
}

template <class List_entry>
void List<List_entry>::traverse(void (*visit)(List_entry &))  //遍歷。參數*visit指向任意一個無參函數,意思是將線性表中的每一項傳給函數供函數使用
{
    Node<List_entry> *q;
    for(q = head;q;q = q->next) (*visit)(q->entry); //將每個值都以引用形式傳回
}

template <class List_entry>
Error_code List<List_entry>::insert(int position, const List_entry &x)   //在指定位置插入數據
{
    if (position < 0 || position > count) return range_error; //判斷指定位置是否合法
    Node<List_entry> *new_node, *previous, *following;
    if (position > 0)  //如果指定位置不是表頭
    {
      previous = set_position(position - 1); //前一位就是指定位置的前一位
      following = previous->next; //後一位就是指定位置
    }
    else following = head; //如果指定位置是表頭,那麼它的後一位就是當前表頭
    new_node = new Node<List_entry>(x, following); //創建新的數據域,並且將新的數據域與它的後一位連起來
    if (new_node == NULL) return overflow; //判斷創建是否成功
    if (position == 0) head = new_node; //如果指定位置是表頭,那麼新的表頭就是插入的數據
    else
        previous->next = new_node; //否則,將前一個與新創建的關聯起來
    count++; //計數器加一
    return success;
}

template <class List_entry>
Error_code List<List_entry>::retrieve(int position, List_entry &x) const //讀取指定位置的數據
{
    Node<List_entry> *current;
    if (position < 0 || position > count) return range_error; //判斷指定位置是否合法
    current = set_position(position); //將current指向指定位置
    x = current->entry; //取出數據賦給x
    return success;
}

template <class List_entry>
Error_code List<List_entry>::replace(int position, const List_entry &x) //替換指定位置的數據
{
    Node<List_entry> *current;
    if (position < 0 || position > count) return range_error; //判斷指定位置是否合法
    current = set_position(position); //將current指向指定位置
    current->entry = x; //將要換入的值填入這個位置
    return success;
}

template <class List_entry>
Error_code List<List_entry>::remove(int position, List_entry &x) //刪除指定位置的數據
{
    Node<List_entry> *prior,*current;
    if(count == 0) return underflow;
    if (position < 0 || position > count) return range_error; //判斷指定位置是否合法
    if(position > 0) //如果指定位置不是表頭
    {
        prior = set_position(position - 1); //前一位就是指定位置的前一位
        current = prior->next; //確定當前位置
        prior->next = current->next; //將下一個元素和前一個相連
    }
    else{
        current = head; //如果指定位置是表頭,當前位置是表頭
        head = head->next; //表頭變成下一個元素
    }
    delete current; //刪除這個空間
    count--; //計數器減一
    return success;
}

template <class List_entry>
Node<List_entry> *List<List_entry>::set_position(int position) const  //讓指針指到指定位置
{
   Node<List_entry> *q = head;
   for (int i = 0; i < position; i++) q = q->next; //遍歷,指到找到指定位置
   return q;
}

template <class List_entry>
List<List_entry> ::~List()  //析構函數
{
    clear();
}

template <class List_entry>
List<List_entry> ::List(const List<List_entry> &copy) //拷貝構造函數
{
    count = copy.count; //表中元素個數相同
    Node<List_entry> *new_node,*old_node = copy.head;
    if(old_node == NULL) head = NULL; //如果原表爲空則新表也爲空
    else{
        new_node = head = new Node<List_entry>(old_node->entry); //定義新表的頭
        while(old_node->next != NULL) //遍歷舊錶
        {
            old_node = old_node->next;
            new_node->next = new Node<List_entry>(old_node->entry);
            new_node = new_node->next;  //將舊錶的每一項賦給新的表
        }
    }
}

template <class List_entry>
void List<List_entry> ::operator =(const List<List_entry> &copy) //“=”運算符重載
{
    List new_copy(copy); //調用拷貝構造函數
    clear(); //將這個表清空
    count = new_copy.count;
    head = new_copy.head; //將拷貝的值傳給新的表
    new_copy.count = 0;
    new_copy.head = NULL; //清空拷貝的表
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章