普通鏈表、隊列、鏈棧的實現

root@iZ14rcmneyrcltZ:~/cpptest# g++ -o LinkedList LinkedList.cpp
root@iZ14rcmneyrcltZ:~/cpptest# ./LinkedList
1 4 2 8 5 7
n=6
L1非空
L1= 1 100 4 2 8 5 7
L2= 7 5 200 200 8 2 4 1
n=0
L1爲空
L3= 1 100 4 2 8 5 7
L3= 1 100 4 2 8 5 7
root@iZ14rcmneyrcltZ:~/cpptest# g++ -D USE_STL -o LinkedList LinkedList.cpp
root@iZ14rcmneyrcltZ:~/cpptest# ./LinkedList
1 4 2 8 5 7
n=6
L1非空
L1= 1 100 4 2 8 5 7
L2= 7 5 200 200 8 2 4 1
n=0
L1爲空
L3= 1 2 4 5 7 8 100
L3= 100 8 7 5 4 2 1
root@iZ14rcmneyrcltZ:~/cpptest# g++ -o LinkedQueue LinkedQueue.cpp
root@iZ14rcmneyrcltZ:~/cpptest# ./LinkedQueue
1 4 2 8 5 7
front:1,back:7
front:4,back:7
front:2,back:7
front:8,back:7
front:5,back:7
front:7,back:7
root@iZ14rcmneyrcltZ:~/cpptest# g++ -D USE_STL -o LinkedQueue LinkedQueue.cpp
root@iZ14rcmneyrcltZ:~/cpptest# ./LinkedQueue
1 4 2 8 5 7
front:1,back:7
front:4,back:7
front:2,back:7
front:8,back:7
front:5,back:7
front:7,back:7
1 4 2 8 5 7
top:8
top:7
top:5
top:4
top:2
top:1
root@iZ14rcmneyrcltZ:~/cpptest# g++ -D USE_STL -o LinkedStack LinkedStack.cpp
root@iZ14rcmneyrcltZ:~/cpptest# ./LinkedStack
5
40
500000
400000
 9 8 7 6 5 4 3 2 1 0
Stack should be 1234
S top is 4
Stack top is 3
Stack top is 2
Stack top is 1
Stack top is empty
root@iZ14rcmneyrcltZ:~/cpptest# g++ -o LinkedStack LinkedStack.cpp
root@iZ14rcmneyrcltZ:~/cpptest# ./LinkedStack
5
40
500000
400000
 9 8 7 6 5 4 3 2 1 0
Stack should be 1234
S top is 4
Stack top is 3
Stack top is 2
Stack top is 1
Stack top is empty

#ifdef USE_STL
#include <list>//STL 線性列表容器,list採用鏈表結構,不支持隨機存取
#else
    
#endif
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;


#ifndef USE_STL

template <class T>
class Node//普通鏈表結點
{
    private:
        // next 爲指向下一結點的指針
        Node<T> *next;
    public:
        // data 爲公有成員
        T data;

        // 構造函數
        Node(const T& item, Node<T> *ptrnext = NULL);

        // 修改表的方法
        void InsertAfter(Node<T> *p);
        Node<T> *DeleteAfter(void);

        // 取得下一結點的指針
        Node<T> *NextNode(void) const;
};

// 構造函數。初始化數據及指針成員
template <class T>
Node<T>::Node(const T& item, Node<T> *ptrnext):
              data(item), next(ptrnext)
{}

// 返回私有成員 next 的值
template <class T>
Node<T> *Node<T>::NextNode(void) const
{
    return next;
}

// 在當前結點之後插入結點 p
template <class T>
void Node<T>::InsertAfter(Node<T> *p)
{
    // p 指向當前結點的後繼結點,然後將當前結點指向 p
    p->next = next;
    next = p;
}

// 刪除當前結點的後繼結點並返回其指針
template <class T>
Node<T> *Node<T>::DeleteAfter(void)
{
    // 若沒有後繼結點,返回 NULL
    if (next == NULL)
        return NULL;

    // 保存指向被刪除結點的指針
    Node<T> *tempPtr = next;
    // 使當前結點指向 tempPtr 的後繼結點
    next = tempPtr->next;
    // 返回被刪除結點的指針
    return tempPtr;
}

template <class T>
class list //普通鏈表(可隨機訪問,但訪問效率低)
{
    private:
        // 指向表頭和表尾的指針
        Node<T> *front, *rear;

