chap_16 链表

#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include <stdexcept>
using namespace std;

template<typename T>
class Node
{
public:
  T element;  // Element contained in the node
  Node<T> *next; // Pointer to the next node

  Node() // No-arg constructor
  {
    next = NULL;
  }

  Node(T element) // Constructor
  {
    this->element = element;
    next = NULL;
  }
};

template<typename T>
class LinkedList
{
public:
  LinkedList();
  void addFirst(T element);
  void addLast(T element);
  T getFirst();
  T getLast();
  T removeFirst() throw (runtime_error);
  T removeLast();
  void add(T element);
  void add(int index, T element);
  void clear();
  bool contains(T element);
  T get(int index);
  int indexOf(T element);
  bool isEmpty();
  int lastIndexOf(T element);
  bool remove(T element);
  int getSize();
  T removeAt(int index);
  T set(int index, T element);

private:
  Node<T> *head, *tail;
  int size;
};

template<typename T>
LinkedList<T>::LinkedList()
{
  head = tail = NULL;
  size = 0;
}

template<typename T>
void LinkedList<T>::addFirst(T element)
{
  Node<T> *newNode = new Node<T>(element);
  newNode->next = head;
  head = newNode;
  size++;

  if (tail == NULL)
    tail = head;
}

template<typename T>
void LinkedList<T>::addLast(T element)
{
  if (tail == NULL)
  {
    head = tail = new Node<T>(element);
  }
  else
  {
    tail->next = new Node<T>(element);
    tail = tail->next;
  }

  size++;
}

template<typename T>
T LinkedList<T>::getFirst()
{
  if (size == 0)
    throw runtime_error("Index out of range");
  else
    return head->element;
}

template<typename T>
T LinkedList<T>::getLast()
{
  if (size == 0)
    throw runtime_error("Index out of range");
  else
    return tail->element;
}

template<typename T>
T LinkedList<T>::removeFirst() throw (runtime_error)
{
  if (size == 0)
   throw runtime_error("No elements in the list");
  else
  {
    Node<T> *temp = head;
    head = head->next;
    size--;
    if (head == NULL) tail = NULL;
    T element = temp->element;
    delete temp;
    return element;
  }
}

template<typename T>
T LinkedList<T>::removeLast()
{
  if (size == 0)
    throw runtime_error("No elements in the list");
  else if (size == 1)
  {
    Node<T> *temp = head;
    head = tail = NULL;
    size = 0;
    T element = temp->element;
    delete temp;
    return element;
  }
  else
  {
    Node<T> *current = head;

    for (int i = 0; i < size - 2; i++)
      current = current->next;

    Node<T> *temp = tail;
    tail = current;
    tail->next = NULL;
    size--;
    T element = temp->element;
    delete temp;
    return element;
  }
}

template<typename T>
void LinkedList<T>::add(T element)
{
  addLast(element);
}

template<typename T>
void LinkedList<T>::add(int index, T element)
{
  if (index == 0)
    addFirst(element);
  else if (index >= size)
    addLast(element);
  else
  {
    Node<T> *current = head;
    for (int i = 1; i < index; i++)
      current = current->next;
    Node<T> *temp = current->next;
    current->next = new Node<T>(element);
    (current->next)->next = temp;
    size++;
  }
}

template<typename T>
void LinkedList<T>::clear()
{
  while (head != NULL)
  {
    Node<T> *temp = head;
    delete temp;
    head = head->next;
  }

  tail = NULL;
}

template<typename T>
T LinkedList<T>::get(int index)
{
  if (index < 0 || index > size - 1)
    throw runtime_error("Index out of range");

  Node<T> *current = head;
  for (int i = 0; i < index; i++)
    current = current->next;

  return current->element;
}

template<typename T>
int LinkedList<T>::indexOf(T element)
{
  // Implement it in this exercise
  Node<T> *current = head;
  for (int i = 0; i < size; i++)
  {
    if (current->element == element)
      return i;
    current = current->next;
  }

  return -1;
}

template<typename T>
bool LinkedList<T>::isEmpty()
{
  return head == NULL;
}

template<typename T>
int LinkedList<T>::getSize()
{
  return size;
}

template<typename T>
T LinkedList<T>::removeAt(int index)
{
  if (index < 0 || index >= size)
    throw runtime_error("Index out of range");
  else if (index == 0)
    return removeFirst();
  else if (index == size - 1)
    return removeLast();
  else
  {
    Node<T> *previous = head;

    for (int i = 1; i < index; i++)
    {
      previous = previous->next;
    }

    Node<T> *current = previous->next;
    previous->next = current->next;
    size--;
    T element = current->element;
    delete current;
    return element;
  }
}

  // The functions remove(T element), lastIndexOf(T element),
  // contains(T element), and set(int index, T element) are
  // to be continued...

#endif
如果预先不知道元素的数目,使用链表的效率更高,因为链表可以动态增长和缩减。如果需要频繁地向数组总任意位置插入和删除元素,使用链表效率更高,因为在数组中进行插入操作需要移动插入点后的所有元素。如果元素数目固定,也不需要随机插入和删除操作,那么使用数组更为简单,效率也更高。
<pre name="code" class="cpp">#include <iostream>
#include <string>
#include "LinkedList.h"
using namespace std;

void printList(LinkedList<string> list){
    for(int i = 0; i < list.getSize(); i++)
        cout<<list.get(i)<<" ";
    cout<<endl;
}

int main(){
    // Create a list for strings
    LinkedList<string> list;

    // Add elements to the list
    list.add("America");   // Add it to the list
    cout<<"(1)"<<endl;
    printList(list);

    list.add(0,"Canada"); // Add it to the beginning of the list
    cout<<"(2)"<<endl;
    printList(list);

    list.add("Russia");
    cout<<"(3)"<<endl;
    printList(list);

    list.add("France");
    cout<<"(4)"<<endl;
    printList(list);

    list.add(2,"Germany");
    cout<<"(5)"<<endl;
    printList(list);

    list.add(5,"Norway");
    cout<<"(6)"<<endl;
    printList(list);

    list.add(0,"Netherlands");
    cout<<"(7)"<<endl;
    printList(list);

    list.removeAt(0);
    cout<<"(8)"<<endl;
    printList(list);

    list.removeAt(2);  // Remove teh element at index 2
    cout<<"(9)"<<endl;
    printList(list);

    //Add elements to the list
    list.removeAt(list.getSize() - 1); // Remove the last element
    cout<<"(10)"<<endl;
    printList(list);

}

                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值