        // 用於數據訪問、插入和刪除的指針
        Node<T> *prevPtr, *currPtr;

        // 表中的元素個數
        int m_size;

        // 表中位置值,用於 Reset
        int position;

        // 將表 L 拷貝到當前表尾
        void CopyList(const list<T> &L);

    public:
        // 構造函數
        list(void);
        list(const list<T>& L);

        // 析構函數
        ~list(void);

        // 賦值運算符
        list<T>& operator= (const list<T>& L);

        // 檢查表狀態的函數
        int size(void) const;               
        bool empty(void) const;

        // 遍歷表的函數
        void Reset(int pos = 0);
        void Next(void);
        bool EndOfList(void) const;
        int CurrentPosition(void) const;

        // 插入函數
        void push_front(const T& item);
        void push_back(const T& item);
        void InsertAt(const T& item);
        void InsertAfter(const T& item);

        // 刪除函數
        void DeleteFront(void);
        void DeleteAt(void);

        // 訪問/修改數據
        T& Data(void);
        bool Find(const T& item);

        // 清空表的函數
        void clear(void);
public:
    //-------------------------------------------------------------
    //  list<T>::iterator
    //-------------------------------------------------------------
    class iterator{
        friend class list<T>; //因爲在list中訪問了protected成員
    protected:
        Node<T>* nodePtr;
        iterator (Node<T>* newPtr)
        {
            nodePtr = newPtr;
        }
    public:
        iterator()
        {
        }
        bool operator== (const iterator& itr) const
        {
            return nodePtr == itr.nodePtr;
        } // overloading ==
        bool operator!= (const iterator& itr) const
        {
            return nodePtr != itr.nodePtr;
        } // overloading !=
        T& operator*() const
        {
            return nodePtr -> data;
        } // overloading *
        iterator operator++(int)
        {
            iterator temp = *this;
            nodePtr = nodePtr -> NextNode();
            return temp;
        } // post-increment ++
        iterator& operator++()
        {
            nodePtr = nodePtr -> NextNode();
            return *this;
        } // pre-increment ++
        bool atEnd()
        {
            return (nodePtr == NULL);
        } 
    };
    //---------------------------------------------
    //  list類要添加begin, end方法
    //---------------------------------------------
    iterator begin()
    {
        return iterator(front);  //要訪問Iterator的protected成員, 要把list添加爲友元類.
    } 
    iterator end()
    {
        return iterator(NULL);  //要訪問Iterator的protected成員, 要把list添加爲友元類.
    }     
    iterator insert(iterator pos, const T &val)
    {
        Reset();
        list<int>::iterator Iter=begin();    
        for(;Iter!=end();Iter++)
        {
            if(Iter==pos)
            {
                InsertAt(val);
                break;
            }
            else
            {
                Next();
            }
        }
        return Iter;
    }
    void insert(iterator pos, int num, const T &val)
    {
        Reset();
        list<int>::iterator Iter=begin();    
        for(;Iter!=end();Iter++)
        {
            if(Iter==pos)
            {
                for(int i=0;i<num;i++)
                    InsertAt(val);
                break;
            }
            else
            {
                Next();
            }
        }
        return;
    }    
};

// 創建空表,使其指針指向 NULL,m_size 置爲 0,position 置爲 -1
template <class T>
list<T>::list(void): front(NULL), rear(NULL),
    prevPtr(NULL),currPtr(NULL), m_size(0), position(-1)
{}

// 將 L 拷貝到當前表尾
template <class T>
void list<T>::CopyList(const list<T> &L)
{
    // 用指針 P 遍歷表
    Node<T> *p = L.front;

    // 往當前表的表尾插入 L 的每個元素
    while (p != NULL)
    {
        push_back(p->data);
        p = p->NextNode();
    }
}

template <class T>
list<T>::list(const list<T>& L)
{
    front = rear = prevPtr = currPtr = NULL;
    m_size = 0;
    position = -1;
    CopyList(L);
}

template <class T>
list<T>::~list(void)
{
    clear();
}

template <class T>
void list<T>::clear(void)
{
    Node<T> *currPos, *nextPos;
    currPos = front;
    while (currPos != NULL) 
    {
        // 取下一結點指針並刪除當前結點
        nextPos = currPos->NextNode();
        delete currPos;
        currPos = nextPos;  //移到下一結點
    }
    front = rear = prevPtr = currPtr = NULL;
    m_size = 0;
    position = -1;
}

template <class T>
list<T>& list<T>::operator= (const list<T>& L)
{
    if (this == &L)      // 無法賦值給自身
        return *this;
    
    clear();
    CopyList(L);
    return *this;
}

template <class T>
int list<T>::size(void) const
{
    return m_size;
}

template <class T>
bool list<T>::empty(void) const
{
    return (m_size == 0);
}

// 將表位置設置到 pos
template <class T>
void list<T>::Reset(int pos)
{
    // 若表爲空,則返回
    if (front == NULL)
        return;

    // 若位置非法,退出程序
    if (pos < 0 || pos > m_size - 1)
        throw "list::Reset: Invalid list position";
    
    prevPtr = NULL;
    currPtr = front;
    for (position = 0; position != pos; position++)
    {
        // 將兩個指針右移
        prevPtr = currPtr;
        currPtr = currPtr->NextNode();
    }
}

// 將 prevPtr 和 currPtr 指針右移一個結點
template <class T>
void list<T>::Next(void)
{
    // 若已到表尾或表爲空,返回
    if (currPtr !=  NULL)
    {
        // 將兩個指針右移一個結點
        prevPtr = currPtr;
        currPtr = currPtr->NextNode();
        position++;
    }
}

// 如果已到表尾,返回真
template <class T>
bool list<T>::EndOfList(void) const
{
    return (currPtr == NULL);
}

// 返回當前結點的位置
template <class T>
int list<T>::CurrentPosition(void) const
{
    return position;
}

// 往表頭插入結點
template <class T>
void list<T>::push_front(const T& item)
{
    Reset();
    InsertAt(item);  // 往表頭插入
}

// 在表尾插入結點
template <class T>
void list<T>::push_back(const T& item)
{
    prevPtr = rear;
    currPtr= NULL;
    position = m_size;

    InsertAt(item);
}

// 往表的當前位置插入結點
template <class T>
void list<T>::InsertAt(const T& item)
{
    Node<T> *newNode;

    // 兩種情況:往表頭或表中插入
    if (prevPtr == NULL)
    {
        // 往表頭插入,包括往空表中插入
        newNode = new Node<T>(item, front);
        front = newNode;
    }
    else
    {
        // 往表中插入。在 prevPtr 後插入結點
        newNode = new Node<T>(item);
        prevPtr->InsertAfter(newNode);
    }

    // 若 currPtr == NULL,表示往空表中或非空表的表尾插入;應修改 rear 及 position 值
    if (currPtr == NULL)
    {
        rear = newNode;
        position = m_size;
    }

    // 改變 currPtr 及增加表的大小
    currPtr = newNode;
    m_size++;
}

// 在當前表位置後插入結點
template <class T>
void list<T>::InsertAfter(const T& item)
{
    Next();
    InsertAt(item);
}

// 刪除表中第一個節點
template <class T>
void list<T>::DeleteFront(void)
{
   if (front == NULL)
      return;
    
   Reset();
   DeleteAt();
}

// 刪除表中當前結點
template <class T>
void list<T>::DeleteAt(void)
{
    // 如果表爲空或已到表尾,則出錯退出
    if (currPtr == NULL)
        throw "list::DeleteAt: Invalid deletion!";
    
    Node<T> *p;

    // 被刪除的必是頭結點或表中結點
    if (prevPtr == NULL)
    {
        // 保存表頭指針並取消其鏈接。如果這是最後結點,front 變爲 NULL
        p = front;
        front = front->NextNode();
    }
    else
        // 取消鏈接 prevPtr 之後的中間結點,並保存其地址
        p = prevPtr->DeleteAfter();
    
    // 若表尾被刪除,則 prevPtr 是新表尾且 position 減 1;否則,position 不變
    // 如果 p 是最後結點,rear = NULL 且 position = -1
    if (p == rear)
    {
        rear = prevPtr;
        position--;
    }
    
    // 將 currPtr 指向下一結點。若 p 爲表中最後結點,則 currPtr 爲 NULL
    currPtr = p->NextNode();
    
    // 釋放結點並將表大小減 1
    delete p;
    m_size--;
}

// 返回當前結點的數據值
template <class T>
T& list<T>::Data(void)
{
    // 若表爲空或已到表尾,則出錯
    if (currPtr == NULL)
        throw "LinkedList::Data: invalid reference!";

    return currPtr->data;
}

// 查找鏈表中是否有某數據
template <class T>
bool list<T>::Find(const T& item)
{
    for (Reset(); !EndOfList(); Next())
        if (Data() == item)
            return true;

    return false;
}

#endif

int main()
{
int arr[]={1,4,2,8,5,7};
int n=sizeof(arr)/sizeof(arr[0]);
cout<<"1 4 2 8 5 7"<<endl;
list<int> L1,L2,L3;
for(int i=0;i<n;i++){
   L1.push_back(arr[i]);
   L2.push_front(arr[i]);
}
auto func1=[&]()->void{
        cout<<"n="<<L1.size()<<endl;
        if(L1.empty())
        cout<<"L1爲空"<<endl;
        else
        cout<<"L1非空"<<endl;
    };
func1();

auto Iter1=L1.begin();
Iter1++;
L1.insert(Iter1,100);//在第一個元素之後插入100
auto Iter2=L2.begin();
Iter2++;
Iter2++;
L2.insert(Iter2,2,200);//在第二個元素之後插入兩個200
cout<<"L1=";
for_each(L1.begin(),L1.end(),[](int& i)->void{cout<< " "<<i;});
cout<<endl;
cout<<"L2=";
for_each(L2.begin(),L2.end(),[](int& i){cout<< " "<<i;});
cout<<endl;
L3=L1;
L1.clear();
func1();
#ifdef USE_STL
L3.sort();//升序
//list不能用sort(L3.begin(),L3.end());
#endif
auto func2=[&]()->void{
        cout<<"L3=";
        for(list<int>::iterator Iter=L3.begin();Iter!=L3.end();Iter++)
        cout<< " "<<*Iter;
        cout<<endl;
    };
func2();
#ifdef USE_STL
L3.sort(greater<int>());//降序
//list不能用sort(L3.begin(),L3.end(),greater<int>());
#endif
func2();

return 0;
}

#include<iostream>
#ifdef USE_STL
#include<queue>//隊列
#else
    
#endif
using namespace std;

#ifndef USE_STL
template <class T> class stack;
template <class T> class queue;

template <class T>
class Node {
    friend stack<T>;
    friend queue<T>;
private:
    T data;
    Node<T> *link;
};

template<class T>
class queue {
    // FIFO objects
public:
    queue() {m_front = m_rear = 0;} // constructor
    ~queue(); // destructor
    bool empty() const
    {return ((m_front) ? false : true);}
    bool IsFull() const;
    T front() const; // return first element
    T back() const; // return last element
    queue<T>& push(const T& x);
    queue<T>& pop();
    queue<T>& Delete(T& x);
private:
    Node<T> *m_front;  // pointer to first node
    Node<T> *m_rear;   // pointer to last node
};

template<class T>
queue<T>::~queue()
{// Queue destructor.  Delete all nodes.
    Node<T> *next;
    while (m_front) {
        next = m_front->link; 
        delete m_front; 
        m_front = next;
    }
}

template<class T>
bool queue<T>::IsFull() const
{// Is the queue full?
    Node<T> *p;
    try {p = new Node<T>;
    delete p;
    return false;}
    catch (...) {return true;}
}

template<class T>
T queue<T>::front() const
{// Return first element of queue.  Throw
    // OutOfBounds exception if the queue is empty.
    if (empty()) throw std::runtime_error("OutOfBounds();");
    return m_front->data;
}

template<class T>
T queue<T>::back() const
{// Return last element of queue.  Throw
    // OutOfBounds exception if the queue is empty.
    if (empty()) throw std::runtime_error("OutOfBounds();");
    return m_rear->data;
}

template<class T>
queue<T>& queue<T>::push(const T& x)
{// Add x to rear of queue.  Do not catch
    // possible NoMem exception thrown by new.

    // create node for new element
    Node<T> *p = new Node<T>;
    p->data = x;
    p->link = 0;

    // add new node to rear of queue
    if (m_front) m_rear->link = p;  // queue not empty
    else m_front = p;             // queue empty
    m_rear = p;

    return *this;
}

template<class T>
queue<T>& queue<T>::Delete(T& x)
{// Delete first element and put it in x.  Throw
    // OutOfBounds exception if the queue is empty.

    if (empty()) throw std::runtime_error("OutOfBounds();");

    // save element in first node
    x = m_front->data;

    // delete first node
    Node<T> *p = m_front;
    m_front = m_front->link;
    delete p;

    return *this;
}

template<class T>
queue<T>& queue<T>::pop()
{
   T x;
   return Delete(x);
}

#endif

int main()
{
queue<int> q;
int arr[]={1,4,2,8,5,7};
int n=sizeof(arr)/sizeof(arr[0]);
cout<<"1 4 2 8 5 7"<<endl;
for(int i=0;i<n;i++){
   q.push(arr[i]);
}
while(!q.empty())
{
cout<<"front:"<<q.front()<<",back:"<<q.back()<<endl;
q.pop();
}

#ifdef USE_STL
//優先隊列是從大到小的順序8 7 5 4 2 1
priority_queue<int> Q;
cout<<"1 4 2 8 5 7"<<endl;
for(int i=0;i<n;i++){
   Q.push(arr[i]);
}
while(!Q.empty())
{
cout<<"top:"<<Q.top()<<endl;
Q.pop();
}
#endif
return 0;
}

#include<iostream>
#ifdef USE_STL
#include <stack>//STL 堆棧容器
#else
    
#endif
#include <string>//字符串類
using namespace std;


#ifndef USE_STL
template <class T> class stack;
template <class T> class deque;
template <class T>
class Node {
    friend stack<T>;
    friend deque<T>;
private:
    T data;
    Node<T> *link;
};

template<class T>
class stack {
   public:
      stack() {m_top = 0;}
      ~stack();
      bool empty() const {return m_top == 0;}
      bool IsFull() const;
      T top() const;
      stack<T>& push(const T& x);
      stack<T>& pop();
      stack<T>& Delete(T& x);
   private:
      Node<T> *m_top; // pointer to top node
};

template<class T>
stack<T>::~stack()
{// Stack destructor..
   Node<T> *next;
   while (m_top) {
      next = m_top->link;
      delete m_top;
      m_top = next;
      }
}

template<class T>
bool stack<T>::IsFull() const
{// Is the stack full?
   try {Node<T> *p = new Node<T>;
        delete p;
        return false;}
   catch (...) {return true;}
}

template<class T>
T stack<T>::top() const
{// Return top element.
   if (empty()) throw std::runtime_error("OutOfBounds();");
   return m_top->data;
}

template<class T>
stack<T>& stack<T>::push(const T& x)
{// Add x to stack.
   Node<T> *p = new Node<T>;
   p->data = x;
   p->link = m_top;
   m_top = p;
   return *this;
}

template<class T>
stack<T>& stack<T>::Delete(T& x)
{// Delete top element and put it in x.
   if (empty()) throw std::runtime_error("OutOfBounds();");
   x = m_top->data;
   Node<T> *p = m_top;
   m_top = m_top->link;
   delete p;
   return *this;
}

template<class T>
stack<T>& stack<T>::pop()
{
   T x;
   return Delete(x);
}

#endif

int main()
{    
    stack<int> a;
    a.push(5);
    cout<<a.top()<<endl;
    a.push(20);
    a.push(40);
    cout<<a.top()<<endl;

    stack<long> b;
    b.push(500000);
    cout<<b.top()<<endl;
    b.push(200000);
    b.push(400000);
    cout<<b.top()<<endl;

    stack<int> s;
    for( int i=0; i < 10; i++ )
    s.push(i);
    while(!s.empty())
    {
    cout<< " "<<s.top();
    s.pop();
    }// 9 8 7 6 5 4 3 2 1 0
    cout<<endl;

    stack<int> S;
    try {
       S.push(1);
       S.push(2);
       S.push(3);
       S.push(4);
       }
    catch (...) {
      cout << "Could not complete additions" << endl;
      }
  
   cout << "Stack should be 1234" << endl;
   cout << "S top is " << S.top() << endl;
   try {
      S.pop();
      cout << "Stack top is " << S.top() << endl;
      S.pop();
      cout << "Stack top is " << S.top() << endl;
      S.pop();
      cout << "Stack top is " << S.top() << endl;
      S.pop();
      if(!s.empty())
        cout << "Stack top is " << S.top() << endl;
      else
        cout << "Stack top is empty" << endl;  
      }
   catch (...) {
      cout << "Last delete failed " << endl;
      }  
    return 0;
}

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